生活随笔
收集整理的這篇文章主要介紹了
Android 多级树形菜单
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在Android里要實(shí)現(xiàn)樹(shù)形菜單,都是用ExpandableList(也有高手自己繼承ListView或者LinearLayout來(lái)做),但是ExpandableList一般只能實(shí)現(xiàn)2級(jí)樹(shù)形菜單......本文也依然使用ExpandableList,但是要實(shí)現(xiàn)的是3級(jí)樹(shù)形菜單。本文程序運(yùn)行效果圖:
當(dāng)用BaseExpandableListAdapter來(lái)實(shí)現(xiàn)二級(jí)樹(shù)形菜單時(shí),父項(xiàng)(getGroupView())和子項(xiàng)(getChildView())都是使用TextView。當(dāng)要實(shí)現(xiàn)三級(jí)樹(shù)形菜單時(shí),子項(xiàng)(getChildView())就必須使用ExpandableList了.......另外還要定義結(jié)構(gòu)體來(lái)方便調(diào)用三級(jí)樹(shù)形的數(shù)據(jù),二級(jí)樹(shù)形菜單可以用如下:
?
static?public?class?TreeNode{??????Object?parent;??????List<Object>?childs=new?ArrayList<Object>();??}?? ?
三級(jí)樹(shù)形菜單可以用如下,子項(xiàng)是二級(jí)樹(shù)形菜單的結(jié)構(gòu)體:
?
static?public?class?SuperTreeNode?{??????Object?parent;??????//二級(jí)樹(shù)形菜單的結(jié)構(gòu)體??????List<TreeViewAdapter.TreeNode>?childs?=?new?ArrayList<TreeViewAdapter.TreeNode>();??}?? ?
實(shí)現(xiàn)三級(jí)樹(shù)形菜單有兩點(diǎn)要注意的:
1、第二級(jí)也是個(gè)樹(shù)形菜單,因此必須在第二級(jí)項(xiàng)目展開(kāi)/回收時(shí)設(shè)置足夠的空間來(lái)完全顯示二級(jí)樹(shù)形菜單;
2、在實(shí)現(xiàn)三級(jí)樹(shù)形菜單時(shí),發(fā)現(xiàn)菜單的方法都是用不了(如OnChildClickListener、OnGroupClickListener等),因此要獲得選中的數(shù)據(jù)就必須在外部定義好回調(diào)函數(shù),然后在第二級(jí)生成二級(jí)樹(shù)形菜單時(shí)回調(diào)這個(gè)外部函數(shù)。
PS:本文在解決No.2關(guān)鍵點(diǎn)的時(shí)候,只能取得第三級(jí)選中的序號(hào).....而第一,第二級(jí)依然無(wú)法獲取其序號(hào)。
main.xml源碼如下:
?
<?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="兩層結(jié)構(gòu)"??????????????android:layout_width="160dip"?android:id="@+id/btnNormal"></Button>??????????<Button?android:layout_height="wrap_content"?android:text="三層結(jié)構(gòu)"??????????????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是主類,調(diào)用其他工具類,源碼如下:
?
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同學(xué)",?"xxxxx女人"};??????public?String[][]??child=?{??????????????{?"A君",?"B君",?"C君",?"D君"?},??????????????{?"同學(xué)甲",?"同學(xué)乙",?"同學(xué)丙"},??????????????{?"御姐",?"蘿莉"?}??????};????????????public?String[]?parent?=?{?"xxxx好友",?"xxxx同學(xué)"};??????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練習(xí)----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];//第二級(jí)菜單的標(biāo)題????????????????????????????????????????????????????for(int?iii=0;iii<child_grandson[ii][1].length;iii++)//第三級(jí)菜單??????????????????????????{??????????????????????????????node.childs.add(child_grandson[ii][1][iii]);??????????????????????????}??????????????????????????superNode.childs.add(node);??????????????????????}??????????????????????superTreeNode.add(superNode);????????????????????????????????????????}??????????????????superAdapter.UpdateTreeNode(superTreeNode);??????????????????expandableList.setAdapter(superAdapter);??????????????}??????????}??????}????????/**??????*?三級(jí)樹(shù)形菜單的事件不再可用,本函數(shù)由三級(jí)樹(shù)形菜單的子項(xiàng)(二級(jí)菜單)進(jìn)行回調(diào)??????*/??????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是實(shí)現(xiàn)二級(jí)樹(shù)形菜單的工具類,源碼如下:
?
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;//每項(xiàng)的高度??????public?static?final?int?PaddingLeft=36;//每項(xiàng)的高度??????private?int?myPaddingLeft=0;//如果是由SuperTreeView調(diào)用,則作為子項(xiàng)需要往右移????????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是實(shí)現(xiàn)三級(jí)樹(shù)形菜單的工具類,會(huì)用到TreeViewAdapter.java,源碼如下:
?
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;??????????//二級(jí)樹(shù)形菜單的結(jié)構(gòu)體??????????List<TreeViewAdapter.TreeNode>?childs?=?new?ArrayList<TreeViewAdapter.TreeNode>();??????}????????private?List<SuperTreeNode>?superTreeNodes?=?new?ArrayList<SuperTreeNode>();??????private?Context?parentContext;??????private?OnChildClickListener?stvClickEvent;//外部回調(diào)函數(shù)????????????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;??????}????????/**??????*?三層樹(shù)結(jié)構(gòu)中的第二層是一個(gè)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();//臨時(shí)變量取得TreeViewAdapter的TreeNode集合,可為空??????????final?TreeNode?treeNode=(TreeNode)?getChild(groupPosition,?childPosition);??????????tmp.add(treeNode);??????????treeViewAdapter.UpdateTreeNode(tmp);??????????treeView.setAdapter(treeViewAdapter);????????????????????//關(guān)鍵點(diǎn):取得選中的二級(jí)樹(shù)形菜單的父子節(jié)點(diǎn),結(jié)果返回給外部回調(diào)函數(shù)??????????treeView.setOnChildClickListener(this.stvClickEvent);????????????????????/**??????????*?關(guān)鍵點(diǎn):第二級(jí)菜單展開(kāi)時(shí)通過(guò)取得節(jié)點(diǎn)數(shù)來(lái)設(shè)置第三級(jí)菜單的大小??????????*/??????????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);??????????????}??????????});????????????????????/**??????????*?第二級(jí)菜單回收時(shí)設(shè)置為標(biāo)準(zhǔn)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;??????}????????/**??????*?三級(jí)樹(shù)結(jié)構(gòu)中的首層是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;??????}??}?? ?
總結(jié),使用ExpandableList實(shí)現(xiàn)三級(jí)樹(shù)形菜單時(shí)有些bug不好解決,而且定義三維數(shù)組的時(shí)候也要倍加小心......所以盡量把數(shù)據(jù)化簡(jiǎn)來(lái)使用二級(jí)樹(shù)形菜單。
總結(jié)
以上是生活随笔為你收集整理的Android 多级树形菜单的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。