Android提高十七篇之多级树形菜单的实现

 

本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!

       在Android里要实现树形菜单,都是用ExpandableList(也有高手自己继承ListView或者LinearLayout来做),但是ExpandableList一般只能实现2级树形菜单......本文也依然使用ExpandableList,但是要实现的是3级树形菜单。本文程序运行效果图:

当用BaseExpandableListAdapter来实现二级树形菜单时,父项(getGroupView())和子项(getChildView())都是使用TextView。当要实现三级树形菜单时,子项(getChildView())就必须使用ExpandableList了.......另外还要定义结构体来方便调用三级树形的数据,二级树形菜单可以用如下:

[java] view plain copy print ?
  1. static public class TreeNode{  
  2.     Object parent;  
  3.     List<Object> childs=new ArrayList<Object>();  
  4. }  
static public class TreeNode{ Object parent; List<Object> childs=new ArrayList<Object>(); }

三级树形菜单可以用如下,子项是二级树形菜单的结构体:

[java] view plain copy print ?
  1. static public class SuperTreeNode {  
  2.     Object parent;  
  3.     //二级树形菜单的结构体   
  4.     List<TreeViewAdapter.TreeNode> childs = new ArrayList<TreeViewAdapter.TreeNode>();  
  5. }  
static public class SuperTreeNode { Object parent; //二级树形菜单的结构体 List<TreeViewAdapter.TreeNode> childs = new ArrayList<TreeViewAdapter.TreeNode>(); }

实现三级树形菜单有两点要注意的:

1、第二级也是个树形菜单,因此必须在第二级项目展开/回收时设置足够的空间来完全显示二级树形菜单;

2、在实现三级树形菜单时,发现菜单的方法都是用不了(如OnChildClickListener、OnGroupClickListener等),因此要获得选中的数据就必须在外部定义好回调函数,然后在第二级生成二级树形菜单时回调这个外部函数。

PS:本文在解决No.2关键点的时候,只能取得第三级选中的序号.....而第一,第二级依然无法获取其序号。

main.xml源码如下:

[xhtml] view plain copy print ?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical" android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent">  
  5.     <LinearLayout android:id="@+id/LinearLayout01"  
  6.         android:layout_width="wrap_content" android:layout_height="wrap_content">  
  7.         <Button android:layout_height="wrap_content" android:text="两层结构"  
  8.             android:layout_width="160dip" android:id="@+id/btnNormal"></Button>  
  9.         <Button android:layout_height="wrap_content" android:text="三层结构"  
  10.             android:layout_width="160dip" android:id="@+id/btnSuper"></Button>  
  11.     </LinearLayout>  
  12.     <ExpandableListView android:id="@+id/ExpandableListView01"  
  13.         android:layout_width="fill_parent" android:layout_height="fill_parent"></ExpandableListView>  
  14. </LinearLayout>  
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:id="@+id/LinearLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content"> <Button android:layout_height="wrap_content" android:text="两层结构" android:layout_width="160dip" android:id="@+id/btnNormal"></Button> <Button android:layout_height="wrap_content" android:text="三层结构" android:layout_width="160dip" android:id="@+id/btnSuper"></Button> </LinearLayout> <ExpandableListView android:id="@+id/ExpandableListView01" android:layout_width="fill_parent" android:layout_height="fill_parent"></ExpandableListView> </LinearLayout>

testExpandableList.java是主类,调用其他工具类,源码如下:

[java] view plain copy print ?
  1. package com.testExpandableList;  
  2.   
  3.   
  4. import java.util.List;  
  5. import android.app.Activity;  
  6. import android.os.Bundle;  
  7. import android.util.Log;  
  8. import android.view.View;  
  9. import android.widget.Button;  
  10. import android.widget.ExpandableListView;  
  11. import android.widget.ExpandableListView.OnChildClickListener;  
  12. import android.widget.Toast;  
  13.   
  14. public class testExpandableList extends Activity {  
  15.     /** Called when the activity is first created. */  
  16.     ExpandableListView expandableList;  
  17.     TreeViewAdapter adapter;  
  18.     SuperTreeViewAdapter superAdapter;  
  19.     Button btnNormal,btnSuper;  
  20.     // Sample data set.  children[i] contains the children (String[]) for groups[i].   
  21.     public String[] groups = { "xxxx好友""xxxx同学""xxxxx女人"};  
  22.     public String[][]  child= {  
  23.             { "A君""B君""C君""D君" },  
  24.             { "同学甲""同学乙""同学丙"},  
  25.             { "御姐""萝莉" }  
  26.     };  
  27.       
  28.     public String[] parent = { "xxxx好友""xxxx同学"};  
  29.     public String[][][]  child_grandson= {  
  30.             {{"A君"},  
  31.                 {"AA","AAA"}},  
  32.             {{"B君"},  
  33.                 {"BBB","BBBB","BBBBB"}},  
  34.             {{"C君"},  
  35.                 {"CCC","CCCC"}},  
  36.             {{"D君"},  
  37.                 {"DDD","DDDD","DDDDD"}},  
  38.     };  
  39.       
  40.     @Override  
  41.     public void onCreate(Bundle savedInstanceState) {  
  42.         super.onCreate(savedInstanceState);  
  43.         setContentView(R.layout.main);  
  44.         this.setTitle("ExpandableListView练习----hellogv");  
  45.         btnNormal=(Button)this.findViewById(R.id.btnNormal);  
  46.         btnNormal.setOnClickListener(new ClickEvent());  
  47.         btnSuper=(Button)this.findViewById(R.id.btnSuper);  
  48.         btnSuper.setOnClickListener(new ClickEvent());  
  49.         adapter=new TreeViewAdapter(this,TreeViewAdapter.PaddingLeft>>1);  
  50.         superAdapter=new SuperTreeViewAdapter(this,stvClickEvent);  
  51.         expandableList=(ExpandableListView) testExpandableList.this.findViewById(R.id.ExpandableListView01);  
  52.     }  
  53.       
  54.     class ClickEvent implements View.OnClickListener{  
  55.   
  56.         @Override  
  57.         public void onClick(View v) {  
  58.             adapter.RemoveAll();  
  59.             adapter.notifyDataSetChanged();  
  60.             superAdapter.RemoveAll();  
  61.             superAdapter.notifyDataSetChanged();  
  62.               
  63.             if(v==btnNormal)  
  64.             {  
  65.                 List<TreeViewAdapter.TreeNode> treeNode = adapter.GetTreeNode();  
  66.                 for(int i=0;i<groups.length;i++)  
  67.                 {  
  68.                     TreeViewAdapter.TreeNode node=new TreeViewAdapter.TreeNode();  
  69.                     node.parent=groups[i];  
  70.                     for(int ii=0;ii<child[i].length;ii++)  
  71.                     {  
  72.                         node.childs.add(child[i][ii]);  
  73.                     }  
  74.                     treeNode.add(node);  
  75.                 }  
  76.                   
  77.                 adapter.UpdateTreeNode(treeNode);       
  78.                 expandableList.setAdapter(adapter);  
  79.                 expandableList.setOnChildClickListener(new OnChildClickListener(){  
  80.   
  81.                     @Override  
  82.                     public boolean onChildClick(ExpandableListView arg0, View arg1,  
  83.                             int parent, int children, long arg4) {  
  84.                           
  85.                         String str="parent id:"+String.valueOf(parent)+",children id:"+String.valueOf(children);  
  86.                         Toast.makeText(testExpandableList.this, str, 300).show();  
  87.                         return false;  
  88.                     }  
  89.                 });  
  90.             }  
  91.             else if(v==btnSuper){  
  92.                 List<SuperTreeViewAdapter.SuperTreeNode> superTreeNode = superAdapter.GetTreeNode();  
  93.                 for(int i=0;i<parent.length;i++)//第一层   
  94.                 {  
  95.                     SuperTreeViewAdapter.SuperTreeNode superNode=new SuperTreeViewAdapter.SuperTreeNode();  
  96.                     superNode.parent=parent[i];  
  97.                       
  98.                     //第二层   
  99.                     for(int ii=0;ii<child_grandson.length;ii++)  
  100.                     {  
  101.                         TreeViewAdapter.TreeNode node=new TreeViewAdapter.TreeNode();  
  102.                         node.parent=child_grandson[ii][0][0];//第二级菜单的标题   
  103.                           
  104.                         for(int iii=0;iii<child_grandson[ii][1].length;iii++)//第三级菜单   
  105.                         {  
  106.                             node.childs.add(child_grandson[ii][1][iii]);  
  107.                         }  
  108.                         superNode.childs.add(node);  
  109.                     }  
  110.                     superTreeNode.add(superNode);  
  111.                       
  112.                 }  
  113.                 superAdapter.UpdateTreeNode(superTreeNode);  
  114.                 expandableList.setAdapter(superAdapter);  
  115.             }  
  116.         }  
  117.     }  
  118.   
  119.     /** 
  120.      * 三级树形菜单的事件不再可用,本函数由三级树形菜单的子项(二级菜单)进行回调 
  121.      */  
  122.     OnChildClickListener stvClickEvent=new OnChildClickListener(){  
  123.   
  124.         @Override  
  125.         public boolean onChildClick(ExpandableListView parent,  
  126.                 View v, int groupPosition, int childPosition,  
  127.                 long id) {  
  128.             String str="parent id:"+String.valueOf(groupPosition)+",children id:"+String.valueOf(childPosition);  
  129.             Toast.makeText(testExpandableList.this, str, 300).show();  
  130.               
  131.             return false;  
  132.         }  
  133.           
  134.     };  
  135. }  
package com.testExpandableList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ExpandableListView; import android.widget.ExpandableListView.OnChildClickListener; import android.widget.Toast; public class testExpandableList extends Activity { /** Called when the activity is first created. */ ExpandableListView expandableList; TreeViewAdapter adapter; SuperTreeViewAdapter superAdapter; Button btnNormal,btnSuper; // Sample data set. children[i] contains the children (String[]) for groups[i]. public String[] groups = { "xxxx好友", "xxxx同学", "xxxxx女人"}; public String[][] child= { { "A君", "B君", "C君", "D君" }, { "同学甲", "同学乙", "同学丙"}, { "御姐", "萝莉" } }; public String[] parent = { "xxxx好友", "xxxx同学"}; public String[][][] child_grandson= { {{"A君"}, {"AA","AAA"}}, {{"B君"}, {"BBB","BBBB","BBBBB"}}, {{"C君"}, {"CCC","CCCC"}}, {{"D君"}, {"DDD","DDDD","DDDDD"}}, }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.setTitle("ExpandableListView练习----hellogv"); btnNormal=(Button)this.findViewById(R.id.btnNormal); btnNormal.setOnClickListener(new ClickEvent()); btnSuper=(Button)this.findViewById(R.id.btnSuper); btnSuper.setOnClickListener(new ClickEvent()); adapter=new TreeViewAdapter(this,TreeViewAdapter.PaddingLeft>>1); superAdapter=new SuperTreeViewAdapter(this,stvClickEvent); expandableList=(ExpandableListView) testExpandableList.this.findViewById(R.id.ExpandableListView01); } class ClickEvent implements View.OnClickListener{ @Override public void onClick(View v) { adapter.RemoveAll(); adapter.notifyDataSetChanged(); superAdapter.RemoveAll(); superAdapter.notifyDataSetChanged(); if(v==btnNormal) { List<TreeViewAdapter.TreeNode> treeNode = adapter.GetTreeNode(); for(int i=0;i<groups.length;i++) { TreeViewAdapter.TreeNode node=new TreeViewAdapter.TreeNode(); node.parent=groups[i]; for(int ii=0;ii<child[i].length;ii++) { node.childs.add(child[i][ii]); } treeNode.add(node); } adapter.UpdateTreeNode(treeNode); expandableList.setAdapter(adapter); expandableList.setOnChildClickListener(new OnChildClickListener(){ @Override public boolean onChildClick(ExpandableListView arg0, View arg1, int parent, int children, long arg4) { String str="parent id:"+String.valueOf(parent)+",children id:"+String.valueOf(children); Toast.makeText(testExpandableList.this, str, 300).show(); return false; } }); } else if(v==btnSuper){ List<SuperTreeViewAdapter.SuperTreeNode> superTreeNode = superAdapter.GetTreeNode(); for(int i=0;i<parent.length;i++)//第一层 { SuperTreeViewAdapter.SuperTreeNode superNode=new SuperTreeViewAdapter.SuperTreeNode(); superNode.parent=parent[i]; //第二层 for(int ii=0;ii<child_grandson.length;ii++) { TreeViewAdapter.TreeNode node=new TreeViewAdapter.TreeNode(); node.parent=child_grandson[ii][0][0];//第二级菜单的标题 for(int iii=0;iii<child_grandson[ii][1].length;iii++)//第三级菜单 { node.childs.add(child_grandson[ii][1][iii]); } superNode.childs.add(node); } superTreeNode.add(superNode); } superAdapter.UpdateTreeNode(superTreeNode); expandableList.setAdapter(superAdapter); } } } /** * 三级树形菜单的事件不再可用,本函数由三级树形菜单的子项(二级菜单)进行回调 */ OnChildClickListener stvClickEvent=new OnChildClickListener(){ @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { String str="parent id:"+String.valueOf(groupPosition)+",children id:"+String.valueOf(childPosition); Toast.makeText(testExpandableList.this, str, 300).show(); return false; } }; }

TreeViewAdapter.java是实现二级树形菜单的工具类,源码如下:

[java] view plain copy print ?
  1. package com.testExpandableList;  
  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.   
  15. public class TreeViewAdapter extends BaseExpandableListAdapter{  
  16.     public static final int ItemHeight=48;//每项的高度   
  17.     public static final int PaddingLeft=36;//每项的高度   
  18.     private int myPaddingLeft=0;//如果是由SuperTreeView调用,则作为子项需要往右移   
  19.   
  20.     static public class TreeNode{  
  21.         Object parent;  
  22.         List<Object> childs=new ArrayList<Object>();  
  23.     }  
  24.       
  25.     List<TreeNode> treeNodes = new ArrayList<TreeNode>();  
  26.     Context parentContext;  
  27.       
  28.     public TreeViewAdapter(Context view,int myPaddingLeft)  
  29.     {  
  30.         parentContext=view;  
  31.         this.myPaddingLeft=myPaddingLeft;  
  32.     }  
  33.       
  34.     public List<TreeNode> GetTreeNode()  
  35.     {  
  36.         return treeNodes;  
  37.     }  
  38.       
  39.     public void UpdateTreeNode(List<TreeNode> nodes)  
  40.     {  
  41.         treeNodes=nodes;  
  42.     }  
  43.       
  44.     public void RemoveAll()  
  45.     {  
  46.         treeNodes.clear();  
  47.     }  
  48.       
  49.     public Object getChild(int groupPosition, int childPosition) {  
  50.         return treeNodes.get(groupPosition).childs.get(childPosition);  
  51.     }  
  52.   
  53.     public int getChildrenCount(int groupPosition) {  
  54.         return treeNodes.get(groupPosition).childs.size();  
  55.     }  
  56.   
  57.     static public TextView getTextView(Context context) {  
  58.         AbsListView.LayoutParams lp = new AbsListView.LayoutParams(  
  59.                 ViewGroup.LayoutParams.FILL_PARENT, ItemHeight);  
  60.   
  61.         TextView textView = new TextView(context);  
  62.         textView.setLayoutParams(lp);  
  63.         textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);  
  64.         return textView;  
  65.     }  
  66.   
  67.     public View getChildView(int groupPosition, int childPosition,  
  68.             boolean isLastChild, View convertView, ViewGroup parent) {  
  69.         TextView textView = getTextView(this.parentContext);  
  70.         textView.setText(getChild(groupPosition, childPosition).toString());  
  71.         textView.setPadding(myPaddingLeft+PaddingLeft, 000);  
  72.         return textView;  
  73.     }  
  74.   
  75.     public View getGroupView(int groupPosition, boolean isExpanded,  
  76.             View convertView, ViewGroup parent) {  
  77.         TextView textView = getTextView(this.parentContext);  
  78.         textView.setText(getGroup(groupPosition).toString());  
  79.         textView.setPadding(myPaddingLeft+(PaddingLeft>>1), 000);  
  80.         return textView;  
  81.     }  
  82.   
  83.     public long getChildId(int groupPosition, int childPosition) {  
  84.         return childPosition;  
  85.     }  
  86.   
  87.     public Object getGroup(int groupPosition) {  
  88.         return treeNodes.get(groupPosition).parent;  
  89.     }  
  90.   
  91.     public int getGroupCount() {  
  92.         return treeNodes.size();  
  93.     }  
  94.   
  95.     public long getGroupId(int groupPosition) {  
  96.         return groupPosition;  
  97.     }  
  98.   
  99.     public boolean isChildSelectable(int groupPosition, int childPosition) {  
  100.         return true;  
  101.     }  
  102.   
  103.     public boolean hasStableIds() {  
  104.         return true;  
  105.     }  
  106. }  
package com.testExpandableList; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.BaseExpandableListAdapter; import android.widget.TextView; public class TreeViewAdapter extends BaseExpandableListAdapter{ public static final int ItemHeight=48;//每项的高度 public static final int PaddingLeft=36;//每项的高度 private int myPaddingLeft=0;//如果是由SuperTreeView调用,则作为子项需要往右移 static public class TreeNode{ Object parent; List<Object> childs=new ArrayList<Object>(); } List<TreeNode> treeNodes = new ArrayList<TreeNode>(); Context parentContext; public TreeViewAdapter(Context view,int myPaddingLeft) { parentContext=view; this.myPaddingLeft=myPaddingLeft; } public List<TreeNode> GetTreeNode() { return treeNodes; } public void UpdateTreeNode(List<TreeNode> nodes) { treeNodes=nodes; } public void RemoveAll() { treeNodes.clear(); } public Object getChild(int groupPosition, int childPosition) { return treeNodes.get(groupPosition).childs.get(childPosition); } public int getChildrenCount(int groupPosition) { return treeNodes.get(groupPosition).childs.size(); } static public TextView getTextView(Context context) { AbsListView.LayoutParams lp = new AbsListView.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ItemHeight); TextView textView = new TextView(context); textView.setLayoutParams(lp); textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); return textView; } public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { TextView textView = getTextView(this.parentContext); textView.setText(getChild(groupPosition, childPosition).toString()); textView.setPadding(myPaddingLeft+PaddingLeft, 0, 0, 0); return textView; } public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { TextView textView = getTextView(this.parentContext); textView.setText(getGroup(groupPosition).toString()); textView.setPadding(myPaddingLeft+(PaddingLeft>>1), 0, 0, 0); return textView; } public long getChildId(int groupPosition, int childPosition) { return childPosition; } public Object getGroup(int groupPosition) { return treeNodes.get(groupPosition).parent; } public int getGroupCount() { return treeNodes.size(); } public long getGroupId(int groupPosition) { return groupPosition; } public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } public boolean hasStableIds() { return true; } }

SuperTreeViewAdapter.java是实现三级树形菜单的工具类,会用到TreeViewAdapter.java,源码如下:

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

总结,使用ExpandableList实现三级树形菜单时有些bug不好解决,而且定义三维数组的时候也要倍加小心......所以尽量把数据化简来使用二级树形菜单。

查看评论
51楼 my_yunjj 2012-02-06 18:06发表 [回复] [引用] [举报]
好厉害!太感谢了
50楼 linder0209 2012-01-19 15:04发表 [回复] [引用] [举报]
好好学习一下,希望在这基础上能实现tree(多级树)
Re: hellogv 2012-01-20 09:24发表 [回复] [引用] [举报]
回复linder0209:多级树要做成很精简的树枝+递归
49楼 yuhx_it 2011-11-18 17:09发表 [回复] [引用] [举报]
三级菜单不显示
48楼 zn9179 2011-10-15 21:38发表 [回复] [引用] [举报]
正好要用到 谢谢分享
47楼 li277680701 2011-09-02 08:30发表 [回复] [引用] [举报]
真是谢谢了。。。。
46楼 maddercat 2011-08-10 16:47发表 [回复] [引用] [举报]
你好,你的实现有些问题,在三层里边,当第一组xxx好友有显示到第三级AA和AAA时,如果点击第二组名xxxx同学,
无论是expand还是collapse,都会使第一组的AA和AAA隐藏起来,不知道这是什么原因造成的,可以帮忙看一下吗?
因为现在开发需要你的这个实现,多谢:)
45楼 CoN_see 2011-07-19 12:32发表 [回复] [引用] [举报]
很好,很强大。。
44楼 ruilina 2011-07-01 11:00发表 [回复] [引用] [举报]
43楼 laker55555 2011-06-27 10:50发表 [回复] [引用] [举报]
布局上的问题挺大的
42楼 meng_qing_shan 2011-06-21 15:54发表 [回复] [引用] [举报]
太好 了 正在苦苦寻找
41楼 j619323539 2011-06-20 17:36发表 [回复] [引用] [举报]
综合起来不适合开发项目
40楼 j619323539 2011-06-20 17:35发表 [回复] [引用] [举报]
把xxxx女人打开的时候怎么设置背景图片啊
39楼 j619323539 2011-06-20 17:34发表 [回复] [引用] [举报]
把xxxx女人打开的时候怎么设置背景图片
38楼 j619323539 2011-06-20 17:30发表 [回复] [引用] [举报]
福鼎市
37楼 hncjlxf 2011-06-13 11:20发表 [回复] [引用] [举报]
很给力 很强大
36楼 bluesky_07_06_1 2011-06-08 11:04发表 [回复] [引用] [举报]
demo 不错,商用价值不高。
35楼 weck0736 2011-06-05 10:44发表 [回复] [引用] [举报]
正要用,楼主太帅了。
34楼 chenjun864 2011-04-23 10:30发表 [回复] [引用] [举报]
33楼 thischou 2011-03-31 11:00发表 [回复] [引用] [举报]
砖家
32楼 qilovehua 2011-03-31 10:39发表 [回复] [引用] [举报]
31楼 CAIYUNFREEDOM 2011-03-28 18:47发表 [回复] [引用] [举报]
30楼 jjxoyzy 2011-03-24 16:23发表 [回复] [引用] [举报]
顶顶!!!
29楼 a222123 2011-03-14 15:44发表 [回复] [引用] [举报]
学习中...
28楼 caorui201314 2011-03-02 18:10发表 [回复] [引用] [举报]
27楼 zhouderek 2011-01-13 18:43发表 [回复] [引用] [举报]
观摩》。。。
26楼 right3 2011-01-12 16:35发表 [回复] [引用] [举报]
太牛了
25楼 chensylsl 2011-01-12 14:02发表 [回复] [引用] [举报]
这个不错
24楼 oldcarnation 2011-01-11 22:50发表 [回复] [引用] [举报]
23楼 phxuecan 2011-01-11 13:17发表 [回复] [引用] [举报]
22楼 hebiaccpguo 2011-01-11 09:14发表 [回复] [引用] [举报]
21楼 chjttony 2011-01-10 16:52发表 [回复] [引用] [举报]
收藏学习!
20楼 lw2078 2011-01-10 10:21发表 [回复] [引用] [举报]
高手见解,膜拜学习~~
19楼 qizi329 2011-01-10 10:07发表 [回复] [引用] [举报]
写的相当的不错,学习中...
18楼 thinkingtoday 2011-01-10 09:26发表 [回复] [引用] [举报]
兄弟,我觉得你的实现有瑕疵,希望你可以参考一下这里:http://isomobile.com/read.php?tid-49.html 的实现
Re: lmldownloading 2011-11-14 18:10发表 [回复] [引用] [举报]
回复thinkingtoday:
It's this,

http://www.isomobile.com/read.php?tid-49.html

你可能感兴趣的:(android,String,object,layout,Class,button)