zoukankan      html  css  js  c++  java
  • 22.Android之ExpandableListView树形列表学习

    Android经常用到树形菜单,一般ExpandableListView可以满足这个需要,今天学习下。

    XML代码:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:orientation="vertical" >
     6 
     7     <LinearLayout
     8         android:layout_width="match_parent"
     9         android:layout_height="wrap_content" >
    10 
    11         <Button
    12             android:id="@+id/btn_tree"
    13             android:layout_width="wrap_content"
    14             android:layout_height="wrap_content"
    15             android:layout_weight="1"
    16             android:text="两层结构" />
    17 
    18      
    19         <Button
    20             android:id="@+id/btn_supertree"
    21             android:layout_width="wrap_content"
    22             android:layout_height="wrap_content"
    23             android:layout_weight="1"
    24             android:text="三层结构" />
    25 
    26     </LinearLayout>
    27 
    28     <ExpandableListView
    29         android:id="@+id/expandlist1"
    30         android:layout_width="match_parent"
    31         android:layout_height="wrap_content" >
    32     </ExpandableListView>
    33 
    34 </LinearLayout>

    接下来增加两个类TreeViewAdapter,SuperTreeViewAdaper继承BaseExpandableListAdapter,实现两层结构和三层结构效果:

    TreeViewAdapter代码:

      1 package com.example.expandlistdemo;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 import android.content.Context;
      6 import android.util.Log;
      7 import android.view.Gravity;
      8 import android.view.View;
      9 import android.view.ViewGroup;
     10 import android.widget.AbsListView;
     11 import android.widget.BaseExpandableListAdapter;
     12 import android.widget.TextView;
     13 
     14 public class TreeViewAdapter extends BaseExpandableListAdapter {
     15 
     16     public static final int ItemHeight = 48;
     17     public static final int PaddingLeft = 36;
     18     private int myPaddingLeft = 0;
     19 
     20     static public class TreeNode {
     21         Object parent;
     22         List childs = new ArrayList();
     23     }
     24 
     25     List<TreeNode> treeNodes = new ArrayList<TreeNode>();
     26     Context parentContext;
     27 
     28     public TreeViewAdapter(Context view, int myPaddingLeft) {
     29         parentContext = view;
     30         this.myPaddingLeft = myPaddingLeft;
     31     }
     32 
     33     public List<TreeNode> GetTreeNode() {
     34         return treeNodes;
     35     }
     36 
     37     public void UpdateTreeNode(List<TreeNode> nodes) {
     38         treeNodes = nodes;
     39     }
     40 
     41     public void RemoveAll() {
     42         treeNodes.clear();
     43     }
     44 
     45     public Object getChild(int groupPosition, int childPosition) {
     46         return treeNodes.get(groupPosition).childs.get(childPosition);
     47     }
     48 
     49     public int getChildrenCount(int groupPosition) {
     50         return treeNodes.get(groupPosition).childs.size();
     51     }
     52 
     53     static public TextView getTextView(Context context) {
     54         AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
     55                 ViewGroup.LayoutParams.FILL_PARENT, ItemHeight);
     56 
     57         TextView textView = new TextView(context);
     58         textView.setLayoutParams(lp);
     59         textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
     60         return textView;
     61     }
     62 
     63     public View getChildView(int groupPosition, int childPosition,
     64             boolean isLastChild, View convertView, ViewGroup parent) {
     65         TextView textView = getTextView(this.parentContext);
     66         textView.setText(getChild(groupPosition, childPosition).toString());
     67         textView.setPadding(myPaddingLeft + PaddingLeft, 0, 0, 0);
     68         return textView;
     69     }
     70 
     71     public View getGroupView(int groupPosition, boolean isExpanded,
     72             View convertView, ViewGroup parent) {
     73         TextView textView = getTextView(this.parentContext);
     74         textView.setText(getGroup(groupPosition).toString());
     75         textView.setPadding(myPaddingLeft + (PaddingLeft >> 1), 0, 0, 0);
     76         return textView;
     77     }
     78 
     79     public long getChildId(int groupPosition, int childPosition) {
     80         return childPosition;
     81     }
     82 
     83     public Object getGroup(int groupPosition) {
     84         return treeNodes.get(groupPosition).parent;
     85     }
     86 
     87     public int getGroupCount() {
     88         return treeNodes.size();
     89     }
     90 
     91     public long getGroupId(int groupPosition) {
     92         return groupPosition;
     93     }
     94 
     95     public boolean isChildSelectable(int groupPosition, int childPosition) {
     96         return true;
     97     }
     98 
     99     public boolean hasStableIds() {
    100         return true;
    101     }
    102 
    103 }

    SuperTreeViewAdaper代码:

      1 package com.example.expandlistdemo;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 import com.example.expandlistdemo.TreeViewAdapter.TreeNode;
      6 import android.content.Context;
      7 import android.view.View;
      8 import android.view.ViewGroup;
      9 import android.widget.AbsListView;
     10 import android.widget.BaseExpandableListAdapter;
     11 import android.widget.ExpandableListView;
     12 import android.widget.ExpandableListView.OnChildClickListener;
     13 import android.widget.ExpandableListView.OnGroupCollapseListener;
     14 import android.widget.ExpandableListView.OnGroupExpandListener;
     15 import android.widget.TextView;
     16 
     17 public class SuperTreeViewAdaper extends BaseExpandableListAdapter {
     18 
     19     static public class SuperTreeNode {
     20         Object parent;
     21         // 二级树形菜单的结构体
     22         List<TreeNode> childs = new ArrayList<TreeNode>();
     23     }
     24 
     25     private List<SuperTreeNode> superTreeNodes = new ArrayList<SuperTreeNode>();
     26     private Context parentContext;
     27     private OnChildClickListener stvClickEvent;// 外部回调函数
     28 
     29     public SuperTreeViewAdaper(Context view, OnChildClickListener stvClickEvent) {
     30         parentContext = view;
     31         this.stvClickEvent = stvClickEvent;
     32     }
     33 
     34     public List<SuperTreeNode> GetTreeNode() {
     35         return superTreeNodes;
     36     }
     37 
     38     public void UpdateTreeNode(List<SuperTreeNode> node) {
     39         superTreeNodes = node;
     40     }
     41 
     42     public void RemoveAll() {
     43         superTreeNodes.clear();
     44     }
     45 
     46     public Object getChild(int groupPosition, int childPosition) {
     47         return superTreeNodes.get(groupPosition).childs.get(childPosition);
     48     }
     49 
     50     public int getChildrenCount(int groupPosition) {
     51         return superTreeNodes.get(groupPosition).childs.size();
     52     }
     53 
     54     public ExpandableListView getExpandableListView() {
     55         AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
     56                 ViewGroup.LayoutParams.FILL_PARENT, TreeViewAdapter.ItemHeight);
     57         ExpandableListView superTreeView = new ExpandableListView(parentContext);
     58         superTreeView.setLayoutParams(lp);
     59         return superTreeView;
     60     }
     61 
     62     /**
     63      * 三层树结构中的第二层是一个ExpandableListView
     64      */
     65     public View getChildView(int groupPosition, int childPosition,
     66             boolean isLastChild, View convertView, ViewGroup parent) {
     67         //
     68         final ExpandableListView treeView = getExpandableListView();
     69         final TreeViewAdapter treeViewAdapter = new TreeViewAdapter(
     70                 this.parentContext, 0);
     71         List<TreeNode> tmp = treeViewAdapter.GetTreeNode();// 临时变量取得TreeViewAdapter的TreeNode集合,可为空
     72         final TreeNode treeNode = (TreeNode) getChild(groupPosition,
     73                 childPosition);
     74         tmp.add(treeNode);
     75         treeViewAdapter.UpdateTreeNode(tmp);
     76         treeView.setAdapter(treeViewAdapter);
     77 
     78         // 关键点:取得选中的二级树形菜单的父子节点,结果返回给外部回调函数
     79         treeView.setOnChildClickListener(this.stvClickEvent);
     80 
     81         /**
     82          * 关键点:第二级菜单展开时通过取得节点数来设置第三级菜单的大小
     83          */
     84         treeView.setOnGroupExpandListener(new OnGroupExpandListener() {
     85             @Override
     86             public void onGroupExpand(int groupPosition) {
     87 
     88                 AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
     89                         ViewGroup.LayoutParams.FILL_PARENT, (treeNode.childs
     90                                 .size() + 1) * TreeViewAdapter.ItemHeight + 10);
     91                 treeView.setLayoutParams(lp);
     92             }
     93         });
     94 
     95         /**
     96          * 第二级菜单回收时设置为标准Item大小
     97          */
     98         treeView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
     99             @Override
    100             public void onGroupCollapse(int groupPosition) {
    101 
    102                 AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
    103                         ViewGroup.LayoutParams.FILL_PARENT,
    104                         TreeViewAdapter.ItemHeight);
    105                 treeView.setLayoutParams(lp);
    106             }
    107         });
    108         treeView.setPadding(TreeViewAdapter.PaddingLeft, 0, 0, 0);
    109         return treeView;
    110     }
    111 
    112     /**
    113      * 三级树结构中的首层是TextView,用于作为title
    114      */
    115     public View getGroupView(int groupPosition, boolean isExpanded,
    116             View convertView, ViewGroup parent) {
    117         TextView textView = TreeViewAdapter.getTextView(this.parentContext);
    118         textView.setText(getGroup(groupPosition).toString());
    119         textView.setPadding(TreeViewAdapter.PaddingLeft, 0, 0, 0);
    120         return textView;
    121     }
    122 
    123     public long getChildId(int groupPosition, int childPosition) {
    124         return childPosition;
    125     }
    126 
    127     public Object getGroup(int groupPosition) {
    128         return superTreeNodes.get(groupPosition).parent;
    129     }
    130 
    131     public int getGroupCount() {
    132         return superTreeNodes.size();
    133     }
    134 
    135     public long getGroupId(int groupPosition) {
    136         return groupPosition;
    137     }
    138 
    139     public boolean isChildSelectable(int groupPosition, int childPosition) {
    140         return true;
    141     }
    142 
    143     public boolean hasStableIds() {
    144         return true;
    145     }
    146 }

    修改下MainActivity.java:

      1 package com.example.expandlistdemo;
      2 
      3 import java.util.List;
      4 
      5 import android.app.Activity;
      6 import android.os.Bundle;
      7 import android.view.View;
      8 import android.widget.Button;
      9 import android.widget.ExpandableListView;
     10 import android.widget.ExpandableListView.OnChildClickListener;
     11 import android.widget.Toast;
     12 
     13 public class MainActivity extends Activity {
     14 
     15     private Button btnTree;
     16     private Button btnSuperTree;
     17     private ExpandableListView expandlist;
     18     private TreeViewAdapter adapter;
     19     private SuperTreeViewAdaper superAdapter;
     20 
     21     public String[] groupTree = { "老师", "学生", "朋友" };
     22     public String[][] child = { { "王老师", "陈老师", "李老师", "黄老师" },
     23             { "学生甲", "学生乙", "学生丙" }, { "朋友甲", "朋友丁" } };
     24 
     25     public String[] parent = { "老师", "学生" };
     26     public String[][][] child_grandson = { { { "王老师" }, { "AA", "AAA" } },
     27             { { "陈老师" }, { "BBB", "BBBB", "BBBBB" } },
     28             { { "李老师" }, { "CCC", "CCCC" } },
     29             { { "黄老师" }, { "DDD", "DDDD", "DDDDD" } } };
     30 
     31     /**
     32      * 三级树形菜单的事件不再可用,本函数由三级树形菜单的子项(二级菜单)进行回调
     33      */
     34     OnChildClickListener stvClickEvent = new OnChildClickListener() {
     35 
     36         @Override
     37         public boolean onChildClick(ExpandableListView parent, View v,
     38                 int groupPosition, int childPosition, long id) {
     39 
     40             String str = "parent id:" + String.valueOf(groupPosition)
     41                     + ",children id:" + String.valueOf(childPosition);
     42             Toast.makeText(getApplicationContext(), str, 300).show();
     43 
     44             return false;
     45 
     46         }
     47 
     48     };
     49     
     50     @Override
     51     protected void onCreate(Bundle savedInstanceState) {
     52         super.onCreate(savedInstanceState);
     53         setContentView(R.layout.activity_main);
     54 
     55         btnTree = (Button) findViewById(R.id.btn_tree);
     56         btnSuperTree = (Button) findViewById(R.id.btn_supertree);
     57 
     58         adapter = new TreeViewAdapter(this, TreeViewAdapter.PaddingLeft >> 1);
     59 
     60         superAdapter = new SuperTreeViewAdaper(this, stvClickEvent);
     61         expandlist = (ExpandableListView) findViewById(R.id.expandlist1);
     62 
     63         btnTree.setOnClickListener(new View.OnClickListener() {
     64 
     65             @Override
     66             public void onClick(View v) {
     67 
     68                 adapter.RemoveAll();
     69                 adapter.notifyDataSetChanged();
     70                 superAdapter.RemoveAll();
     71                 superAdapter.notifyDataSetChanged();
     72  
     73                 List treeNode = adapter.GetTreeNode();
     74                 for (int i = 0; i < groupTree.length; i++) {
     75                     TreeViewAdapter.TreeNode node = new TreeViewAdapter.TreeNode();
     76                     node.parent = groupTree[i];
     77                     for (int ii = 0; ii < child[i].length; ii++) {
     78                         node.childs.add(child[i][ii]);
     79                     }
     80                     treeNode.add(node);
     81                 }
     82 
     83                 adapter.UpdateTreeNode(treeNode);
     84                 expandlist.setAdapter(adapter);
     85                 expandlist.setOnChildClickListener(new OnChildClickListener() {
     86 
     87                     @Override
     88                     public boolean onChildClick(ExpandableListView arg0,
     89                             View arg1, int parent, int children, long arg4) {
     90 
     91                         String str = "parent id:" + String.valueOf(parent)
     92                                 + ",children id:" + String.valueOf(children);
     93                         Toast.makeText(getApplicationContext(), str, 300)
     94                                 .show();
     95                         return false;
     96                     }
     97                 });
     98 
     99             }
    100         });
    101 
    102         btnSuperTree.setOnClickListener(new View.OnClickListener() {
    103 
    104             @Override
    105             public void onClick(View v) {
    106 
    107                 adapter.RemoveAll();
    108                 adapter.notifyDataSetChanged();
    109                 superAdapter.RemoveAll();
    110                 superAdapter.notifyDataSetChanged();
    111 
    112                 List superTreeNode = superAdapter.GetTreeNode();
    113                 for (int i = 0; i < parent.length; i++) // 第一层
    114                 {
    115                     SuperTreeViewAdaper.SuperTreeNode superNode = new SuperTreeViewAdaper.SuperTreeNode();
    116                     superNode.parent = parent[i];
    117 
    118                     // 第二层
    119                     for (int ii = 0; ii < child_grandson.length; ii++) {
    120                         TreeViewAdapter.TreeNode node = new TreeViewAdapter.TreeNode();
    121                         node.parent = child_grandson[ii][0][0];// 第二级菜单的标题
    122 
    123                         for (int iii = 0; iii < child_grandson[ii][1].length; iii++) // 第三级菜单
    124                         {
    125                             node.childs.add(child_grandson[ii][1][iii]);
    126                         }
    127                         superNode.childs.add(node);
    128                     }
    129                     superTreeNode.add(superNode);
    130 
    131                 }
    132                 superAdapter.UpdateTreeNode(superTreeNode);
    133                 expandlist.setAdapter(superAdapter);
    134             }
    135 
    136         });
    137     }
    138 }

    运行效果:

    点击两层结构:

         

    点击三层结构:

        

  • 相关阅读:
    (译).NET4.X并行任务Task需要释放吗?
    微软面向高并发应用而推出的新程序库——TPL Dataflow
    C# 5.0 Async函数的提示和技巧
    内存泄露——文章
    AJAX POST请求中参数以form data和request payload形式在php中的获取方式
    NodeJS中间层搭建
    HTML5上传预览
    laravel 图片上传 ajax 方式
    抽奖程序
    IText 生成页脚页码
  • 原文地址:https://www.cnblogs.com/benchao/p/5103707.html
Copyright © 2011-2022 走看看