Android自定义任意层级树形控件

Android自定义任意层级树形控件

简介:

开发项目时,偶尔会遇到诸如展示公司员工结构,商品分类显示,文件管理…的问题。大家自然会想到ExpandableListView。但,问题是其目前基本只支持两级且数据集的组织较复杂。接下来,我给大家介绍一种自定义任意层级树形控件的方法。

效果展示图:

连真机演示

基本原理:

  • ListView’s item + paddingLeft(level) + expand + include

  • 将数据库中的数据 Bean 转化wei树形结构里的 Node

  • 通过 反射+注解 实现通用的获取任意Bean中的数据

主要代码逻辑:

  • 将用户的数据转化为树的节点

  • 设置节点间的关系(父子,兄弟)

  • 对节点进行排序(形成树形结构)

  • 过滤出需要在界面显示的数据

书写代码:

1)创建节点类Node

1_1)新建包bean——>FileBean.java(保存数据库实体属性)

代码如下:

    package com.qiyu.treeview.bean;

    /**
     * Created by qiyu on 2016/4/29.
     */

    public class FileBean {
        private int id;//主键
        private int PId;//父节点Id
        private String label;//描述信息
        private String desc;//其他描述信息
        //....

        public FileBean() {
        }

        public FileBean(int id, int PId, String label) {
            this.id = id;
            this.PId = PId;
            this.label = label;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public int getPId() {
            return PId;
        }

        public void setPId(int PId) {
            this.PId = PId;
        }

        public String getLabel() {
            return label;
        }

        public void setLabel(String label) {
            this.label = label;
        }

        public String getDesc() {
            return desc;
        }

        public void setDesc(String desc) {
            this.desc = desc;
        }
    }
1_2)新建包utils—>Node.java(设置节点信息)


代码如下:

    package com.qiyu.treeview.utils;

    import java.util.ArrayList;
    import java.util.List;

    /**
     * Created by qiyu on 2016/4/29.
     */
    public class Node {
        private int id;//节点Id
        private int PId = 0;//根节点PId为0,表示目前没有子节点
        private String name;//节点描述信息
        private int level;//节点层次
        private boolean isExpand = false;//节点是否展开
        private int icon;//节点图标
        private Node parent;//父节点
        private List<Node> children = new ArrayList<>();//子节点

        public Node() {
        }

        public Node(int id, int PId, String name) {
            this.id = id;
            this.PId = PId;
            this.name = name;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public int getPId() {
            return PId;
        }

        public void setPId(int PId) {
            this.PId = PId;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }


        public void setLevel(int level) {
            this.level = level;
        }

        public boolean isExpand() {
            return isExpand;
        }

        public int getIcon() {
            return icon;
        }

        public void setIcon(int icon) {
            this.icon = icon;
        }

        public Node getParent() {
            return parent;
        }

        public void setParent(Node parent) {
            this.parent = parent;
        }

        public List<Node> getChildren() {
            return children;
        }

        public void setChildren(List<Node> children) {
            this.children = children;
        }

        //是否为根节点
        public boolean isRoot() {
            return parent == null;
        }

        //是否为叶子节点
        public boolean isLeaf() {
            return children.size() == 0;
        }

        //当前父节点的收缩状态
        public boolean isParentExpand() {
            if (parent == null) {
                return false;
            }
            return parent.isExpand();
        }

        //设置节点收缩状态,如果父节点收缩,所有子节点也收缩
        public void setExpand(boolean expand) {
            isExpand = expand;
            if (!isExpand) {
                for (Node node : children) {
                    node.setExpand(false);
                }
            }
        }

        //获取节点层级
        public int getLevel() {
            return parent == null ? 0 : parent.getLevel() + 1;
        }
    }

2)将用户数据转化为Node节点

2_1)utils—>TreeHelper.java(辅助类:将Bean转化为Node)

代码如下(代码未完结):

package com.qiyu.treeview.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by qiyu on 2016/4/29.
 */
//辅助类:将Bean转化为Node
public class TreeHelper {
    public static <T> List<Node> convertData2Nodes(List<T> datas) throws IllegalAccessException {
        List<Node> nodes = new ArrayList<>();
        Node node = null;
         /*循环遍历用户Bean数据,将其依次加入Node中:
            * 通过T—>找到相应的class—>对应的属性field—>加入node
            * */
        for (T t : datas) {
            int id = -1;
            int pid = -1;
            String label = null;
            node = new Node();
            Class clazz = t.getClass();
            Field[] fields = clazz.getFields();
            for (Field field : fields) {
                //1,命名规范。PS:id统一为nodeId....不灵活,用户体验不好
                //2,注解+反射。注解:定位,给id加一个标志;反射:通过注解取值
            }
            //遍历完属性,将id,pid,label添加到node中
            node = new Node(id, pid, label);
            nodes.add(node);
        }
        return nodes;
    }
}
2_2)utils—>annotation—>TreeNodeId.java(为FileBean里的id添加注解)

代码如下:

package com.qiyu.treeview.utils.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by qiyu on 2016/5/3.
 */
//注解的声明
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值