ListView实现多级树形菜单

项目中需要用到使用到多级树形菜单,敲了个简单的demo
项目地址:http://download.csdn.net/download/weixin_40391500/10102547
这里写图片描述

根节点实体类TreePatent.java,各个分组之间的关系是根据ID和parentID关联的,根据ID添加分支节点

/**
 * Created by pc20170521 on 2017-11-01.
 * 分组实例
 */
public class TreePatent {
    private int id;//对应节点的groupId
    private int parentId;//父类编号
    private String name;//名称

    /**
     *
     * @param id
     * @param parentId
     * @param name
     */
    public TreePatent(int id, int parentId, String name) {
        this.id = id;
        this.parentId = parentId;
        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public int getParentId() {
        return parentId;
    }

    public void setParentId(int parentId) {
        this.parentId = parentId;
    }

    public String getName() {
        return name;
    }

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

}

子叶节点实体类TreeInfo.Java,根据groupId与组id对应添加叶节点

/**
 * Created by pc20170521 on 2017-11-01.
 * 子节点实例
 */
public class TreeInfo {
    private int id;
    private int groupId;//组ID
    private String name;

    public TreeInfo(int id, int groupId, String name) {
        this.id = id;
        this.groupId = groupId;
        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public int getGroupId() {
        return groupId;
    }

    public void setGroupId(int groupId) {
        this.groupId = groupId;
    }

    public String getName() {
        return name;
    }

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

树结构类TreeNode.java

/**
 * Created by pc20170521 on 2017-11-01.
 * 树结构
 */
public class TreeNode {

    private TreeNode parent = null;//父节点
    private String name;//名称
    private boolean isLeaf = false;//是否为叶节点
    private boolean isExpanded = false;//该节点是否展开
    private ArrayList<TreeNode> childList = null;//子树
    private boolean isCheck = false;

    public TreeNode(TreeNode treeNode, String name, boolean isLeaf){
        this.parent = treeNode;
        this.name = name;
        this.isLeaf = isLeaf;
    }

    public TreeNode getParent() {
        return parent;
    }

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

    public String getName() {
        return name;
    }

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

    public boolean isLeaf() {
        return isLeaf;
    }

    public void setLeaf(boolean leaf) {
        isLeaf = leaf;
    }

    public ArrayList<TreeNode> getChildList() {
        return childList;
    }

    public void setChildList(ArrayList<TreeNode> childList) {
        this.childList = childList;
    }

    public boolean isCheck() {
        return isCheck;
    }

    public void setCheck(boolean check) {
        isCheck = check;
    }

    //得到当前节点所在的层数,根为0层
    public int getLevel(){
        return parent == null?0:parent.getLevel() + 1;
    }

    public boolean isExpanded() {
        return isExpanded;
    }

    public void setExpanded(boolean expanded) {
        isExpanded = expanded;
    }

    //添加子节点
    public void addChildNode(TreeNode node){
        if (childList == null){
            childList = new ArrayList<>();
        }
        childList.add(node);
    }

    //清空子节点
    public void clearChildren(){
        if (childList != null){
            childList.clear();
        }
    }

}

activity类

public class MainActivity extends AppCompatActivity {

    private ListView lv_tree;
    private TreeNodeAdapter adapter;
    private TreeNode parent;
    private ArrayList<TreePatent> patentList = new ArrayList<>();
    private ArrayList<TreeInfo> mList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();
        addListener();
    }

    private void initData() {
        //组
        TreePatent patent1 = new TreePatent(1, 0, "A");//id, parentId, name
        TreePatent patent2 = new TreePatent(2, 0, "AA");
        TreePatent patent3 = new TreePatent(3, 0, "AAA");
        TreePatent patent4 = new TreePatent(4, 0, "AAA_A");
        TreePatent patent5 = new TreePatent(5, 0, "AAA_AA");
        TreePatent patent6 = new TreePatent(6, 1, "AAA_AAA");
        TreePatent patent7 = new TreePatent(7, 2, "AAA_AAA_A");
        TreePatent patent8 = new TreePatent(8, 3, "AAA_AAA_AA");
        TreePatent patent9 = new TreePatent(9, 6, "AAA_AAA_AAA");
        patentList.add(patent1);
        patentList.add(patent2);
        patentList.add(patent3);
        patentList.add(patent4);
        patentList.add(patent5);
        patentList.add(patent6);
        patentList.add(patent7);
        patentList.add(patent8);
        patentList.add(patent9);

        //组对应节点
        TreeInfo info1 = new TreeInfo(0, 1, "B");//id, groupId, name
        TreeInfo info2 = new TreeInfo(1, 1, "BB");
        TreeInfo info3 = new TreeInfo(2, 1, "BBB");
        TreeInfo info4 = new TreeInfo(3, 2, "C");
        TreeInfo info5 = new TreeInfo(4, 2, "CC");
        TreeInfo info6 = new TreeInfo(5, 3, "D");
        TreeInfo info7 = new TreeInfo(6, 4, "E");
        TreeInfo info8 = new TreeInfo(7, 4, "EE");
        TreeInfo info9 = new TreeInfo(8, 5, "F");
        TreeInfo info10 = new TreeInfo(9, 5, "FF");
        TreeInfo info11 = new TreeInfo(10, 6, "J");
        TreeInfo info12 = new TreeInfo(11, 6, "JJ");
        TreeInfo info13 = new TreeInfo(12, 7, "K");
        TreeInfo info14 = new TreeInfo(13, 8, "M");
        TreeInfo info15 = new TreeInfo(14, 9, "N");
        mList.add(info1);
        mList.add(info2);
        mList.add(info3);
        mList.add(info4);
        mList.add(info5);
        mList.add(info6);
        mList.add(info7);
        mList.add(info8);
        mList.add(info9);
        mList.add(info10);
        mList.add(info11);
        mList.add(info12);
        mList.add(info13);
        mList.add(info14);
        mList.add(info15);
        parent = new TreeNode(null, "树形列表", false);
        initTreeRoot(parent, 0);
    }

    //添加分支节点
    private void initTreeRoot(TreeNode parent, int parentId){
        for (int i = 0; i < patentList.size(); i++ ) {
            TreePatent treeParent = patentList.get(i);
            if (parentId == treeParent.getParentId()){
                TreeNode treeNode = new TreeNode(parent, treeParent.getName(), false);
                initTreeRoot(treeNode, treeParent.getId());
                parent.addChildNode(treeNode);
            }
        }
        initTreeChild(parent, parentId);
    }

    //添加子叶节点
    private void initTreeChild(TreeNode parent, int groupId) {
        for (int i = 0; i < mList.size(); i++) {
            TreeInfo treeInfo = mList.get(i);
            if (groupId == treeInfo.getGroupId()){
                TreeNode treeNode = new TreeNode(parent, treeInfo.getName(), true);
                parent.addChildNode(treeNode);
            }
        }
    }

    private void initView() {
        lv_tree = (ListView) findViewById(R.id.lv_tree);
        adapter = new TreeNodeAdapter(this, parent);
        lv_tree.setAdapter(adapter);
    }

    private void addListener() {
        lv_tree.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                adapter.OnClickListener(position, false, false, "");
            }
        });
    }
}

main_activity.xml布局文件


    <ListView
        android:id="@+id/lv_tree"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

装配树结构,TreeNodeAdapter.Java类,

/**
 * Created by pc20170521 on 2017-11-01.
 */
public class TreeNodeAdapter extends BaseAdapter {

    private Context mContext;
    private LayoutInflater mInflater;
    private TreeNode root;

    private ArrayList<TreeNode> mListNode = new ArrayList<>();//所有的节点
    private ArrayList<TreeNode> mListTree = new ArrayList<>();//要展现的节点

    public TreeNodeAdapter(Context context, TreeNode treeNode){
        mContext = context;
        root = treeNode;
        mInflater = LayoutInflater.from(mContext);
        mListNode.clear();
        setTreeNode(root);
        setTreeNodeToShow(false, false, "");
    }

    /***
     *添加所有节点到mListNode列表中
     * @param node
     */
    public void setTreeNode(TreeNode node){
        mListNode.add(node);
        if (node.isLeaf())return;
        List<TreeNode> child = node.getChildList();
        if (child == null)return;
        for (int i = 0; i < child.size(); i++) {
            setTreeNode(child.get(i));
        }
    }

    private void setTreeNodeToShow(boolean isCheck, boolean state, String name){
        mListTree.clear();
        treeNodeToShow(this.root, isCheck, state, name);
    }

    /**
     * 装配所有展开的节点数据显示出来
     * @param node
     * @param isCheck
     * @param state
     * @param name
     */
    private void treeNodeToShow(TreeNode node, boolean isCheck, boolean state, String name) {
        mListTree.add(node);
        if (node.isExpanded()
                && !node.isLeaf()
                && node.getChildList() != null){
            List<TreeNode> children = node.getChildList();
            for (int i = 0; i < children.size(); i++) {
                if (state && node.getName().equals(name)){
                    node.setCheck(isCheck);
                    children.get(i).setCheck(isCheck);
                    changceCheck(children.get(i), state);
                }
                treeNodeToShow(children.get(i), isCheck, state, name);
            }
        }
    }

    /**
     * 改变子节点状态
     * @param node
     * @param state
     */
    public void changceCheck(TreeNode node, boolean state){
        if (state){
            List<TreeNode> child = node.getChildList();
            if (child != null){
                for (int j = 0; j < child.size(); j++) {
                    child.get(j).setCheck(node.isCheck());
                    changceCheck(child.get(j), state);
                }
            }
        }
    }

    /**
     * 改变展开/收起状态
     * @param node
     * @param isCheck
     * @param state
     */
    public void changceExpandedTree(TreeNode node, boolean isCheck, boolean state){
        for (int i = 0; i < mListNode.size(); i++) {
            if (node.getName().equals(mListNode.get(i).getName())){
                if (state){
                    mListNode.get(i).setCheck(isCheck);
                }else {
                    boolean flag = mListNode.get(i).isExpanded();
                    mListNode.get(i).setExpanded(!flag);
                }
            }
        }
    }

    /**
     * 点击item
     * @param isCheck
     * @param state  true位点击ChechBox, false为点击item
     * @param name
     */
    public void OnClickListener(int position, boolean isCheck, boolean state, String name){
        TreeNode node = mListTree.get(position);
        if (node.isLeaf()){
            if (state){
                for (int i = 0; i < mListNode.size(); i++) {
                    if (node.getName().equals(mListNode.get(i).getName())){
                        mListNode.get(i).setCheck(isCheck);
                    }
                }
            }
        }else {
            changceExpandedTree(node, isCheck, state);
            setTreeNodeToShow(isCheck, state, name);
            notifyDataSetChanged();
        }
    }

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

    @Override
    public Object getItem(int position) {
        return mListTree.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if (convertView == null){
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.tree_item, null);
            holder.cb_check = convertView.findViewById(R.id.cb_check);
            holder.tv_expanded = convertView.findViewById(R.id.tv_expanded);
            holder.tv = convertView.findViewById(R.id.tv);
            convertView.setTag(holder);
        }else {
            holder = (ViewHolder) convertView.getTag();
        }

        final TreeNode node = mListTree.get(position);
        holder.cb_check.setChecked(node.isCheck());

        if (!node.isLeaf()){
            if (node.isExpanded()){
                holder.tv_expanded.setVisibility(View.VISIBLE);
                holder.tv_expanded.setText("-");
            }else {
                holder.tv_expanded.setVisibility(View.VISIBLE);
                holder.tv_expanded.setText("+");
            }
        }else {
            holder.tv_expanded.setVisibility(View.GONE);
        }
        holder.tv.setText(node.getName());

        holder.cb_check.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                OnClickListener(position, holder.cb_check.isChecked(), true, node.getName() );
            }
        });

        convertView.setPadding(node.getLevel()*50, 0, 0, 0);//根据节点树级排布节点位置
        return convertView;
    }

    class ViewHolder{
        private CheckBox cb_check;
        private TextView tv_expanded;
        private TextView tv;
    }

}

tree_item.xml布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:descendantFocusability="blocksDescendants"
    android:orientation="horizontal">

    <CheckBox
        android:id="@+id/cb_check"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_expanded"
        android:layout_width="10dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:gravity="center"
        android:textSize="20sp"
        />

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:gravity="center_vertical"
        android:textSize="20sp"
        />

</LinearLayout>

项目地址:http://download.csdn.net/download/weixin_40391500/10102547

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值