控件:多级树(第三方AndroidTreeView)

版权声明:本文为博主原创文章,码字不易,转载时请标明具体出处(博主名+博客页面链接),万分感谢Thanks♪(・ω・)ノ https://blog.csdn.net/An_nAl/article/details/83379532

第三方框架AndroidTreeView官方网址Github Demo其中使用到一个 第三方图标框架Print 。

不使用图标库框架Print(因为不需要)。

分析第三方框架AndroidTreeView:

        每一层使用LinearLayout添加内部节点(TreeNodeWrapperView)。

一、实现的功能

        默认显示所有年级名称;点击某一个年级,加载其所有班级名称;点击某一班级,加载其所有学生名称。年级、班级单选,学生可多选。选择的项文字变红,没选择的是黑色。相应的箭头会根据状态改变。

二、运行效果

三、功能代码

因为功能需求,在library的AndroidTreeView中新增了一个方法:

   //新增函数:只展开自己;收缩自己及子节点
    public void toggleNode(TreeNode node,boolean includeSubnodes) {
        if (node.isExpanded()) {
            collapseNode(node, includeSubnodes);//收缩所有,包括子节点
        } else {
            expandNode(node, false);//只展开自己
        }

    }

Fragment代码:

功能逻辑处理整个过程

public class MoreListFragment extends Fragment {

    private TextView tvShow;
    private ViewGroup containerView;
    private AndroidTreeView tView;

    private TreeNode choseGradeNode;//已选的年级节点
    private String choseGradeStr;//已选的年级值
    private List<TreeNode> initGradeList = new ArrayList<>();//已初始化班级节点的年级
    private TreeNode choseClassNode;//已选的班级节点
    private String choseClassStr;//已选的班级值
    private List<TreeNode> initClassList = new ArrayList<>();//已初始化学生节点的班级
    private List<String> choseStudentList = new ArrayList<>();//已选的学生值
    private int nodeCount = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_default, null, false);
        containerView = (ViewGroup) rootView.findViewById(R.id.container);
        tvShow = (TextView) rootView.findViewById(R.id.status_bar);
        initGradeNodes();
        return rootView;
    }

    /**
     * 初始化年级节点
     */
    private void initGradeNodes(){
        TreeNode root = TreeNode.root();
        for (int i = 0; i < 3; i++) {
            TreeNode areaNode = new TreeNode(new TreeNodeHolder.IconTreeItem("grade_" + i, "" + nodeCount,0));
            nodeCount++;
            root.addChildren(areaNode);
        }
        tView = new AndroidTreeView(getActivity(), root);
        tView.setDefaultAnimation(true);
        tView.setUseAutoToggle(false);//不使用自动展开收缩
        tView.setDefaultContainerStyle(R.style.TreeNodeStyleCustom);//TreeNodeStyleCustom、 TreeNodeStyleDivided
        tView.setDefaultViewHolder(TreeNodeHolder.class);
        tView.setDefaultNodeClickListener(nodeClickListener);

        containerView.addView(tView.getView());
    }

    /**
     * 初始化指定班级节点下的所有班级节点
     * @param gradeNode 年级节点
     */
    private void initClassNodes(TreeNode gradeNode){
        for (int j = 0; j < 3; j++) {
            TreeNode classNode = new TreeNode(new TreeNodeHolder.IconTreeItem("class_" + j, "" + nodeCount,1));
            nodeCount++;
            tView.addNode(gradeNode,classNode);
        }
        initGradeList.add(gradeNode);
    }

    /**
     * 初始化指定班级节点下的所有学生节点
     * @param classNode 班级节点
     */
    private void initStudentNodes(TreeNode classNode){
        for (int j = 0; j < 3; j++) {
            TreeNode studentNode = new TreeNode(new TreeNodeHolder.IconTreeItem("student_" + j, "" + nodeCount,2));
            nodeCount++;
            tView.addNode(classNode,studentNode);
        }
        initClassList.add(classNode);
    }

    /**
     * 多级树节点点击事件
     */
    private TreeNode.TreeNodeClickListener nodeClickListener = new TreeNode.TreeNodeClickListener() {
        @Override
        public void onClick(TreeNode node, Object value) {
            TreeNodeHolder.IconTreeItem item = (TreeNodeHolder.IconTreeItem) value;
            switch (item.level){
                case 0:
                    choseClassNode = null;
                    choseClassStr = "";
                    choseStudentList.clear();
                    if (choseGradeNode != null){//之前已选过节点
                        TreeNodeHolder.IconTreeItem choseAreaNodeValue = (TreeNodeHolder.IconTreeItem) choseGradeNode.getValue();
                        if (!item.id.equals(choseAreaNodeValue.id)) {
                            //此节点 != 上次选择的节点,则取消、收缩上次的节点及其子节点
                            tView.toggleNode(choseGradeNode, true);
                        }
                    }
                    choseGradeNode = node;
                    tView.toggleNode(node, true);//只展开此节点或收缩此节点及其子节点
                    if(node.isExpanded()){//选择此节点
                        choseGradeStr = item.text;
                        if(!initGradeList.contains(node)){//此节点还未初始化过子节点
                            initClassNodes(node);
                        }
                    }else {//取消此节点
                        choseGradeStr = "";
                        choseGradeNode = null;
                    }
                    break;
                case 1:
                    choseStudentList.clear();
                    if (choseClassNode != null){//之前已选过节点
                        TreeNodeHolder.IconTreeItem choseHspNodeValue = (TreeNodeHolder.IconTreeItem) choseClassNode.getValue();
                        if (!item.id.equals(choseHspNodeValue.id)) {
                            //此节点 != 上次选择的节点,则取消、收缩上次的节点
                            tView.toggleNode(choseClassNode, true);
                        }
                    }
                    choseClassNode = node;
                    tView.toggleNode(node, true);//只展开此节点或收缩此节点及其子节点
                    if(node.isExpanded()){//选择此节点
                        choseClassStr = item.text;
                        if(!initClassList.contains(node)){//此节点还未初始化过子节点
                            initStudentNodes(node);
                        }
                    }else {//取消此节点
                        choseClassStr = "";
                        choseClassNode = null;
                    }
                    break;
                case 2:
                    if(!choseStudentList.contains(item.text)){
                        choseStudentList.add(item.text);
                    }else {
                        choseStudentList.remove(item.text);
                    }
                    tView.toggleNode(node, true);
                    break;
            }
            tvShow.setText("["+choseGradeStr+"]_["+choseClassStr+"]_"+choseStudentList.toString());
        }
    };
}

ViewHolder:

public class TreeNodeHolder extends TreeNode.BaseNodeViewHolder<TreeNodeHolder.IconTreeItem> {

    private TextView tvValue;
    private ImageView ivArrowIcon;

    public TreeNodeHolder(Context context) {
        super(context);
    }

    @Override
    public View createNodeView(final TreeNode node, final IconTreeItem value) {
        final LayoutInflater inflater = LayoutInflater.from(context);
        final View view = inflater.inflate(R.layout.item_tree_node, null, false);
        tvValue = (TextView) view.findViewById(R.id.node_value);
        tvValue.setText(value.text);
        ivArrowIcon = (ImageView) view.findViewById(R.id.iv_arrow_icon);
        if (value.level == 2) {
            ivArrowIcon.setVisibility(View.GONE);
        }
        return view;
    }

    @Override
    public void toggle(boolean active) {
        ivArrowIcon.setImageDrawable(context.getResources().getDrawable(active ? R.mipmap.ic_node_open:R.mipmap.ic_node_close));
        tvValue.setTextColor(context.getResources().getColor(active ? R.color.text_red : R.color.text_black));
    }

    public static class IconTreeItem {
        public String text;//文字
        public String id;
        public int level;

        public IconTreeItem(String text,String id,int level) {
            this.text = text;
            this.id = id;
            this.level = level;
        }
    }
}

fragment的布局:

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

    <TextView
        android:padding="8dp"
        android:textSize="16sp"
        android:text="Last Clicked:"
        android:layout_alignParentTop="true"
        android:background="@android:color/holo_blue_dark"
        android:id="@+id/status_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <RelativeLayout
        android:layout_below="@id/status_bar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/container"></RelativeLayout>


</RelativeLayout>

item的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:minHeight="48dp"
    android:gravity="center_vertical"
    android:background="?android:attr/selectableItemBackground"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/iv_arrow_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:gravity="center"
            android:src="@mipmap/ic_node_close"
            android:scaleType="centerInside"/>
        <TextView
            android:textSize="16sp"
            android:layout_marginLeft="10dp"
            android:id="@+id/node_value"
            android:textColor="@color/text_black"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
</RelativeLayout>

猜你喜欢

转载自blog.csdn.net/An_nAl/article/details/83379532