ExpandableListView简单应用及listview模拟ExpandableListView

  首先我们还是来看一些案例,还是拿搜狐新闻客户端,因为我天天上下班没事爱看这个东东,上班又没时间看新闻,上下班路途之余浏览下新闻打发时间嘛.

                          

看这个效果挺棒吧,其实实现起来也不难,我简单说明下.

首先我们用到的控件是:ExpandableListView

布局文件:

[java] view
plain
copy

  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.   
  6.     <!--  
  7.      android:groupIndicator="@null" 取消默认图片  
  8.     android:childIndicatorLeft 设置孩子左边间距  
  9.     android:dividerHeight 这个高度一定要设置,不然显示不出来分割线,估计默认为0 吧  
  10.      android:childDivider="@drawable/child_bg" 这个直接引color,或者图片会导致整个孩子背景都为这个颜色  ,不知道原因,如果有谁知道,请Give me say.  
  11.     -->  
  12.   
  13.     <ExpandableListView  
  14.         android:id="@+id/expandablelist"  
  15.         android:layout_width="match_parent"  
  16.         android:layout_height="match_parent"  
  17.         android:cacheColorHint="@null"  
  18.         android:childDivider="@drawable/child_bg"  
  19.         android:childIndicatorLeft="0dp"  
  20.         android:divider="@color/Grey"  
  21.         android:dividerHeight="1dp"  
  22.         android:groupIndicator="@null"  
  23.         android:scrollbarAlwaysDrawHorizontalTrack="true" >  
  24.     </ExpandableListView>  
  25.   
  26. </RelativeLayout>  

MyexpandableListAdapter.java

[java] view
plain
copy

  1. /*** 
  2.      * 数据源 
  3.      *  
  4.      * @author Administrator 
  5.      *  
  6.      */  
  7.     class MyexpandableListAdapter extends BaseExpandableListAdapter {  
  8.         private Context context;  
  9.         private LayoutInflater inflater;  
  10.   
  11.         public MyexpandableListAdapter(Context context) {  
  12.             this.context = context;  
  13.             inflater = LayoutInflater.from(context);  
  14.         }  
  15.   
  16.         // 返回父列表个数  
  17.         @Override  
  18.         public int getGroupCount() {  
  19.             return groupList.size();  
  20.         }  
  21.   
  22.         // 返回子列表个数  
  23.         @Override  
  24.         public int getChildrenCount(int groupPosition) {  
  25.             return childList.get(groupPosition).size();  
  26.         }  
  27.   
  28.         @Override  
  29.         public Object getGroup(int groupPosition) {  
  30.   
  31.             return groupList.get(groupPosition);  
  32.         }  
  33.   
  34.         @Override  
  35.         public Object getChild(int groupPosition, int childPosition) {  
  36.             return childList.get(groupPosition).get(childPosition);  
  37.         }  
  38.   
  39.         @Override  
  40.         public long getGroupId(int groupPosition) {  
  41.             return groupPosition;  
  42.         }  
  43.   
  44.         @Override  
  45.         public long getChildId(int groupPosition, int childPosition) {  
  46.             return childPosition;  
  47.         }  
  48.   
  49.         @Override  
  50.         public boolean hasStableIds() {  
  51.   
  52.             return true;  
  53.         }  
  54.   
  55.         @Override  
  56.         public View getGroupView(int groupPosition, boolean isExpanded,  
  57.                 View convertView, ViewGroup parent) {  
  58.             GroupHolder groupHolder = null;  
  59.             if (convertView == null) {  
  60.                 groupHolder = new GroupHolder();  
  61.                 convertView = inflater.inflate(R.layout.group, null);  
  62.                 groupHolder.textView = (TextView) convertView  
  63.                         .findViewById(R.id.group);  
  64.                 groupHolder.imageView = (ImageView) convertView  
  65.                         .findViewById(R.id.image);  
  66.                 groupHolder.textView.setTextSize(15);  
  67.                 convertView.setTag(groupHolder);  
  68.             } else {  
  69.                 groupHolder = (GroupHolder) convertView.getTag();  
  70.             }  
  71.   
  72.             groupHolder.textView.setText(getGroup(groupPosition).toString());  
  73.             if (isExpanded)// ture is Expanded or false is not isExpanded  
  74.                 groupHolder.imageView.setImageResource(R.drawable.expanded);  
  75.             else  
  76.                 groupHolder.imageView.setImageResource(R.drawable.collapse);  
  77.             return convertView;  
  78.         }  
  79.   
  80.         @Override  
  81.         public View getChildView(int groupPosition, int childPosition,  
  82.                 boolean isLastChild, View convertView, ViewGroup parent) {  
  83.             if (convertView == null) {  
  84.                 convertView = inflater.inflate(R.layout.item, null);  
  85.             }  
  86.             TextView textView = (TextView) convertView.findViewById(R.id.item);  
  87.             textView.setTextSize(13);  
  88.             textView.setText(getChild(groupPosition, childPosition).toString());  
  89.             return convertView;  
  90.         }  
  91.   
  92.         @Override  
  93.         public boolean isChildSelectable(int groupPosition, int childPosition) {  
  94.             return true;  
  95.         }  
  96.     }  
  97.   
  98.     @Override  
  99.     public boolean onGroupClick(final ExpandableListView parent, final View v,  
  100.             int groupPosition, final long id) {  
  101.   
  102.         return false;  
  103.     }  

上面实现起来比较简单.相信对listview熟悉的朋友看这个一定很熟悉,无外乎就是多了个孩子.

selector_group.xml

[java] view
plain
copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  3.   
  4.     <item android:drawable="@color/Grey" android:state_pressed="true"></item>  
  5.     <item android:drawable="@color/Grey" android:state_selected="true"></item>  
  6.     <item android:drawable="@color/LightGray"></item>  
  7.   
  8. </selector>  

selector_item.xml  同理.

效果图:

              
      

效果虽然丑了点,不过就是这么回事,至于显示group的item,还是孩子的item,你可以随意定制.

   不想敲的同学,可以下载源码,稍作调整.  

   源码下载

/********************************LIstView模拟ExpandableListView**************************************************************/

下面我们接着看一些案例:

               

其实就是:点击listview的一个item,展开其孩子,点击另一个item,打开其孩子,关闭之前那个孩子.

这个眨一看是ExpandableListView这个东东,可是本人比较笨戳,整了好久没有弄出来,最终放弃,google下,发现有人用listview来模拟实现,也就跟着做了下.

布局文件:(后面多个隐藏text.)

[java] view
plain
copy

  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:background="@color/white"  
  6.     android:gravity="center_vertical"  
  7.     android:orientation="vertical" >  
  8.   
  9.     <RelativeLayout  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="wrap_content"  
  12.         android:background="@drawable/selector_group"  
  13.         android:gravity="center_vertical"  
  14.         android:orientation="horizontal"  
  15.         android:padding="5dp" >  
  16.   
  17.         <TextView  
  18.             android:id="@+id/group"  
  19.             android:layout_width="wrap_content"  
  20.             android:layout_height="wrap_content"  
  21.             android:layout_centerVertical="true"  
  22.             android:textColor="@color/black" />  
  23.   
  24.         <ImageView  
  25.             android:id="@+id/image"  
  26.             android:layout_width="wrap_content"  
  27.             android:layout_height="wrap_content"  
  28.             android:layout_alignParentRight="true"  
  29.             android:layout_centerVertical="true"  
  30.             android:src="@drawable/collapse" />  
  31.     </RelativeLayout>  
  32.   
  33.     <TextView  
  34.         android:id="@+id/hint_item"  
  35.         android:layout_width="fill_parent"  
  36.         android:layout_height="wrap_content"  
  37.         android:gravity="center_vertical"  
  38.         android:padding="10dp"  
  39.         android:textColor="@color/black"  
  40.         android:visibility="gone" />  
  41.   
  42. </LinearLayout>  

MyAdpter.java

[java] view
plain
copy

  1. /*** 
  2.      * 数据源 
  3.      *  
  4.      * @author zhangjia 
  5.      *  
  6.      */  
  7.     class MyAdpter extends BaseAdapter {  
  8.         private Context context;  
  9.         private LayoutInflater inflater;  
  10.   
  11.         private int change_index = -1;// 改变项  
  12.   
  13.         public MyAdpter(Context context) {  
  14.             super();  
  15.             this.context = context;  
  16.             inflater = (LayoutInflater) context  
  17.                     .getSystemService(context.LAYOUT_INFLATER_SERVICE);  
  18.         }  
  19.   
  20.         @Override  
  21.         public int getCount() {  
  22.             return groupList.size();  
  23.         }  
  24.   
  25.         @Override  
  26.         public Object getItem(int position) {  
  27.             return groupList.get(position);  
  28.         }  
  29.   
  30.         @Override  
  31.         public long getItemId(int position) {  
  32.             return position;  
  33.         }  
  34.   
  35.         @Override  
  36.         public View getView(int position, View convertView, ViewGroup parent) {  
  37.             GroupHolder groupHolder = null;  
  38.             if (convertView == null) {  
  39.                 groupHolder = new GroupHolder();  
  40.                 convertView = inflater.inflate(R.layout.group, null);  
  41.                 groupHolder.textView = (TextView) convertView  
  42.                         .findViewById(R.id.group);  
  43.                 groupHolder.imageView = (ImageView) convertView  
  44.                         .findViewById(R.id.image);  
  45.                 groupHolder.hint_item = (TextView) convertView  
  46.                         .findViewById(R.id.hint_item);  
  47.                 convertView.setTag(groupHolder);  
  48.             } else {  
  49.                 groupHolder = (GroupHolder) convertView.getTag();  
  50.             }  
  51.             groupHolder.textView.setText(groupList.get(position));  
  52.             groupHolder.hint_item.setText(childList.get(position));  
  53.             if (change_index == position)  
  54.                 groupHolder.hint_item.setVisibility(View.VISIBLE);  
  55.             else  
  56.                 groupHolder.hint_item.setVisibility(View.GONE);  
  57.   
  58.             return convertView;  
  59.         }  
  60.   
  61.         /*** 
  62.          * 这个方法用于更改子item的状态 
  63.          */  
  64.         public void changeImageVisable(View view, int position) {  
  65.             // 隐藏提示  
  66.             if (change_index == position) {  
  67.                 GroupHolder groupHolder = (GroupHolder) view.getTag();  
  68.                 if (groupHolder.hint_item.getVisibility() == View.VISIBLE)  
  69.                     groupHolder.hint_item.setVisibility(View.GONE);  
  70.                 else  
  71.                     groupHolder.hint_item.setVisibility(View.VISIBLE);  
  72.   
  73.             } else {  
  74.                 change_index = position;  
  75.                 notifyDataSetChanged();// restart getview  
  76.             }  
  77.   
  78.         }  
  79.     }  

这个数据源很简单,只是多了个用于控制孩子隐藏与显示的方法changeImageVisable.代码很简单,相信不用过多解释.

效果:

            
         

上面模拟显示的孩子是一个textview(缺点:隐藏textview显示时候点击会影响到其父控件,大家尝试一下,不过肯定有解决办法的.),

下面我来介绍下,如果孩子是listview应该怎么办.

首先配置文件:

[java] view
plain
copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!-- android:descendantFocusability="blocksDescendants"这个属性就可以让父listview获取焦点 -->  
  3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="wrap_content"  
  6.     android:background="@color/white"  
  7.     android:descendantFocusability="blocksDescendants"  
  8.     android:gravity="center_vertical"  
  9.     android:orientation="vertical" >  
  10.   
  11.     <RelativeLayout  
  12.         android:layout_width="match_parent"  
  13.         android:layout_height="wrap_content"  
  14.         android:background="@drawable/selector_group"  
  15.         android:gravity="center_vertical"  
  16.         android:orientation="horizontal"  
  17.         android:padding="5dp" >  
  18.   
  19.         <TextView  
  20.             android:id="@+id/group"  
  21.             android:layout_width="wrap_content"  
  22.             android:layout_height="wrap_content"  
  23.             android:layout_centerVertical="true"  
  24.             android:text="精品推荐"  
  25.             android:textColor="@color/black" />  
  26.   
  27.         <ImageView  
  28.             android:id="@+id/image"  
  29.             android:layout_width="wrap_content"  
  30.             android:layout_height="wrap_content"  
  31.             android:layout_alignParentRight="true"  
  32.             android:layout_centerVertical="true"  
  33.             android:src="@drawable/collapse" />  
  34.     </RelativeLayout>  
  35.   
  36.     <ListView  
  37.         android:id="@+id/hint_item"  
  38.         android:layout_width="fill_parent"  
  39.         android:layout_height="wrap_content"  
  40.         android:gravity="center_vertical"  
  41.         android:textColor="@color/black" />  
  42.   
  43. </LinearLayout>  

[java] view
plain
copy

  1. /*** 
  2.  * InitData 
  3.  */  
  4. void InitData() {  
  5.     groupList = new ArrayList<String>();  
  6.     groupList.add("Ios");  
  7.     groupList.add("Android");  
  8.     groupList.add("Window");  
  9.     childList = new ArrayList<ArrayList<String>>();  
  10.     for (int i = 0; i < groupList.size(); i++) {  
  11.         ArrayList<String> childTemp;  
  12.         if (i == 0) {  
  13.             childTemp = new ArrayList<String>();  
  14.             childTemp.add("iphone 4");  
  15.             childTemp.add("iphone 5");  
  16.         } else if (i == 1) {  
  17.             childTemp = new ArrayList<String>();  
  18.             childTemp.add("Anycall");  
  19.             childTemp.add("HTC");  
  20.             childTemp.add("Motorola");  
  21.         } else {  
  22.             childTemp = new ArrayList<String>();  
  23.             childTemp.add("Lumia 800C ");  
  24.         }  
  25.         childList.add(childTemp);  
  26.     }  
  27. }  

[java] view
plain
copy

  1. /*** 
  2.      * 父数据源 
  3.      *  
  4.      * @author zhangjia 
  5.      *  
  6.      */  
  7.     class MyAdpter extends BaseAdapter {  
  8.         private Context context;  
  9.         private LayoutInflater inflater;  
  10.   
  11.         private int change_index = -1;// 改变项  
  12.   
  13.         public MyAdpter(Context context) {  
  14.             super();  
  15.             this.context = context;  
  16.             inflater = (LayoutInflater) context  
  17.                     .getSystemService(context.LAYOUT_INFLATER_SERVICE);  
  18.         }  
  19.   
  20.         @Override  
  21.         public int getCount() {  
  22.             return groupList.size();  
  23.         }  
  24.   
  25.         @Override  
  26.         public Object getItem(int position) {  
  27.             return groupList.get(position);  
  28.         }  
  29.   
  30.         @Override  
  31.         public long getItemId(int position) {  
  32.             return position;  
  33.         }  
  34.   
  35.         @Override  
  36.         public View getView(final int position, View convertView,  
  37.                 ViewGroup parent) {  
  38.             GroupHolder groupHolder = null;  
  39.             if (convertView == null) {  
  40.                 groupHolder = new GroupHolder();  
  41.                 convertView = inflater.inflate(R.layout.group_item, null);  
  42.                 groupHolder.textView = (TextView) convertView  
  43.                         .findViewById(R.id.group);  
  44.                 groupHolder.imageView = (ImageView) convertView  
  45.                         .findViewById(R.id.image);  
  46.                 groupHolder.hint_item = (ListView) convertView  
  47.                         .findViewById(R.id.hint_item);  
  48.   
  49.                 convertView.setTag(groupHolder);  
  50.             } else {  
  51.                 groupHolder = (GroupHolder) convertView.getTag();  
  52.             }  
  53.             groupHolder.textView.setText(groupList.get(position));  
  54.             groupHolder.hint_item.setAdapter(getListView(childList  
  55.                     .get(position)));  
  56.             groupHolder.hint_item  
  57.                     .setOnItemClickListener(new OnItemClickListener() {  
  58.                         @Override  
  59.                         public void onItemClick(AdapterView<?> parent,  
  60.                                 View view, int position_id, long id) {  
  61.                             Toast.makeText(context,  
  62.                                     childList.get(position).get(position_id), 1)  
  63.                                     .show();  
  64.                         }  
  65.                     });  
  66.             // 动态设置listview 的高度  
  67.             setListViewHeightBaseOnChildren(groupHolder.hint_item);  
  68.   
  69.             if (change_index == position) {  
  70.                 groupHolder.hint_item.setVisibility(View.VISIBLE);  
  71.                 groupHolder.imageView.setImageResource(R.drawable.expanded);  
  72.             }  
  73.   
  74.             else {  
  75.                 groupHolder.hint_item.setVisibility(View.GONE);  
  76.                 groupHolder.imageView.setImageResource(R.drawable.collapse);  
  77.             }  
  78.   
  79.             return convertView;  
  80.         }  
  81.   
  82.         /*** 
  83.          * 这个方法用于更改子item的状态 
  84.          */  
  85.         public void changeImageVisable(View view, int position) {  
  86.             // 隐藏提示  
  87.             if (change_index == position) {  
  88.                 GroupHolder groupHolder = (GroupHolder) view.getTag();  
  89.                 if (groupHolder.hint_item.getVisibility() == View.VISIBLE)  
  90.                     groupHolder.hint_item.setVisibility(View.GONE);  
  91.                 else  
  92.                     groupHolder.hint_item.setVisibility(View.VISIBLE);  
  93.             } else {  
  94.                 change_index = position;  
  95.                 notifyDataSetChanged();// restart getview  
  96.             }  
  97.   
  98.         }  
  99.     }  

上面代码和刚才的差不多,唯一需要我们注意的是“listview嵌套listview,我们需要注意哪些问题”.

第一:listview和listview嵌套,子listview只显示一个多一点点,不能正常显示,解决办法:对listview重新设置起高度.(相信同学们对这个方法一点也不陌生.)

[java] view
plain
copy

  1. /*** 
  2.      * 动态设置listview的高度 
  3.      *  
  4.      * @param listView 
  5.      */  
  6.     public void setListViewHeightBaseOnChildren(ListView listView) {  
  7.         ListAdapter listAdapter = listView.getAdapter();  
  8.         if (listAdapter == null)  
  9.             return;  
  10.         int totalHeight = 0;// 总高度  
  11.         for (int i = 0; i < listAdapter.getCount(); i++) {  
  12.             View listitem = listAdapter.getView(i, null, listView);  
  13.             listitem.measure(0, 0);  
  14.             totalHeight += listitem.getMeasuredHeight();  
  15.         }  
  16.         int totalDividerHeight = 0;  
  17.         totalDividerHeight = listView.getDividerHeight()  
  18.                 * (listAdapter.getCount() - 1);  
  19.         ViewGroup.LayoutParams layoutParams = listView.getLayoutParams();  
  20.         layoutParams.height = totalHeight + totalDividerHeight;  
  21.         listView.setLayoutParams(layoutParams);  
  22.     }  

第二个问题:listview 嵌套listview的时候,子listview会屏蔽掉父listview的焦点.使得父listview无法点击.

解决办法很简单:我们只需要在父listview的Adapter里面的配置文件最顶部的如LinearLayout加入一行:  android:descendantFocusability="blocksDescendants"就ok了. 

效果图:

   

嗯,效果还可以吧,就介绍这么多了,如有问题或好的建议请吉留言.

时间: 2024-09-13 01:33:26

ExpandableListView简单应用及listview模拟ExpandableListView的相关文章

android Listview模拟聊天界面

本文实例为大家分享了android Listview模拟聊天界面的具体代码,供大家参考,具体内容如下 代码: package com.example.test; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; im

qtday02 qt做简单的加法器和模拟登陆功能

//在3t2目录下 //adder.h /* qt简单加法计算器 */ #ifndef ADDER_H #define ADDER_H #include<QDialog> #include<QLineEdit> #include<QtWidgets/QPushButton> #include<QtWidgets/QLabel> class Adder:public QDialog{     Q_OBJECT//让自定义的槽函数生效     private:

Android中使用ListView模拟微信好友功能

效果图: 分析: 1.创建listView 2.创建数据 3.创建适配器 将数据放到呈现数据的容器里面. 将这个容器(带数据)连接适配器. 其实是直接在我们自己写的adapter的getView重载方法中返回连接的view. View view=View.inflate(mContext, com.example.weChatFriends.R.layout.item_friend, null); return view; 4.ListView设置适配器 代码: package fry; imp

Android开发之ListView实现不同品种分类分隔栏的效果(非ExpandableListView实现)

我们有时候会遇到这么一个情况.就是我在一个ListView里面需要显示的东西其实是有种类之分的.比如我要分冬天,夏天,秋天,春天,然后在这每个季节下面再去加载各自的条目数据.还有,比如我们的通讯录,我们需要按A,B,C这样的字母顺序分类然后显示.这个怎么实现呢? 下面我们不用ExpandableListView,而是只用ListView来实现这一显示效果. MainActivity.java [java] view plaincopy package com.xzq.listviewadapte

android使用ExpandableListView控件实现小说目录效果的例子_Android

今天给大家讲讲android的目录实现方法,就像大家看到的小说目录一样,android 提供了ExpandableListView控件可以实现二级列表展示效果,现在给大家讲讲这个控件的用法,下面是XML定义: 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout     xmlns:android="http://schemas.android.com/apk/re

Android ExpandableListView展开列表控件使用实例_Android

你是否觉得手机QQ上的好友列表那个控件非常棒? 不是..... 那也没关系,学多一点知识对自己也有益无害. 那么我们就开始吧. 展开型列表控件, 原名ExpandableListView 是普通的列表控件进阶版, 可以自由的把列表进行收缩, 非常的方便兼好看. 首先看看我完成的截图, 虽然界面不漂亮, 但大家可以自己去修改界面. 该控件需要一个主界面XML 一个标题界面XML及一个列表内容界面XML 首先我们来看看 mian.xml 主界面 复制代码 代码如下: //该界面非常简单, 只要一个E

《Android 平板电脑开发实战详解和典型案例》——2.6节可展开列表—— ExpandableListView

2.6 可展开列表-- ExpandableListView Android 平板电脑开发实战详解和典型案例 上一节中介绍了NumberPicker的基本知识及简单案例,本节将介绍Android 2.0控件可扩展列表ExpandableListView,主要内容包括其基本知识以及一个简单的案例. 2.6.1 可展开列表基本知识 可展开列表ExpandableListView在主界面显示的效果就是下拉菜单.当单击可展开列表ExpandableListView时会弹出一个子菜单,当再单击时界面就会恢

Android 关于ExpandableListView刷新问题的解决方法_Android

正文 首先是最基础的 ExpandableListView vList = (ExpandableListView) this.findViewById(R.id.list); EListAdapter adapter = new EListAdapter(getApplicationContext(), list); //list 是数据源 vList.setAdapter(adapter); //适配器就不写了, 都懂的 class EListAdapter extends BaseExpa

Android 中使用ExpandableListView 实现分组的实例_Android

 Android 中使用ExpandableListView 实现分组 一个视图显示垂直滚动两级列表中的条目.这不同于列表视图,允许两个层次,类似于QQ的好友分组.要实现这个效果的整体思路为: 1.要给ExpandableListView 设置适配器,那么必须先设置数据源. 2.数据源,就是此处的适配器类,此方法继承了BaseExpandableListAdapter,它是ExpandableListView的一个子类.需要重写里面的多个方法.方法的意思,代码中都有详细的注释.数据源中,用到了自