演示代码
演示工程项目
点击下载演示APK
导入相关模块andnext_recyclerview基于RecyclerView的封装,包含了本文中的树形实现;
andnext_overscrollRecyclerView的OverScroll依赖;
andnext_java部分代码依赖于JavaSE;
下载地址:https://github.com/jicanghai37927/WhatsAndroid
实例化TreeListTreeList参考了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的代码即可无缝对接。
直接拷贝了一份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); // 删除数据