在 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;??
- ????}??
- ??
頂
踩
- 2011-01-11 08:53
- 瀏覽 1435
- 評(píng)論(0)
- 分類: 移動(dòng)開(kāi)發(fā)
- 相關(guān)推薦
發(fā)表評(píng)論
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

評(píng)論