ExpandableListView的使用详解

在Android开发中,我们知道经常会用到ListView来加载一些列表数据,但有时候ListView并不能完全十分满足我们的需求。比如如下图的效果用ExpandableListView实现起来就更方便点,我们直接用ExpandableListView,设置Group不能点击即可。好,费话不多说。下面详细介绍ExpandableListView的使用。
 
          图(一)
ExpandableListView主要由组与子元素组成。所以我们要分别对组元素以及子元素进行配置及操作。由于ExpandableListView与ListView类似,所以ExpandableListView必不可少的配置过程是必不可少的。首先在XML文件里配置ExpandableListView。
main.xml配置如下:
  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配置如下:
  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配置如下:
  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如下所示:
 
  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);
  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. }
  119. }

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

--------------------- 本文来自 金杰米 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/jamy2015/article/details/51131583?utm_source=copy

posted @ 2018-10-08 12:36  天涯海角路  阅读(1181)  评论(0)    收藏  举报