Android tutorial 2020 – recyclerview displays multiple items

Android tutorial 2020 - series overview

Article link

The previous list shows similar data. What if you want to display different categories of data in a list? Recyclerview has the ability to deal with such scenarios. This article describes how to use recyclerview to display multiple items.

There are many classes and files involved in this example.

Files in the same package

BaseMultiData.java
BaseVH.java
ItemTypeDef.java
MultiData1.java
MultiData2.java
MultiItemAdapter.java
OneVH.java
ReViewDemoMulti.java
TwoVH.java

Layout resource file

item_multi_1.xml
item_multi_2.xml

First assume the scenario. Suppose we have two kinds of data. The first data has only one string, and the second data has two strings. Then we can design an abstract class of data first. And the enumeration type is designed to distinguish these two kinds of data.

Use enumeration types to distinguish data categories, itemtypedef.java.

public class ItemTypeDef {

    public static final int ITEM_TYPE_ONE_TEXT = 1;
    public static final int ITEM_TYPE_2_TEXT = 2;

    public enum Type {
        ONE_TEXT(ITEM_TYPE_ONE_TEXT),TWO_TEXT(ITEM_TYPE_2_TEXT);
        int code;

        Type(int code) {
            this.code = code;
        }

        public int getCode() {
            return code;
        }

        public static Type getItemTypeByCode(int code) {
            switch (code) {
                case ITEM_TYPE_ONE_TEXT:
                    return Type.ONE_TEXT;
                case ITEM_TYPE_2_TEXT:
                    return Type.TWO_TEXT;
            }
            return Type.ONE_TEXT;
        }
    }
}

The enumeration class itself has an ordinal () method to indicate the ordinal value of the enumeration. But in this example, we wrap the enumeration in a class and force int to mark the class.

Abstract class of data

public abstract class BaseMultiData {
    public abstract int typeCode();
}

Class representing specific data. The first data class.

public class MultiData1 extends BaseMultiData {

    private String str1;

    public MultiData1(String str1) {
        this.str1 = str1;
    }

    public String getStr1() {
        return str1;
    }

    @Override
    public int typeCode() {
        return ItemTypeDef.Type.ONE_TEXT.getCode();
    }
}

The second data class.

public class MultiData2 extends BaseMultiData {

    private String str1;
    private String str2;

    public MultiData2(String str1,String str2) {
        this.str1 = str1;
        this.str2 = str2;
    }

    public String getStr1() {
        return str1;
    }

    public String getStr2() {
        return str2;
    }

    @Override
    public int typeCode() {
        return ItemTypeDef.Type.TWO_TEXT.getCode();
    }
}

You can see that the two data classes hold 1 and 2 strings respectively.

Two types of data are designed in the front, corresponding to each other. Next, we design two styles.

Prepare two layouts first.

Item is prepared for the first kind of data multidata1_ multi_ 1.xml。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:background="#33691E"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginStart="12dp"
        android:textColor="#ffffff" />

</LinearLayout>

Item is prepared for the second kind of data, multidata2_ multi_ 2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="#ffffff"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginStart="12dp"
        android:text="tv1"
        android:textColor="#33691E" />

    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginStart="12dp"
        android:text="tv2"
        android:textColor="#8BC34A" />

</LinearLayout>

Design the corresponding viewholder. The first is the abstract class basevh. It holds an itemtypedef. Type to indicate its category.

public abstract class BaseVH extends RecyclerView.ViewHolder {
    private ItemTypeDef.Type type;
    public View root;

    public BaseVH(View itemView,ItemTypeDef.Type type) {
        super(itemView);
        this.root = itemView;
        this.type = type;
    }

    public ItemTypeDef.Type getType() {
        return type;
    }
}

Concrete implementation class. Onevh of type 1 data.

public class OneVH extends BaseVH {
    public TextView tv1;

    public OneVH(View itemView,ItemTypeDef.Type type) {
        super(itemView,type);
        tv1 = itemView.findViewById(R.id.tv1);
    }
}

Twovh of the second data.

public class TwoVH extends BaseVH {
    public TextView tv1;
    public TextView tv2;

    public TwoVH(View itemView,type);
        tv1 = itemView.findViewById(R.id.tv1);
        tv2 = itemView.findViewById(R.id.tv2);
    }
}

Now the classes and resources of the two kinds of data are ready. Let's design the adapter. The method used to distinguish molecular item categories in recyclerview.adapter is public int getitemviewtype (int position). We need to duplicate this method to tell recyclerview the category of the current child. It returns int.

    @Override
    public int getItemViewType(int position) {
        return dataList.get(position).typeCode();
    }

The complete code of the adapter is as follows


public class MultiItemAdapter extends RecyclerView.Adapter<BaseVH> {

    private List<BaseMultiData> dataList = new ArrayList<>();

    public void setDataList(List<BaseMultiData> dataList) {
        this.dataList = dataList;
        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public BaseVH onCreateViewHolder(@NonNull ViewGroup parent,int viewType) {
        switch (ItemTypeDef.Type.getItemTypeByCode(viewType)) {
            case ONE_TEXT:
                return new OneVH(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_multi_1,parent,false),ItemTypeDef.Type.ONE_TEXT);
            case TWO_TEXT:
                return new TwoVH(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_multi_2,ItemTypeDef.Type.TWO_TEXT);
        }
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull BaseVH holder,int position) {
        BaseMultiData data = dataList.get(position);
        switch (holder.getType()) {
            case ONE_TEXT:
                ((OneVH) holder).tv1.setText(((MultiData1) data).getStr1());
                break;
            case TWO_TEXT:
                TwoVH twoVH = (TwoVH) holder;
                MultiData2 data2 = (MultiData2) data;
                twoVH.tv1.setText(data2.getStr1());
                twoVH.tv2.setText(data2.getStr2());
                break;
        }
    }

    @Override
    public int getItemCount() {
        return dataList.size();
    }

    @Override
    public int getItemViewType(int position) {
        return dataList.get(position).typeCode();
    }
}

To display multiple items, you have to put them together. The data list declaration loads the abstract class basemultidata. In the oncreateviewholder method of creating a viewholder, judge which viewholder should be created according to the viewtype. In the onbindviewholder method of assembly data, the corresponding data is also set according to the type of holder. Cast is used here.

Use this adapter in the activity

public class ReViewDemoMulti extends AbsActivity {

    private MultiItemAdapter mMultiItemAdapter = new MultiItemAdapter();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recyler_view_demo);

        RecyclerView recyclerView = findViewById(R.id.re_view);
        recyclerView.setAdapter(mMultiItemAdapter);
        recyclerView.setLayoutManager(new linearlayoutmanager(this,RecyclerView.VERTICAL,false));

        mMultiItemAdapter.setDataList(genData());
    }

    private List<BaseMultiData> genData() {
        List<BaseMultiData> list = new ArrayList<>();
        for (int i = 0; i < 60; i++) {
            if (i % 2 == 0) {
                list.add(new MultiData1("[Data1] " + i));
            } else {
                list.add(new MultiData2("[Data2] " + i,"Type2"));
            }
        }
        return list;
    }
}

You can see the effect when running. This is a simple example

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>