天天看點

安卓 ExpandableListView的使用詳解

在Android開發中,我們知道經常會用到ListView來加載一些清單資料,但有時候ListView并不能完全十分滿足我們的需求。比如如下圖的效果用 ExpandableListView實作起來就更友善點,我們直接用ExpandableListView,設定Group不能點選即可。好,費話不多說。下面詳細介紹 ExpandableListView的使用。

安卓 ExpandableListView的使用詳解

          圖(一) ExpandableListView主要由組與子元素組成。是以我們要分别對組元素以及子元素進行配置及操作。由于ExpandableListView與ListView類似,是以ExpandableListView必不可少的配置過程是必不可少的。首先在XML檔案裡配置ExpandableListView。 main.xml配置如下: [html]  view plain  copy  print ?

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     tools:context=".MainActivity" >  
  6.     <ExpandableListView   
  7.         android:id="@+id/list"  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="fill_parent"  
  10.         android:background="#ffffff"  
  11.         android:cacheColorHint="#00000000"  
  12.         android:listSelector="#00000000"  
  13.         >  
  14.     </ExpandableListView>   
  15. </RelativeLayout>  

group.xml配置如下: [html]  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:layout_width="match_parent"  
  4.     android:layout_height="wrap_content"  
  5.     android:gravity="center"  
  6.     android:orientation="vertical" >  
  7.     <TextView  
  8.         android:id="@+id/group_text"  
  9.          android:layout_width="match_parent"  
  10.          android:layout_height="wrap_content"  
  11.          android:paddingTop="10dip"  
  12.          android:paddingBottom="10dip"  
  13.          android:gravity="center_horizontal"  
  14.          android:text="122"  
  15.         />  
  16. </LinearLayout>  

child.xml配置如下: [html]  view plain  copy  print ?

  1. <pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="horizontal" >  
  6.     <ImageView  
  7.         android:id="@+id/image"  
  8.          android:layout_width="60dip"  
  9.          android:layout_height="60dip"  
  10.          android:src="@drawable/ic_launcher"  
  11.         />  
  12.    <LinearLayout   
  13.         android:layout_width="match_parent"  
  14.         android:layout_height="wrap_content"  
  15.         android:orientation="vertical"  
  16.        >  
  17.        <TextView  
  18.            android:id="@+id/textOne"  
  19.             android:layout_width="match_parent"  
  20.             android:layout_height="match_parent"  
  21.             android:text="1"  
  22.            />  
  23.          <TextView  
  24.               android:id="@+id/textTwo"  
  25.             android:layout_width="match_parent"  
  26.             android:layout_height="match_parent"  
  27.             android:text="2"  
  28.            />  
  29.            <TextView  
  30.                 android:id="@+id/textThree"  
  31.             android:layout_width="match_parent"  
  32.             android:layout_height="match_parent"  
  33.             android:text="3"  
  34.            />  
  35.    </LinearLayout>  
  36. </LinearLayout>  

前面介紹過 ExpandableListView與ListView類似,是以ListView   Adapter中存在的方法, ExpandableListView  Adapter必定存在,隻是Group和Child分别重寫了 ListView   Adapter中的方法,同時新增加了兩個方法,分别是hasStableIds() 和isChildSelectable(int groupPosition, int childPosition),是以 , ExpandableListView  Adapter中總共重寫了10個方法。 其中要注意 hasStableIds() 和isChildSelectable(int groupPosition, int childPosition)這兩個方法。hasStableIds() 主要是用來判斷ExpandableListView内容id是否有效的(傳回true or false),系統會跟據id來确定目前顯示哪條内容,也就是firstVisibleChild的位置。而 isChildSelectable(int groupPosition, int childPosition)用來判斷某Group某個child是否可可選。我們可以添加條件控制某Group某個child可點或不可點選。當不加任何條件直接傳回false,所有的組的child均不可點選。 經過對ExpandableListView Adapter簡單的說明,下面我們來看下TestExpandableListViewDemo源碼。 其MainActiivty.java如下所示: [java]  view plain  copy  print ?

  1. <pre name="code" class="java">package com.example.testexpandlistview;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. import android.app.Activity;  
  5. import android.os.Bundle;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.view.ViewGroup;  
  10. import android.widget.BaseExpandableListAdapter;  
  11. import android.widget.ExpandableListView;  
  12. import android.widget.ExpandableListView.OnChildClickListener;  
  13. import android.widget.ExpandableListView.OnGroupClickListener;  
  14. import android.widget.ExpandableListView.OnGroupCollapseListener;  
  15. import android.widget.ExpandableListView.OnGroupExpandListener;  
  16. import android.widget.ImageView;  
  17. import android.widget.TextView;  
  18. import android.widget.Toast;  
  19. public class MainActivity extends Activity {  
  20.   private ExpandableListView mListView;  
  21.   private List<StrBean> group_list;  
  22.   private List<memBean> child_list;  
  23.   private StrBean strbean;  
  24.   private memBean membean;  
  25.   private LayoutInflater mInflater;  
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.activity_main);  
  30.         initView();  
  31.     }  
  32.     private void initView(){  
  33.         mListView = (ExpandableListView) findViewById(R.id.list);  
  34.         mInflater = LayoutInflater.from(MainActivity.this);  
  35.         group_list = new ArrayList<StrBean>();  
  36.         for(int i=0;i<5;i++){  
  37.             strbean =new StrBean();  
  38.             strbean.spacename = "深圳航港"+i;  
  39.             strbean.childsize = 8;  
  40.             child_list = new ArrayList<memBean>();  
  41.             for(int j=0;j<8;j++){  
  42.                 membean = new memBean();  
  43.                 membean.price=1+j+"萬";  
  44.                 membean.secondPrice="1.6萬";  
  45.                 membean.flag = i;  
  46.                 membean.title = "商務卡";  
  47.                 child_list.add(membean);  
  48.             }  
  49.             strbean.setList(child_list);   
  50.             group_list.add(strbean);  
  51.         }  
  52.         Adapter adapter = new Adapter();  
  53.         mListView.setGroupIndicator(null);  
  54.         mListView.setOnGroupClickListener(new OnGroupClickListener() {  
  55.             @Override  
  56.             public boolean onGroupClick(ExpandableListView parent, View v,  
  57.                     int groupPosition, long id) {  
  58.                 Toast.makeText(MainActivity.this, "第"+groupPosition+"組被點選了", 0).show();  
  59.                 return true;  
  60.             }  
  61.         });  
  62.         mListView.setOnGroupExpandListener(new OnGroupExpandListener() {  
  63.             @Override  
  64.             public void onGroupExpand(int groupPosition) {  
  65.                 Toast.makeText(MainActivity.this, "第"+groupPosition+"組展開", 0).show();  
  66.             }  
  67.         });  
  68.         mListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {  
  69.             @Override  
  70.             public void onGroupCollapse(int groupPosition) {  
  71.                 Toast.makeText(MainActivity.this, "第"+groupPosition+"組合攏", 0).show();  
  72.             }  
  73.         });  
  74.         mListView.setOnChildClickListener(new OnChildClickListener() {  
  75.             @Override  
  76.             public boolean onChildClick(ExpandableListView parent, View v,  
  77.                     int groupPosition, int childPosition, long id) {  
  78.                 Toast.makeText(MainActivity.this, "第"+groupPosition+"組的第"+childPosition+"被點選了", 0).show();  
  79.                 return true;  
  80.             }  
  81.         });  
  82.         mListView.setAdapter(adapter);  

[java]  view plain  copy  print ?

  1.                 //設定Group預設展開  
  2.      int groupCount = mListView.getCount();  
  3.      for(int i=0;i<groupCount;i++){  
  4.          mListView.expandGroup(i);  
  5.      }  
  6. }  
  7. //自定義擴充卡  
  8. class Adapter extends BaseExpandableListAdapter{  
  9.        //擷取子元素對象  
  10.     @Override  
  11.     public Object getChild(int groupPosition, int childPosition) {  
  12.         return null;  
  13.     }  
  14.        //擷取子元素Id  
  15.     @Override  
  16.     public long getChildId(int groupPosition, int childPosition) {  
  17.         return childPosition;  
  18.     }  
  19.        //加載子元素并顯示  
  20.     @Override  
  21.     public View getChildView(final int groupPosition, final int childPosition,  
  22.             boolean isLastChild, View convertView, ViewGroup parent) {  
  23.         View view=null;  
  24.         ChildHolder childholder = null;  
  25.         if(convertView!=null){  
  26.             view = convertView;  
  27.             childholder = (ChildHolder) view.getTag();  
  28.         }else{  
  29.             view = View.inflate(MainActivity.this,R.layout.item, null);  
  30.             childholder = new ChildHolder();  
  31.             childholder.mImage = (ImageView) view.findViewById(R.id.image);  
  32.             childholder.mPrice = (TextView) view.findViewById(R.id.textTwo);  
  33.             childholder.mStateText = (TextView) view.findViewById(R.id.textOne);  
  34.             childholder.mSecondPrice = (TextView) view.findViewById(R.id.textThree);  
  35.             view.setTag(childholder);  
  36.         }  
  37.         childholder.mImage.setOnClickListener(new OnClickListener() {  
  38.             @Override  
  39.             public void onClick(View v) {  
  40.                 Toast.makeText(MainActivity.this, "第"+groupPosition+"組的第"+childPosition+"圖標被點選了", 0).show();  
  41.             }  
  42.         });  
  43.         childholder.mPrice.setText(group_list.get(groupPosition)  
  44.                 .getList().get(childPosition).price);  
  45.         int len = group_list.get(groupPosition)  
  46.                 .getList().size();  
  47.         System.out.println(len+"-----------------");  
  48.         childholder.mStateText.setText(group_list.get(groupPosition)  
  49.                 .getList().get(childPosition).title);  
  50.         childholder.mSecondPrice.setText(group_list.get(groupPosition)  
  51.                 .getList().get(childPosition).secondPrice);  
  52.         return view;  
  53.     }  
  54.        //擷取子元素數目  
  55.     @Override  
  56.     public int getChildrenCount(int groupPosition) {  
  57.         return group_list.get(groupPosition).childsize;  
  58.     }  
  59.     //擷取組元素對象  
  60.     @Override  
  61.     public Object getGroup(int groupPosition) {  
  62.         return group_list.get(groupPosition);  
  63.     }  
  64.        //擷取組元素數目  
  65.     @Override  
  66.     public int getGroupCount() {  
  67.         return group_list.size();  
  68.     }  
  69.     //擷取組元素Id  
  70.     @Override  
  71.     public long getGroupId(int groupPosition) {  
  72.         return groupPosition;  
  73.     }  
  74.        //加載并顯示組元素  
  75.     @Override  
  76.     public View getGroupView(int groupPosition, boolean isExpanded,  
  77.             View convertView, ViewGroup parent) {  
  78.         View view=null;  
  79.         GroupHolder groupholder = null;  
  80.         if(convertView!=null){  
  81.             view = convertView;  
  82.             groupholder = (GroupHolder) view.getTag();  
  83.         }else{  
  84.             view = View.inflate(MainActivity.this,R.layout.textview, null);  
  85.             groupholder =new GroupHolder();  
  86.             groupholder.mSpaceText = (TextView) view.findViewById(R.id.group_text);  
  87.             view.setTag(groupholder);  
  88.         }  
  89.         groupholder.mSpaceText.setText(group_list.get(groupPosition).spacename);  
  90.         return view;  
  91.     }  
  92.     @Override  
  93.     public boolean hasStableIds() {  
  94.         return true;  
  95.     }  
  96.     @Override  
  97.     public boolean isChildSelectable(int groupPosition, int childPosition) {  
  98.         return false;  
  99.     }  
  100. }  
  101. static class GroupHolder{  
  102.     TextView mSpaceText;  
  103. }  
  104. static class ChildHolder{  
  105.     ImageView mImage;  
  106.     TextView mStateText;  
  107.     TextView mPrice;  
  108.     TextView mSecondPrice;  
  109. }  
安卓 ExpandableListView的使用詳解

               效果圖

在上面的源碼中,總結說來ExpandableListView主要有setOnGroupClickListener, setOnGroupExpandListener, setOnGroupCollapseListener,setOnChildClickListener這四個監聽事件,分别表示組元素點選事件,組元素展開,組收縮,子元素點選事件。我們可按需添加這四個監聽事件即可。由此看來ExpandableListView是多麼的簡單。看似簡單,但我們也要注意其中的一些細節。我相信你聽過細節決定成敗。下面我們就來一起看看細節。

1. 當設定setOnGroupClickListener監聽并讓其傳回true時,所有Group消費點選事件,事件均不能分發傳遞給child(換言之,設定setOnChildClickListener不起任何作用)。

2.預設設定完Group以及child,Group左邊會預設有以上下切換的圖示,假如你有強迫症可以通過mListView.setGroupIndicator(null)去除。

3.前面已經簡單說明了isChildSelectable(int groupPosition, int childPosition)方法的作用,是以當我們需要child可點選時,必須将setOnGroupClickListener和isChildSelectable對應設定為false和true。

4.說到這裡也許讀者會問,到底還是沒有說出圖一的做法。現在對圖一進行詳細的介紹。圖一主要是将Group設定為不能收縮并且使其預設展開(即設定setOnGroupClickListener傳回true,并且添加源碼中setAdapter後三行代碼)。

以上就是本人對ExpandableListView的一些淺薄之見,今天也是鄙人第一次寫部落格。都說Android技術博大精深,可能我闡述的隻是冰山一角,希望大家踴躍的給出批評與建議。本人也希望能與熱愛技術的開發人員進行深入的學習與交流。