1. 程式人生 > >基於RecyclerView的樹形結構

基於RecyclerView的樹形結構

基於RecyclerView的樹形結構

一、使用方式Usage

  • 實現效果
    在這裡插入圖片描述

演示程式碼

演示工程專案

點選下載演示APK

  • 匯入相關模組

andnext_recyclerview基於RecyclerView的封裝,包含了本文中的樹形實現;

andnext_overscrollRecyclerView的OverScroll依賴;

andnext_java部分程式碼依賴於JavaSE;

下載地址:https://github.com/jicanghai37927/WhatsAndroid

  • 例項化TreeList

TreeList參考了SortedList的實現,如果有使用過SortedList,那麼上手會非常容易。TreeList內部實現了樹形結構的展開和摺疊,所以提供了TreeListAdapterCallback來通知資料變化。

this.treeList = new TreeList(new TreeListAdapterCallback(adapter) {
    @Override
    public void onInserted(int position, int count) {
        super.onInserted(position, count);

        recyclerView.smoothScrollToPosition(position);
    }
});
  • 構建樹形結構

通過TreeListadd(Object parent, Object child)構建樹形結構,parent = null時新增到TreeList的根節點。

treeList.add(null, new FolderHeader());

通過遍歷將資料新增到TreeList中。

AreaDataset dataset = GsonUtils.fromJson(getActivity(), "dataset/area_ds.json", AreaDataset.class);
this.buildTree(treeList, dataset, null);
void buildTree(TreeList tree, AreaDataset ds, AreaDataset.AreaEntity parent) {
    List<AreaDataset.AreaEntity> list = ds.getChildren(parent == null? "": parent.getId(), null);

    for (AreaDataset.AreaEntity e : list) {
        tree.add(parent, e);
    }

    for (AreaDataset.AreaEntity e : list) {
        this.buildTree(tree, ds, e);
    }
}
  • 適配到RecyclerView.Adapter

通過TreeListget()size()介面,可以獲取到當前可見的節點資料。

this.adapter = new BridgeAdapter(getActivity(), new BridgeAdapterProvider() {
    @Override
    public Object get(int position) {
        return treeList.get(position);
    }

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

二、設計理念

功能設計上要求不需要調整既有的程式碼結構,僅僅是擴充套件功能,所有設計時作了以下幾點限制:

  • 不依賴於RecyclerView

  • 不依賴於Adapter

  • 不依賴於ViewHolder

  • 不依賴於Object

所以使用TreeList,不需要調整現有的任何程式碼。

只需要稍微修改RecyclerView.Adapter的程式碼即可無縫對接。

三、程式碼解析

  • 樹形資料結構
package javax.swing.tree;
	TreeNode.java
	MutableTreeNode.java
	DefaultMutableTreeNode.java

直接拷貝了一份JavaSE的程式碼,不需要重新造輪子。

  • TreeList
package club.andnext.recyclerview.tree;
	TreeList.java // Tree->List轉換
	TreeListAdapterCallback.java // 回撥介面,通知節點變化
  • TreeList的主要屬性
Node root; // all nodes

ArrayList<Node> expandList; // expanded nodes

ArrayList<Node> nodeList; // visible nodes

TreeList.Callback callback; // RecyclerView.Adapter callback to notify changed
  • TreeList的主要方法

第一層:構建並顯示資料內容

public void add(Object parent, Object child); // 構建樹形結構

public Object get(int index); // 獲取可見節點資料
public int size(); // 可見節點數

public int getChildCount(Object obj); // 獲取節點的child個數
public boolean isLeaf(Object obj); // 判斷是否葉子節點
public boolean isExpand(Object obj); // 判斷是否展開

public int getLevel(Object obj); // 當前資料所處level
public int getLevel(); // 最大level

第二層:展開、摺疊資料節點

public boolean setExpand(Object obj, boolean expand); // 設定展開或摺疊

第三層:新增、刪除節點

public void add(Object parent, Object child); // 新增資料

public void remove(Object obj); // 刪除資料