惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Palo Alto Networks Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
CERT Recently Published Vulnerability Notes
C
Cybersecurity and Infrastructure Security Agency CISA
S
Schneier on Security
S
Securelist
酷 壳 – CoolShell
酷 壳 – CoolShell
C
CXSECURITY Database RSS Feed - CXSecurity.com
Cyberwarzone
Cyberwarzone
Apple Machine Learning Research
Apple Machine Learning Research
S
SegmentFault 最新的问题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
GbyAI
GbyAI
Security Latest
Security Latest
Last Week in AI
Last Week in AI
Microsoft Security Blog
Microsoft Security Blog
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
Webroot Blog
Webroot Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
TaoSecurity Blog
TaoSecurity Blog
C
Cisco Blogs
博客园 - 【当耐特】
Blog — PlanetScale
Blog — PlanetScale
Hugging Face - Blog
Hugging Face - Blog
B
Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Attack and Defense Labs
Attack and Defense Labs
The Last Watchdog
The Last Watchdog
U
Unit 42
阮一峰的网络日志
阮一峰的网络日志
Project Zero
Project Zero
WordPress大学
WordPress大学
L
LINUX DO - 最新话题
F
Fortinet All Blogs
L
LINUX DO - 热门话题
PCI Perspectives
PCI Perspectives
Simon Willison's Weblog
Simon Willison's Weblog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
MongoDB | Blog
MongoDB | Blog
Latest news
Latest news
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
The Hacker News
The Hacker News
爱范儿
爱范儿
O
OpenAI News
J
Java Code Geeks
T
The Exploit Database - CXSecurity.com
H
Hackread – Cybersecurity News, Data Breaches, AI and More

博客园 - 生如夏花之灿烂

本人讲课时录制的Android应用开发技术教学视频 jsoup使用样式class抓取数据时空格的处理 我的第一款anroid软件作品--短信精灵1.0 (原创)Android入门教程(三十六)------实现手机联系人的全选 Android入门教程(三十五)------在Android上使用ZXing识别条形码/二维码(转) Android入门教程(三十三)------之ListView自适应实现表格(转) Android入门教程(三十二)------之SQLite分页表格(转) Android入门教程(三十一)------SQLite分页读取(转) Android入门教程(三十)------之XML解析与生成(转) Android入门教程(二十九)------之BroadcastReceiver (转) Android入门教程(二十八)------之Service(转) Android入门教程(二十七)------之Style与Theme (转) Android入门教程(二十六)------之ActivityGroup + GridView 实现Tab分页标签(转) Android入门教程(二十五)------之画图(转) Android入门教程(二十四)------之Gallery + ImageSwitcher(转) Android入门教程(二十三)------之Gallery(转) Android入门教程(二十二)------之TabHost,TabWidget(转) Android入门教程(二十一)------之PopupWindow (转) Android入门教程(二十)之--之AlertDialog(转)
Android入门教程(三十四)------之多级树形菜单的实现 (转)
生如夏花之灿烂 · 2011-08-11 · via 博客园 - 生如夏花之灿烂

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

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

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

  1. static public class TreeNode{  
  2.     Object parent;  
  3.     List<Object> childs=new ArrayList<Object>();  
  4. }  

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

  1. static public class SuperTreeNode {  
  2.     Object parent;  
  3.       
  4.     List<TreeViewAdapter.TreeNode> childs = new ArrayList<TreeViewAdapter.TreeNode>();  
  5. }  

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

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

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

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

main.xml源码如下:

  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>  

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

  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.       
  16.     ExpandableListView expandableList;  
  17.     TreeViewAdapter adapter;  
  18.     SuperTreeViewAdapter superAdapter;  
  19.     Button btnNormal,btnSuper;  
  20.       
  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. }  

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

  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;  
  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. }  

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

  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.  
  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();  
  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.  
  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.  
  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. }