安卓 ExpandableListView的使用详解

来源:互联网 发布:知乎 未解之谜 编辑:程序博客网 时间:2024/06/06 08:51

在Android开发中,我们知道经常会用到ListView来加载一些列表数据,但有时候ListView并不能完全十分满足我们的需求。比如如下图的效果用ExpandableListView实现起来就更方便点,我们直接用ExpandableListView,设置Group不能点击即可。好,费话不多说。下面详细介绍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.   
  17. </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.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.app.Activity;  
  7. import android.os.Bundle;  
  8. import android.view.LayoutInflater;  
  9. import android.view.View;  
  10. import android.view.View.OnClickListener;  
  11. import android.view.ViewGroup;  
  12. import android.widget.BaseExpandableListAdapter;  
  13. import android.widget.ExpandableListView;  
  14. import android.widget.ExpandableListView.OnChildClickListener;  
  15. import android.widget.ExpandableListView.OnGroupClickListener;  
  16. import android.widget.ExpandableListView.OnGroupCollapseListener;  
  17. import android.widget.ExpandableListView.OnGroupExpandListener;  
  18. import android.widget.ImageView;  
  19. import android.widget.TextView;  
  20. import android.widget.Toast;  
  21.   
  22. public class MainActivity extends Activity {  
  23.   private ExpandableListView mListView;  
  24.   private List<StrBean> group_list;  
  25.   private List<memBean> child_list;  
  26.   private StrBean strbean;  
  27.   private memBean membean;  
  28.   private LayoutInflater mInflater;  
  29.     @Override  
  30.     protected void onCreate(Bundle savedInstanceState) {  
  31.         super.onCreate(savedInstanceState);  
  32.         setContentView(R.layout.activity_main);  
  33.         initView();  
  34.     }  
  35.       
  36.     private void initView(){  
  37.         mListView = (ExpandableListView) findViewById(R.id.list);  
  38.         mInflater = LayoutInflater.from(MainActivity.this);  
  39.         group_list = new ArrayList<StrBean>();  
  40.         for(int i=0;i<5;i++){  
  41.             strbean =new StrBean();  
  42.             strbean.spacename = "深圳航港"+i;  
  43.             strbean.childsize = 8;  
  44.             child_list = new ArrayList<memBean>();  
  45.             for(int j=0;j<8;j++){  
  46.                 membean = new memBean();  
  47.                 membean.price=1+j+"万";  
  48.                 membean.secondPrice="1.6万";  
  49.                 membean.flag = i;  
  50.                 membean.title = "商务卡";  
  51.                 child_list.add(membean);  
  52.             }  
  53.             strbean.setList(child_list);   
  54.             group_list.add(strbean);  
  55.         }  
  56.         Adapter adapter = new Adapter();  
  57.         mListView.setGroupIndicator(null);  
  58.           
  59.         /** 
  60.          * ExpandableListView的组监听事件 
  61.          */  
  62.         mListView.setOnGroupClickListener(new OnGroupClickListener() {  
  63.               
  64.             @Override  
  65.             public boolean onGroupClick(ExpandableListView parent, View v,  
  66.                     int groupPosition, long id) {  
  67.                 Toast.makeText(MainActivity.this"第"+groupPosition+"组被点击了"0).show();  
  68.                 return true;  
  69.             }  
  70.         });  
  71.         /** 
  72.          * ExpandableListView的组展开监听 
  73.          */  
  74.         mListView.setOnGroupExpandListener(new OnGroupExpandListener() {  
  75.               
  76.             @Override  
  77.             public void onGroupExpand(int groupPosition) {  
  78.                 Toast.makeText(MainActivity.this"第"+groupPosition+"组展开"0).show();  
  79.             }  
  80.         });  
  81.         /** 
  82.          * ExpandableListView的组合拢监听 
  83.          */  
  84.         mListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {  
  85.               
  86.             @Override  
  87.             public void onGroupCollapse(int groupPosition) {  
  88.                 Toast.makeText(MainActivity.this"第"+groupPosition+"组合拢"0).show();  
  89.             }  
  90.         });  
  91.         /** 
  92.          * ExpandableListView的子元素点击监听 
  93.          */  
  94.         mListView.setOnChildClickListener(new OnChildClickListener() {  
  95.               
  96.             @Override  
  97.             public boolean onChildClick(ExpandableListView parent, View v,  
  98.                     int groupPosition, int childPosition, long id) {  
  99.                 Toast.makeText(MainActivity.this"第"+groupPosition+"组的第"+childPosition+"被点击了"0).show();  
  100.                 return true;  
  101.             }  
  102.         });  
  103.           
  104.         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. //自定义适配器  
  9. class Adapter extends BaseExpandableListAdapter{  
  10.        //获取子元素对象  
  11.     @Override  
  12.     public Object getChild(int groupPosition, int childPosition) {  
  13.         return null;  
  14.     }  
  15.        //获取子元素Id  
  16.     @Override  
  17.     public long getChildId(int groupPosition, int childPosition) {  
  18.         return childPosition;  
  19.     }  
  20.        //加载子元素并显示  
  21.     @Override  
  22.     public View getChildView(final int groupPosition, final int childPosition,  
  23.             boolean isLastChild, View convertView, ViewGroup parent) {  
  24.         View view=null;  
  25.         ChildHolder childholder = null;  
  26.         if(convertView!=null){  
  27.             view = convertView;  
  28.             childholder = (ChildHolder) view.getTag();  
  29.         }else{  
  30.             view = View.inflate(MainActivity.this,R.layout.item, null);  
  31.             childholder = new ChildHolder();  
  32.             childholder.mImage = (ImageView) view.findViewById(R.id.image);  
  33.             childholder.mPrice = (TextView) view.findViewById(R.id.textTwo);  
  34.             childholder.mStateText = (TextView) view.findViewById(R.id.textOne);  
  35.             childholder.mSecondPrice = (TextView) view.findViewById(R.id.textThree);  
  36.             view.setTag(childholder);  
  37.         }  
  38.         childholder.mImage.setOnClickListener(new OnClickListener() {  
  39.             @Override  
  40.             public void onClick(View v) {  
  41.                 Toast.makeText(MainActivity.this"第"+groupPosition+"组的第"+childPosition+"圖標被点击了"0).show();  
  42.             }  
  43.         });  
  44.         childholder.mPrice.setText(group_list.get(groupPosition)  
  45.                 .getList().get(childPosition).price);  
  46.         int len = group_list.get(groupPosition)  
  47.                 .getList().size();  
  48.         System.out.println(len+"-----------------");  
  49.         childholder.mStateText.setText(group_list.get(groupPosition)  
  50.                 .getList().get(childPosition).title);  
  51.         childholder.mSecondPrice.setText(group_list.get(groupPosition)  
  52.                 .getList().get(childPosition).secondPrice);  
  53.         return view;  
  54.     }  
  55.        //获取子元素数目  
  56.     @Override  
  57.     public int getChildrenCount(int groupPosition) {  
  58.         return group_list.get(groupPosition).childsize;  
  59.     }  
  60.     //获取组元素对象  
  61.     @Override  
  62.     public Object getGroup(int groupPosition) {  
  63.         return group_list.get(groupPosition);  
  64.     }  
  65.        //获取组元素数目  
  66.     @Override  
  67.     public int getGroupCount() {  
  68.         return group_list.size();  
  69.     }  
  70.     //获取组元素Id  
  71.     @Override  
  72.     public long getGroupId(int groupPosition) {  
  73.         return groupPosition;  
  74.     }  
  75.        //加载并显示组元素  
  76.     @Override  
  77.     public View getGroupView(int groupPosition, boolean isExpanded,  
  78.             View convertView, ViewGroup parent) {  
  79.         View view=null;  
  80.         GroupHolder groupholder = null;  
  81.         if(convertView!=null){  
  82.             view = convertView;  
  83.             groupholder = (GroupHolder) view.getTag();  
  84.         }else{  
  85.             view = View.inflate(MainActivity.this,R.layout.textview, null);  
  86.             groupholder =new GroupHolder();  
  87.             groupholder.mSpaceText = (TextView) view.findViewById(R.id.group_text);  
  88.             view.setTag(groupholder);  
  89.         }  
  90.         groupholder.mSpaceText.setText(group_list.get(groupPosition).spacename);  
  91.         return view;  
  92.     }  
  93.   
  94.     @Override  
  95.     public boolean hasStableIds() {  
  96.       
  97.         return true;  
  98.     }  
  99.          
  100.       
  101.     @Override  
  102.     public boolean isChildSelectable(int groupPosition, int childPosition) {  
  103.       
  104.         return false;  
  105.     }  
  106.       
  107. }  
  108.    
  109. static class GroupHolder{  
  110.     TextView mSpaceText;  
  111. }  
  112.   
  113. static class ChildHolder{  
  114.     ImageView mImage;  
  115.     TextView mStateText;  
  116.     TextView mPrice;  
  117.     TextView mSecondPrice;  
  118. }  

               效果图

在上面的源码中,总结说来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技术博大精深,可能我阐述的只是冰山一角,希望大家踊跃的给出批评与建议。本人也希望能与热爱技术的开发人员进行深入的学习与交流。
原创粉丝点击