一個RecyclerView實現多級摺疊列表(TreeRecyclerView)

jlanglang發表於2018-01-19

前言

不得不吐槽一下產品. 尼瑪為啥要搞這樣的功能.... 搞個兩級的不就好了嘛...自帶控制元件,多好. 三級,四級,聽說還有六級的.... 這樣喪心病狂的設計,後臺也不好給資料吧.

2018年更新:

由於迭代了很多版本,老的文章內容已經不適用,更新一下.

效果及實現程式碼:

以下實現都只用一個RecycerView,沒有巢狀.

三級列表:

Paste_Image.png

購物車:

image.png

分類快速定位:

image.png

綜合(頭部,側滑,定位,摺疊):

image.png

多樣式列表:

image.png

如何使用,這裡只列出摺疊的使用方法:

一.你需要建立一個adapter:

 //根據item的狀態展示,可摺疊
    TreeRecyclerAdapter treeRecyclerAdapter = new TreeRecyclerAdapter(TreeRecyclerType.SHOW_EXPAND);
複製程式碼

二.你需要選擇一種展開方式

image.png

   public TreeRecyclerAdapter() {
        this(null);
    }

    public TreeRecyclerAdapter(TreeRecyclerType treeRecyclerType) {
        type = treeRecyclerType == null ? TreeRecyclerType.SHOW_DEFAULT : treeRecyclerType;
    }
複製程式碼

建構函式傳入,不傳預設則使用SHOW_DEFAULT.

三.寫具體展示的item

注意! 使用這個,沒有寫ViewHolder的概念,只有TreeItem和TreeItemGroup

簡單的TreeItemGroup示例,第二級 市:
/**
* 城市
 */
public class CountyItemParent extends TreeItemGroup<ProvinceBean.CityBean> {//泛型代表繫結的javabean
    
    //建立子TreeItem.
    @Override
    public List<TreeItem> initChildList(ProvinceBean.CityBean data) {
        return ItemHelperFactory.createItems(data.getAreas(),  this);
    }

    //該級具體展示的Layout
    @Override
    public int getLayoutId() {
        return R.layout.item_two;
    }

    //view和data繫結
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder) {
        holder.setText(R.id.tv_content, data.getCityName());
    }
}
複製程式碼

簡單的TreeItem示例,第三級城市:
/**
* 縣
 */
public class AreaItem extends TreeItem<ProvinceBean.CityBean.AreasBean> {//泛型代表繫結的javabean

    //這個item的具體展示layout
    @Override
    public int getLayoutId() {
        return R.layout.item_three;
    }
    //這個Item條目的檢視繫結操作,
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder) {
        holder.setText(R.id.tv_content, data.getAreaName());
    }
    //這個Item,在RecyclerView的每行所佔比,只有RecyclerView設定了GridLayoutManager才會生效.
    //這個最好是返回能整出的數.之所以用除法,是為了可以做到,只改變GridLayoutManager的總數,無需改變Item
    @Override
    public int getSpanSize(int maxSpan) {
        return maxSpan / 6;
    }
}

複製程式碼

第一級為啥沒寫呢? 因為寫法和第二級一樣的,就不寫出來了.具體見demo

怎麼建立Item呢?

有兩種方法:

1.在javabean上使用註解:
 @TreeDataType(iClass = AreaItem.class)
  public class AreasBean{
  ...
  }
複製程式碼

然後重寫在TreeItemGroup中initChildList()

  @Override
    public List<TreeItem> initChildList(ProvinceBean.CityBean data) {
        return ItemHelperFactory.createItems(data.getAreas(),  this);
    }

複製程式碼

這樣,item就生成了.

2.直接傳入item的class,建立item
 //建立item
 List<TreeItem> provinceItemList = ItemHelperFactory.createItems(cityBeen, ProvinceItemParent.class, null);
 List<TreeItem> items = ItemHelperFactory.createItems(cityBeen, null);
複製程式碼

這2行程式碼,效果上是一樣的.


四.如何更新adapter:

image.png

五,如何設定點選:

條目點選

1.重寫TreeItemonClick():

image.png
2.adapter設定setOnItemClickListener

 adapter.setOnItemClickListener(new BaseRecyclerAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(@NonNull ViewHolder viewHolder, int position) {
       
            }
        });
複製程式碼

注意.二者衝突


下面附上github地址,裡面有Demo,

傳送門:TreeRecyclerView 歡迎Star,哈哈

您的喜歡與回覆是我最大的動力,歡迎評論補充.

相關文章