Android 의 다단 계 트 리 메뉴 구현 방법

16206 단어 Android메뉴
일반적으로 안 드 로 이 드 에 서 는 트 리 메뉴 를 구현 하려 면 Expandablerest(ListView 나 LinearLayout 를 계승 하 는 고수 도 있다)를 사용 하지만 Expandablerest 는 보통 2 급 트 리 메뉴 만 구현 할 수 있다.본 논문 에서 말 한 인 스 턴 스 도 Expandablerest 를 사용 하지만 3 급 트 리 메뉴 를 실현 해 야 합 니 다.
본 프로그램의 실행 효과 도 는 다음 그림 과 같다.

BaseExpandableListAdapter 로 2 급 트 리 메뉴 를 구현 할 때 부모 항목(getGroupView()과 하위 항목(getChildView()은 모두 TextView 를 사용 합 니 다.3 급 트 리 메뉴 를 구현 하려 면 하위 항목(getChildView()은 Expandableest 를 사용 해 야 합 니 다.또한 3 급 트 리 의 데 이 터 를 쉽게 호출 할 수 있 도록 구조 체 를 정의 해 야 합 니 다.2 급 트 리 메뉴 는 다음 과 같 습 니 다.

static public class TreeNode{
 Object parent;
 List<Object> childs=new ArrayList<Object>();
}

3 급 트 리 메뉴 는 다음 과 같이 사용 할 수 있 습 니 다.하위 항목 은 2 급 트 리 메뉴 의 구조 체 는 다음 과 같 습 니 다.

static public class SuperTreeNode {
 Object parent;
 //          
 List<TreeViewAdapter.TreeNode> childs = new ArrayList<TreeViewAdapter.TreeNode>();
}

3 급 트 리 메뉴 를 실현 하려 면 두 가지 주의해 야 할 것 이 있 습 니 다.
1.2 급 도 트 리 메뉴 이기 때문에 2 급 항목 을 펼 치 거나 회수 할 때 충분 한 공간 을 설정 하여 2 급 트 리 메뉴 를 완전히 표시 해 야 합 니 다.
2.3 급 트 리 메뉴 를 구현 할 때 메뉴 를 발견 하 는 방법 은 모두 사용 할 수 없습니다(예 를 들 어 OnChildClickListener,OnGroupClickListener 등).따라서 선택 한 데 이 터 를 얻 으 려 면 외부 에서 리 셋 함 수 를 정의 한 다음 에 2 급 트 리 메뉴 를 생 성 할 때 이 외부 함 수 를 리 셋 해 야 합 니 다.
또한 본 고 는 No.2 의 관건 을 해결 할 때 3 급 선택의 번호 만 얻 을 수 있다 는 점 에 주의해 야 한다.첫째,두 번 째 단 계 는 그 번 호 를 얻 을 수 없다.
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="    "
  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 는 주 클래스 입 니 다.다른 도구 클래스 를 호출 합 니 다.원본 코드 는 다음 과 같 습 니 다.

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 는 2 급 트 리 메뉴 를 실현 하 는 도구 클래스 입 니 다.원본 코드 는 다음 과 같 습 니 다.

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 는 3 급 트 리 메뉴 를 실현 하 는 도구 클래스 로 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;
 //          
 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;
 }
}

결론 적 으로 Expandablerest 를 사용 하여 3 급 트 리 메뉴 를 실현 할 때 bug 가 해결 되 지 않 고 3 차원 배열 을 정의 할 때 도 더욱 조심해 야 합 니 다!그래서 가능 한 한 데 이 터 를 간략하게 해서 2 급 트 리 메뉴 를 사용 하 세 요.
본 논문 에서 말 한 코드 가 여러분 에 게 안 드 로 이 드 프로 그래 밍 을 하 는 데 어느 정도 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기