Tampilan pohon RecyclerView (tanpa perpustakaan pihak ketiga dan array anak)

Selamat siang, pembaca yang budiman.

Dalam artikel saya, saya ingin berbagi implementasi tampilan hierarki dengan RecyclerView. Tanpa menggunakan pustaka tambahan dan tanpa menggunakan array anak.
Siapa yang peduli, tolong, di bawah kucing. Saya akan mencoba menggambarkan sebanyak mungkin apa dan bagaimana.



Prinsip pembentukan daftar elemen adalah bahwa elemen anak akan ditampilkan atau disembunyikan.

Meskipun saya mengatakan bahwa implementasinya akan tanpa perpustakaan tambahan, namun, perpustakaan standar masih perlu dihubungkan.

Perpustakaan yang terhubung
dependencies { implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support:design:26.1.0' implementation 'com.android.support:recyclerview-v7:26.1.0' } 


Markup akan sangat minim - hanya daftar RecyclerView.

Markup
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/recycler_list"> </android.support.v7.widget.RecyclerView> </RelativeLayout> 


Selain itu, kita membutuhkan kelas terpisah yang dengannya kita akan menyimpan nilai daftar.

Kelas untuk data Data.java
 public final class Data { private String valueText = ""; //  private int valueId = 0; //  private boolean itemParent = false; //    private int parentId = -1; //id ,    private boolean childVisibility = false; //   //     public boolean isItemParent() { return itemParent; } //    public void setItemParent(boolean newItemParent) { itemParent = newItemParent; } //    public boolean isChildVisibility() { return childVisibility; } //     public void setChildVisibility(boolean newChildVisibility) { childVisibility = newChildVisibility; } //    public int getParentId() { return parentId; } //    public void setParentId(int newParentId) { parentId = newParentId; } //   public String getValueText() { return valueText; } //   public void setValueText(String newValueText) { valueText = newValueText; } //   public int getValueId() { return valueId; } //   public void setValueId(int newValueId) { valueId = newValueId; } } 


Komentar harus jelas, tetapi saya akan jelaskan. Untuk setiap elemen dalam daftar, kami akan menyimpan valueId pengenalnya, name valueText , pengidentifikasi elemen induk parentId , label yang menunjukkan bahwa elemen tersebut adalah parent itemParent dan nilai visibilitas untuk elemen anak childVisibility .

Langkah persiapan berikutnya adalah membuat markup untuk item daftar itu sendiri.

Markup untuk item.xml
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/item" android:layout_width="match_parent" android:layout_height="wrap_content"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <!--     --> <android.support.v7.widget.AppCompatImageView android:id="@+id/icon_tree" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/icon_hide" android:visibility="gone" app:backgroundTint="@color/colorPrimary" android:layout_centerVertical="true"/> <LinearLayout android:id="@+id/block_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@+id/icon_tree"> <!--  --> <TextView android:id="@+id/value_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:foreground="?android:attr/selectableItemBackground" android:text="sdfdsf"/> </LinearLayout> <!--  --> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/colorPrimary" android:layout_below="@+id/block_text" android:layout_marginTop="4dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp"/> </RelativeLayout> </LinearLayout> 


AppCompatImageView diperlukan untuk menampilkan status elemen induk. TextView - untuk menampilkan nilai suatu elemen. Lihat hanya untuk berbagi.

Langkah persiapan terakhir adalah membuat kelas untuk menangani daftar adaptor.

Adaptor untuk daftar RecyclerViewAdapter.java
 public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> { private View vv; private List<Data> allRecords; //   public RecyclerViewAdapter(List<Data> records) { allRecords = records; } @Override public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false); return new RecyclerViewAdapter.ViewHolder(v); } @Override public void onBindViewHolder(final RecyclerViewAdapter.ViewHolder viewHolder, int i) { Data record = allRecords.get(i); String value = record.getValueText(); int id = record.getValueId(); int parentId = record.getParentId(); final int position = i; final String text = "#" + id + ": " + value + " (id  : " + parentId + ")"; //   ,    if (parentId >= 0) { //      setVisibility(viewHolder.item, allRecords.get(parentId).isChildVisibility(), parentId); } else { //  ,   setVisibility(viewHolder.item, true, parentId); } //      if (record.isItemParent()) { viewHolder.iconTree.setVisibility(View.VISIBLE); //   if (record.isChildVisibility()) //   viewHolder.iconTree.setBackgroundResource(R.drawable.icon_show); else //   viewHolder.iconTree.setBackgroundResource(R.drawable.icon_hide); } else //   viewHolder.iconTree.setVisibility(View.GONE); //   if (!TextUtils.isEmpty(value)) { viewHolder.valueText.setText(value); } //     viewHolder.valueText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Data dataItem = allRecords.get(position); if (dataItem.isItemParent()) { //   ,     dataItem.setChildVisibility(!dataItem.isChildVisibility()); notifyDataSetChanged(); } else { //   ,    Snackbar snackbar = Snackbar.make(vv, text, Snackbar.LENGTH_LONG); snackbar.show(); } } }); } //   private void setVisibility(View curV, boolean visible, int parentId) { // ,      LinearLayout vPadding = curV.findViewById(R.id.block_text); LinearLayout.LayoutParams params; if (visible) { params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); if (vPadding != null) { if (parentId >= 0) { //  ,   vPadding.setPadding(80, 0, 0, 0); } else { vPadding.setPadding(0, 0, 0, 0); } } } else params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0); curV.setLayoutParams(params); } @Override public int getItemCount() { return allRecords.size(); } class ViewHolder extends RecyclerView.ViewHolder { private LinearLayout item; private TextView valueText; private AppCompatImageView iconTree; public ViewHolder(View itemView) { super(itemView); vv = itemView; item = vv.findViewById(R.id.id_item); valueText = vv.findViewById(R.id.value_name); iconTree = vv.findViewById(R.id.icon_tree); } } } 


Pemrosesan utama berlangsung dalam prosedur onBindViewHolder . Untuk setiap elemen daftar, pengidentifikasi, nilai, dan parameter dari nilai induk diperoleh. Menampilkan atau menyembunyikan elemen anak, serta ikon status untuk elemen induk. Nah, pemrosesan klik pada daftar digantung. Kemudian semua orang memutuskan bagaimana dia perlu memproses daftar. Contoh ini hanya menunjukkan pesan dengan nilai id dan elemen.
Dalam prosedur untuk menampilkan atau menyembunyikan anak setVisibility , teks juga diindentasi untuk elemen anak di 80 piksel.

Tinggal mengisi daftar saja di tempat yang tepat.

Daftar bangunan
 List<Data> records = new ArrayList<Data>(); //  Data record; RecyclerViewAdapter adapter; int parentId; RecyclerView recyclerView = findViewById(R.id.recycler_list); record = new Data(); record.setValueId(1); record.setValueText("  1"); record.setItemParent(true); //  records.add(record); parentId = records.size() -1; for (int ind = 1; ind <= 3; ind ++) { record = new Data(); record.setValueId(ind); record.setValueText(" " + ind); record.setParentId(parentId); records.add(record); } record = new Data(); record.setValueId(1); record.setValueText("  "); record.setItemParent(true); //  records.add(record); parentId = records.size() -1; for (int ind = 4; ind <= 7; ind ++) { record = new Data(); record.setValueId(ind); record.setValueText("  " + ind); record.setParentId(parentId); records.add(record); } record = new Data(); record.setValueId(1); record.setValueText("  "); record.setItemParent(true); //  records.add(record); parentId = records.size() -1; for (int ind = 8; ind <= 12; ind ++) { record = new Data(); record.setValueId(ind); record.setValueText(" " + ind); record.setParentId(parentId); records.add(record); } for (int ind = 13; ind <= 18; ind ++) { record = new Data(); record.setValueId(ind); record.setValueText("  " + ind); records.add(record); } for (int ind = 19; ind <= 21; ind ++) { record = new Data(); record.setValueId(ind); record.setValueText("   " + ind); records.add(record); } record = new Data(); record.setValueId(1); record.setValueText("  "); record.setItemParent(true); //  records.add(record); parentId = records.size() -1; for (int ind = 22; ind <= 30; ind ++) { record = new Data(); record.setValueId(ind); record.setValueText(": " + ind); record.setParentId(parentId); records.add(record); } for (int ind = 31; ind <= 45; ind ++) { record = new Data(); record.setValueId(ind); record.setValueText("   " + ind); records.add(record); } adapter = new RecyclerViewAdapter(records); RecyclerView.ItemAnimator itemAnimator = new DefaultItemAnimator(); LinearLayoutManager layoutManager = new LinearLayoutManager(this); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(layoutManager); recyclerView.setItemAnimator(itemAnimator); 


Hasilnya adalah daftar sederhana dengan dukungan untuk elemen anak. Implementasi ini memungkinkan Anda untuk mengisi beberapa elemen bersarang. Tetapi Anda perlu sedikit memperbaiki lekukan untuk elemen anak jika level bersarang lebih dari 1.

Terima kasih atas perhatian dan proyek sukses Anda.

Source: https://habr.com/ru/post/id431718/


All Articles