基於RecyclerView的樹形結構
阿新 • • 發佈:2018-11-13
基於RecyclerView的樹形結構
一、使用方式Usage
- 實現效果
- 匯入相關模組
andnext_recyclerview
基於RecyclerView的封裝,包含了本文中的樹形實現;
andnext_overscroll
RecyclerView的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); } });
- 構建樹形結構
通過TreeList
的add(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
通過TreeList
的get()
與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); // 刪除資料