package com.bigfat.treeview.utils; import com.bigfat.treeview.R; import com.bigfat.treeview.annotation.TreeNodeId; import com.bigfat.treeview.annotation.TreeNodeLabel; import com.bigfat.treeview.annotation.TreeNodePId; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; /** * @author <a href="mailto:fbzhh007@gmail.com">bigfat</a> * @since 2015/2/10 */ public class TreeHelper { /** * 将用户数据转换为序列化的树形数据 * * @param datas 用户数据 * @param defaultExpandLevel 默认展开层级 * @return 序列换的树形数据 * @throws IllegalAccessException */ public static <T> List<Node> getSortedNodes(List<T> datas, int defaultExpandLevel) throws IllegalAccessException { List<Node> result = new ArrayList<>();//排序后的结果 List<Node> nodes = convertDatas2Nodes(datas);//转换的树形数据 //获得树的根节点 List<Node> rootNodes = getRootNodes(nodes); for (Node node : rootNodes) { addNode(result, node, defaultExpandLevel, 1); } return result; } /** * 过滤出需要显示的节点 * * @param nodes 序列化树形数据 */ public static List<Node> filterVisibleNodes(List<Node> nodes) { List<Node> result = new ArrayList<>(); for (Node n : nodes) { if (n.isRoot() || n.isParentExpand()) { setNodeIcon(n); result.add(n); } } return result; } /** * 遍历根节点像序列化树形数据中添加节点 * * @param result 序列化树形数据 * @param node 根节点 * @param defaultExpandLevel 默认展开层级 * @param currentLevel 当前添加节点层级 */ private static void addNode(List<Node> result, Node node, int defaultExpandLevel, int currentLevel) { //加入当前节点 result.add(node); //判断当前节点是否展开 if (defaultExpandLevel >= currentLevel) { node.setExpand(true); } //如果是叶子节点则表示当前分支遍历完毕 if (node.isLeaf()) { return; } //不是叶子节点则继续遍历 for (Node n : node.getChildren()) { addNode(result, n, defaultExpandLevel, currentLevel + 1); } } /** * 获得树的根节点 * * @param nodes 树形数据 */ private static List<Node> getRootNodes(List<Node> nodes) { List<Node> rootNodes = new ArrayList<>(); for (Node n : nodes) { if (n.isRoot()) { rootNodes.add(n); } } return rootNodes; } /** * 将用户的数据转换为树形数据 * * @param datas 用户数据 * @param <T> 用户数据类型 * @return 转换后的树形数据 */ private static <T> List<Node> convertDatas2Nodes(List<T> datas) throws IllegalAccessException { List<Node> nodes = new ArrayList<>(); Node node = null; for (T t : datas) { int id = -1; int pId = -1; String label = null; Class clazz = t.getClass(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (field.getAnnotation(TreeNodeId.class) != null) { field.setAccessible(true); id = field.getInt(t); } else if (field.getAnnotation(TreeNodePId.class) != null) { field.setAccessible(true); pId = field.getInt(t); } else if (field.getAnnotation(TreeNodeLabel.class) != null) { field.setAccessible(true); label = (String) field.get(t); } } node = new Node(id, pId, label); nodes.add(node); } //设置父子关系 for (int i = 0; i < nodes.size(); i++) { Node n1 = nodes.get(i); for (int j = i + 1; j < nodes.size(); j++) { Node n2 = nodes.get(j); if (n1.getpId() == n2.getId()) {//n2是n1的父亲 n2.getChildren().add(n1); n1.setParent(n2); } else if (n1.getId() == n2.getpId()) {//n2是n1的孩子 n2.setParent(n1); n1.getChildren().add(n2); } } } //设置节点展开状态图片 for (Node n : nodes) { setNodeIcon(n); } return nodes; } /** * 设置节点展开状态图片 */ private static void setNodeIcon(Node node) { if (node.getChildren().size() <= 0) {//没有孩子 node.setIcon(-1); } else if (node.isExpand()) {//有孩子且展开 node.setIcon(R.mipmap.tree_ex); } else {//有孩子未展开 node.setIcon(R.mipmap.tree_ec); } } }