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 }
运行效果:
点击两层结构:
点击三层结构:
时间: 2024-11-02 23:32:36