RecyclerView tree list (without third-party libraries and child arrays)

Good day, dear readers.
 
 
In my article, I want to share the implementation of the tree view using RecyclerView. Without using any additional libraries and without using a child array.
 
Who cares, I ask under the cat. I will try to describe as much as possible what yes how.
 
 
RecyclerView tree list (without third-party libraries and child arrays)  
 
The principle of forming a list of elements is that the child elements will be shown or hidden.
 
 
Although I said that the implementation will be without additional libraries, but the standard libraries still need to connect.
 
 
3r33333. 3r3333391. Linked libraries [/b] 3r33393. 3r33394. 3r3179. dependencies {
implementation 'com.android.support:appcompat-v7:???'
implementation 'com.android.support:design:???'
implementation 'com.android.support:recyclerview-v7:???'
}

 
 
The markup will be the most minimal - only the RecyclerView list.
 
 
3r33333. 3r3333391. Markup [/b] 3r33393. 3r33394. 3r3179. 3r3185. xmlns: android = "http://schemas.android.com/apk/res/android"
android: layout_width = "match_parent"
android: layout_height = "match_parent">
3r3633. android: layout_width = "match_parent"
android: layout_height = "match_parent"
android: id = "@ + id /recycler_list">

 
 
Additionally, you need a separate class with which we will store the values ​​of the list.
 
 
3r33333. 3r3333391. The class for data is Data.java [/b] 3r33393. 3r33394. 3r33395. public final class Data {
private String valueText = ""; //the name of the value 3r3505. private int valueId = 0; //id of the value 3r3505.
private boolean itemParent = false; //parent or not element
private int parentId = -1; //id of the element that is the parent
private boolean childVisibility = false; //visibility of child elements
//check the parent element or not
public boolean isItemParent () {
return itemParent;
}
//set the value of the parent element
public void setItemParent (boolean newItemParent) {
itemParent = newItemParent;
}
//check the visibility of child elements 3r3505. public boolean isChildVisibility () {
return childVisibility;
}
//set the visibility for child elements 3r3505. public void setChildVisibility (boolean newChildVisibility) {
childVisibility = newChildVisibility;
}
//get the parent element number
public int getParentId () {
return parentId;
}
//set the parent number
public void setParentId (int newParentId) {
parentId = newParentId;
}
//get the name of the value 3r3505. public String getValueText () {
return valueText;
}
//set the name of the value 3r3505. public void setValueText (String newValueText) {
valueText = newValueText;
}
//get the value identifier 3r3505. public int getValueId () {
return valueId;
}
//set the value identifier 3r3505. public void setValueId (int newValueId) {
valueId = newValueId;
}
}

 
 
The comments should be clear, but I will explain. For each item in the list, we will store it with some identifier 3r33380. valueId [/i] , the name valueText , parent id parentId , the label that the item is the parent itemParent and the visibility value for child elements childVisibility .
 
 
The next preparatory step is to create markup for the list item itself.
 
 
3r33333. 3r3333391. The markup for item.xml is [/b] 3r33393. 3r33394. 3r3179. 3r33180. xmlns: app = "http://schemas.android.com/apk/res-auto"
android: id = "@ + id /item"
android: layout_width = "match_parent"
android: layout_height = "wrap_content">
3r3185. android: layout_width = "match_parent"
android: layout_height = "match_parent">
3r3189.
3r3191. 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" />

 
 
3r33380. AppCompatImageView [/i] needed to display the status of the parent element. 3r33380. TextView [/i] - to display the value of the item. 3r33380. View [/i] - just for separation.
 
 
The final preparatory step is to create a class for handling the list adapter.
 
 
3r33333. 3r3333391. Adapter for the RecyclerViewAdapter.java [/b] list. 3r33393. 3r33394. 3r33395. public class RecyclerViewAdapter extends RecyclerView.Adapter
{
private View vv;
private List
allRecords; //list of all data 3r3505.
public RecyclerViewAdapter (List
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 + "(parent id:" + parentId + ")";
//show or hide the element if it is a child of
if (parentId> = 0) {
//visibility is done by the parameter of the parent element
setVisibility (viewHolder.item, allRecords.get (parentId) .isChildVisibility (), parentId);
}
else {//element is not a child, show it
setVisibility (viewHolder.item, true, parentId);
}
//show or hide the tree view icon
if (record.isItemParent ()) {
viewHolder.iconTree.setVisibility (View.VISIBLE);
//show the desired icon
if (record.isChildVisibility ()) //child elements are shown
viewHolder.iconTree.setBackgroundResource (R.drawable.icon_show);
else //hidden child elements
viewHolder.iconTree.setBackgroundResource (R.drawable.icon_hide);
}
else //element is not parent
viewHolder.iconTree.setVisibility (View.GONE);
//set the text of the element
if (! TextUtils.isEmpty (value)) {
viewHolder.valueText.setText (value);
}
//add click processing for the value of
viewHolder.valueText.setonclickListener (new View.onclickListener () {
@Override
public void onclick (View view) {
Data dataItem = allRecords.get (position); 3r3505 .str-a, a newer for the current account, for a newer to create a newer .???.???.???.??? //clicked on the parent element, changing the visibility of the child elements 3r3505. dataItem.setChildVisibility (! dataItem.isChildVisibility ());
notifyDataSetChanged ();
}
Snackbar snackbar = Snackbar.make (vv, text, Snackbar.LENGTH_LONG);
Snackbar.show ();
}
}
};
}
//set the visibility of the element
private void setVisibility (View curV, boolean visible, int parentId) {
//find a block, thanks to which we will move the text
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) {//this is a child, indent
vPadding.setPadding (8? ? ? 0);
}
else {
vPadding.setPadding (? ? ? 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);
}
}
}

 
 
The main processing occurs in the procedure onBindViewHolder . For each element of the list, its identifier, value and parameters of the parent value are obtained. Child elements are shown or hidden, as well as the status icon for the parent element. Well, hangs up the processing of clicks on the list. Here everyone decides how he needs to handle the list. The example simply displays a message with the id and value of the element.
 
In the procedure for showing or hiding a child element setVisibility additionally indent text for a child element of 80 pixels.
 
 
It remains only to fill the list in the right place.
 
 
3r33333. 3r3333391. Formation of the list [/b] 3r33393. 3r33394. 3r33395. List
records = new ArrayList
(); //list of values ​​3r3505. Data record;
RecyclerViewAdapter adapter;
int parentId;
RecyclerView recyclerView = findViewById (R.id.recycler_list);
record = new Data ();
record.setValueId (1);
record.setValueText ("Parent value 1");
record.setItemParent (true); //parent value
records.add (record);
parentId = records.size () -1;
for (int ind = 1; ind <= 3; ind ++) {
record = new Data ();
record.setValueId (ind);
record.setValueText ("Text" + ind);
record.setParentId (parentId);
records.add (record);
}
record = new Data ();
record.setValueId (1);
record.setValueText ("Second Parent Value"); 3r3505. ); //parent value
records.add (record);
parentId = records.size () -1;
for (int ind = 4; ind <= 7; ind ++) {
record = new Data (); 3r3505. record. setValueId (ind);
record.setValueText ("Child text" + ind);
record.setParentId (parentId); 3r3505. records.add (record);
} 3r3505 .3r3r3r5r. ;
Record.setValueId (1);
Record.setValueText ("Another parent value");
Reco rd.setItemParent (true); //parent value
records.add (record);
parentId = records.size () -1;
for (int ind = 8; ind 3r3438. record = new Data ();
record.setValueId (ind);
record.setValueText ("Value" + ind);
record.setParentId (parentId);
records.add (record); 3r3505.}
for (int ind = 13; ind <= 18; ind ++) {
record = new Data ();
record.setValueId (ind);
record.setValueText "+ ind); 3r3505. records.add (record);
}
for (int ind = 19; ind <= 21; ind ++) {
record = new Data ();
record.setValueId (ind);
.setValueText (“Element is also without parent” + ind); 3r3505. records.add (record); 3r3505.}
record = new Data ();
("Again parental value");
Record.setItemParent (true); //parental value
5. records.add (record);
ParentId = records.size () -1;
For (int ind = 22; ind <= 30; ind ++) {
record = new Data ();
record.setValueId (ind);
record.setValueText ("Child:" + ind);
record.setParentId (parentId);
records.add (record);
}
for (int ind = 31; ind <= 45; ind ++) {
record = new Data ();
record.setValueId (ind);
record.setValueText ("Last without parent" + ind);
records.add (record); 3r3505.
3r3505. Adapter .setLayoutManager (layoutManager);
recyclerView.setItemAnimator (itemAnimator);
3r3488.
 
 
The result is such a simple list with support for children. This implementation allows you to fill in several nested elements. But you need quite a bit to modify the indents for the children, if the level of nesting is more than 1. 3r3497.  
 
Thank you all for your attention and successful projects.
+ 0 -

Add comment