ExpandableListView使用
相关博客
ExpandableListView使用
博客内容记录
场景
有时候,使用ListView并不能满足应用程序所需要的功能。有些应用程序需要多组ListView,这时候我们就要使用一种新的控件ExpandableListView——可以扩展的ListView。它的作用就是将ListView进行分组。就好像我们使用QQ的时候,有“我的好友”,“陌生人”,“黑名单”一样,点击一下会扩展开,再点击一下又会收缩回去。
ExpandableListView是一个垂直滚动显示两级列表项的视图,与ListView不同的是,它可以有两层:每一层都能够被独立的展开并显示其子项。这些子项来自于与该视图关联的ExpandableListAdapter。
每一个可以扩展的列表项的旁边都有一个指示符(箭头)用来说明该列表项目前的状态(这些状态一般是已经扩展开的列表项,还没有扩展开的列表项,子列表项和最后一个子列表项)。
- 可以使用方法:setChildIndicator(Drawable),setGroupIndicator(Drawable)(或者相应的XML文件的属性) 去设置这些指示符的样式。当然也可以使用默认的指示符。
- 和android.R.layout.simple_expandable_list_item_1,android.R.layout.simple_expandable_list_item_2和ListView一样,ExpandableListView也是一个需要Adapter作为桥梁来取得数据的控件。一般适用于ExpandableListView的Adapter都要继承BaseExpandableListAdapter这个类,并且必须重载getGroupView和getChildView这两个最为重要的方法。
- BaseExpandableListAdapter的主要重载方法如下:
- public abstract ObjectgetChild (int groupPosition, int childPosition)
取得与指定分组、指定子项目关联的数据.
参数
groupPosition 包含子视图的分组的位置.
childPosition 指定的分组中的子视图的位置.
返回
与子视图关联的数据. - public abstract long getChildId (int groupPosition, intchildPosition)
取得给定分组中给定子视图的ID. 该组ID必须在组中是唯一的.必须不同于其他所有ID(分组及子项目的ID).
参数
groupPosition 包含子视图的分组的位置.
childPosition 要取得ID的指定的分组中的子视图的位置.
返回
与子视图关联的ID. - public abstract View getChildView (int groupPosition, intchildPosition, boolean isLastChild, View convertView, ViewGroup parent)
取得显示给定分组给定子位置的数据用的视图.
参数
groupPosition 包含要取得子视图的分组位置.
childPosition 分组中子视图(要返回的视图)的位置.
isLastChild 该视图是否为组中的最后一个视图.
convertView 如果可能,重用旧的视图对象.使用前你应该保证视图对象为非空,并且是否是合适的类型.如果该对象不能转换为可以正确显示数据的视图,该方法就创建新视图.不保证使用先前由 getChildView(int, int,boolean, View, ViewGroup)创建的视图.
parent 该视图最终从属的父视图.
返回
指定位置相应的子视图. - public abstract int getChildrenCount (int groupPosition)
取得指定分组的子元素数.
参数
groupPosition 要取得子元素个数的分组位置.
返回
指定分组的子元素个数. - public abstract long getCombinedChildId (long groupId, long childId)
取得一览中可以唯一识别子条目的 ID(包括分组ID和子条目ID).可扩展列表要求每个条目 (分组条目和子条目)具有一个可以唯一识别列表中子条目和分组条目的ID. 该方法根据给定子条目ID和分组条目ID返回唯一识别ID.另外,如果 hasStableIds() 为真,该函数返回的ID必须是固定不变的.
参数
groupId 包含子条目ID的分组条目ID.
childId 子条目的ID.
返回
可以在所有分组条目和子条目中唯一识别该子条目的ID(可能是固定不变的). - public abstract long getCombinedGroupId (long groupId)
取得一览中可以唯一识别子条目的 ID(包括分组ID和子条目ID).可扩展列表要求每个条目 (分组条目和子条目)具有一个可以唯一识别列表中子条目和分组条目的ID. 该方法根据给定子条目ID和分组条目ID返回唯一识别ID.另外,如果 hasStableIds() 为真,该函数返回的ID必须是固定不变的.
参数
groupId 分组条目ID.
返回
可以在所有分组条目和子条目中唯一识别该分组条目的ID(可能是固定不变的). - public abstract Object getGroup (int groupPosition)
取得与给定分组关联的数据.
参数
groupPosition 分组的位置.
返回
指定分组的数据.
public abstract int getGroupCount ()
取得分组数.
返回
分组数. - public abstract long getGroupId (int groupPosition)
取得指定分组的ID.该组ID必须在组中是唯一的.必须不同于其他所有ID(分组及子项目的ID).
参数
groupPosition 要取得ID的分组位置.
返回
与分组关联的ID. - public abstract View getGroupView (int groupPosition, booleanisExpanded, View convertView, ViewGroup parent)
取得用于显示给定分组的视图. 这个方法仅返回分组的视图对象, 要想获取子元素的视图对象,就需要调用 getChildView(int, int, boolean, View, ViewGroup).
参数
groupPosition 决定返回哪个视图的组位置 .
isExpanded 该组是展开状态还是收起状态 .
convertView 如果可能,重用旧的视图对象.使用前你应该保证视图对象为非空,并且是否是合适的类型.如果该对象不能转换为可以正确显示数据的视图,该方法就创建新视图.不保证使用先前由 getGroupView(int, boolean,View, ViewGroup)创建的视图.
parent 该视图最终从属的父视图.
返回
指定位置相应的组视图. - public abstract boolean hasStableIds ()
是否指定分组视图及其子视图的ID对应的后台数据改变也会保持该ID.
返回
是否相同的ID总是指向同一个对象. - public abstract boolean isChildSelectable (int groupPosition, intchildPosition)
指定位置的子视图是否可选择.
参数
groupPosition 包含要取得子视图的分组位置.
childPosition 分组中子视图的位置.
返回
是否子视图可选择.
- 优化扩展
这样就完成了一个最简单的ExpandableListView的控件。
在实际开发过程中,常常有不同的需求,比如每一个child需要不同的控件,每一个group或者child需要有图标,图标显示需要不一样,需要设置背景等各种各样能够让我们的程序变得美观的需求。那么下面就逐 一讨论一下ExpandableListView如何实现这些需求。
- 为ExpandableListView设置背景,并且默认展开第n组,n从0开始计数,则只需要添加如下代码:
1. myExpandableListView.setBackgroundResource(R.drawable.background);
2. myExpandableListView.expandGroup(0);
复制代码
则效果如下:
- 改变每个组前面的图标,并且图标样式随着合拢和展开不同,则只需要在res/drawable目录下定义文件:
Indicator.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_expanded="true" android:drawable="@drawable/right" />
<item android:drawable="@drawable/down"></item>
</selector>
复制代码
- 在JAVA文件中添加:
myExpandableListView.setGroupIndicator(this.getResources().getDrawable(R.drawable.indicator));
复制代码
效果如下:
对于其他的属性设置,可以参考以下属性说明:
- android:childDivider
来分离子列表项的图片或者是颜色。注:图片不会完全显示,分离子列表项的是一条直线 - android:childIndicator
在子列表项旁边显示的指示符。注:可以是一个图片 - android:childIndicatorLeft
子列表项指示符的左边约束位置。注:即从左端0位置开始计数,比如,假设指示符是一个图标,给定这个属性值为3dip,则表示从左端起3dip开始显示此图标。 - android:childIndicatorRight
子列表项指示符的右边约束位置。注:表示右端到什么位置结束 - android:groupIndicator
在组列表项旁边显示的指示符。注:可以是一个图片。 - android:indicatorLeft
组列表项指示器的左边约束位置。注:表示左端从什么位置开始。 - android:indicatorRight
组列表项指示器的右边约束位置。注:表示右端到什么位置结束。
- 以疯狂android为例的基本用法介绍ExpandableListView其中几个重要的方法
- getGroupCount()
返回包含的组列表项的数量。
@Override
public int getGroupCount()
{
return armTypes.length;
}
- getGroup(int groupPosition)
返回组列表的数据
@Override
public Object getGroup(int groupPosition)
{
return armTypes[groupPosition];
}
- getGroupId(int groupPosition)
放回组列表组件的id
@Override
public long getGroupId(int groupPosition)
{
return groupPosition;
}
- getGroupView()
该方法将返回的View对象将作为组列表项
public View getGroupView(int groupPosition, boolean isExpanded,View convertView, ViewGroup parent)
{
LinearLayout ll = new LinearLayout(MainActivity.this);
ll.setOrientation(0);
ImageView logo = new ImageView(MainActivity.this);
logo.setImageResource(logos[groupPosition]);
ll.addView(logo);
TextView textView = getTextView();
textView.setText(getGroup(groupPosition).toString());
ll.addView(textView);
return ll;
}
- getChildCount()
该方法返回特定组所包含的子列表项的数量
@Override
public int getChildrenCount(int groupPosition)
{
return arms[groupPosition].length;
}
- getChildView()
该方法返回的View对象将作为特定组、特定位置的子列表项
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent)
{
TextView textView = getTextView();
textView.setText(getChild(groupPosition, childPosition)
.toString());
return textView;
}
- getChildId()
返回子列表组件的id
public long getChildId(int groupPosition, int childPosition)
{
return childPosition;
}
- getChild(int groupPosition, int childPosition)
返回子列表的数据
public Object getChild(int groupPosition, int childPosition)
{
return arms[groupPosition][childPosition];
}
@Override
public long getChildId(int groupPosition, int childPosition)
{
return childPosition;
}
isChildSelectable()
该方法返回true时,可以对子列表项设置监听监听函数
1、listView.setOnChildClickListener()
监听子列表项按下事件
2、setOnGroupClickListener()
监听组列表项按下事件
疯狂android中代码文件
package org.crazyit.ui;
import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//创建一个BaseExpandableListAdapter对象
ExpandableListAdapter adapter = new BaseExpandableListAdapter()
{
int[] logos = new int[]
{
R.drawable.p,
R.drawable.z,
R.drawable.t
};
private String[] armTypes = new String[]
{ "神族兵种", "虫族兵种", "人族兵种"};
private String[][] arms = new String[][]
{
{ "狂战士", "龙骑士", "黑暗圣堂", "电兵" },
{ "小狗", "刺蛇", "飞龙", "自爆飞机" },
{ "机枪兵", "护士MM" , "幽灵" }
};
// 获取指定组位置、指定子列表项处的子列表项数据
@Override
public Object getChild(int groupPosition, int childPosition)
{
return arms[groupPosition][childPosition];
}
@Override
public long getChildId(int groupPosition, int childPosition)
{
return childPosition;
}
@Override
public int getChildrenCount(int groupPosition)
{
return arms[groupPosition].length;
}
private TextView getTextView()
{
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, 64);
TextView textView = new TextView(MainActivity.this);
textView.setLayoutParams(lp);
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
textView.setPadding(36, 0, 0, 0);
textView.setTextSize(20);
return textView;
}
// 该方法决定每个子选项的外观
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent)
{
TextView textView = getTextView();
textView.setText(getChild(groupPosition, childPosition)
.toString());
return textView;
}
// 获取指定组位置处的组数据
@Override
public Object getGroup(int groupPosition)
{
return armTypes[groupPosition];
}
@Override
public int getGroupCount()
{
return armTypes.length;
}
@Override
public long getGroupId(int groupPosition)
{
return groupPosition;
}
// 该方法决定每个组选项的外观
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent)
{
LinearLayout ll = new LinearLayout(MainActivity.this);
ll.setOrientation(0);
ImageView logo = new ImageView(MainActivity.this);
logo.setImageResource(logos[groupPosition]);
ll.addView(logo);
TextView textView = getTextView();
textView.setText(getGroup(groupPosition).toString());
ll.addView(textView);
return ll;
}
@Override
public boolean isChildSelectable(int groupPosition,
int childPosition)
{
return true;
}
@Override
public boolean hasStableIds()
{
return true;
}
};
ExpandableListView expandListView = (ExpandableListView) findViewById(R.id.list);
expandListView.setAdapter(adapter);
}
}
ExpandableListView使用的更多相关文章
- Android中使用ExpandableListView实现微信通讯录界面(完善仿微信APP)
之前的博文<Android中使用ExpandableListView实现好友分组>我简单介绍了使用ExpandableListView实现简单的好友分组功能,今天我们针对之前的所做的仿微信 ...
- Android中使用ExpandableListView实现好友分组
一个视图显示垂直滚动两级列表中的条目.这不同于列表视图,允许两个层次,类似于QQ的好友分组.要实现这个效果的整体思路为: 1.要给ExpandableListView 设置适配器,那么必须先设置数据源 ...
- 安卓开发树形控件之ExpandableListView(一)
这个例子非常简单,简单到一个初学者都能随便开发出来,今天的目的仅仅只是为了将效果实现出来,如果想深入这里有几篇非常不错的博客: Android 之ExpandableListView几个特殊的属性 h ...
- android 伸缩控件ExpandableListView 展开失败的可能原因。
(原创)转载请声明出处http://www.cnblogs.com/linguanh/ 问题原型: ExpandableListView 展开失效. --------------------直接看结论 ...
- ExpandableListView实现展开更多和收起更多
[需求]: 如上面图示 当点开某个一级菜单的时候,其他菜单收起: 子级菜单默认最多5个: 多于5个的显示"展开更多" 点击"展开更多",展开该级所有子级菜单,同 ...
- Android UI控件----ExpandableListView的基本用法
ExpandableListView介绍 ExpandableListView的引入 ExpandableListView可以显示一个视图垂直滚动显示两级列表中的条目,这不同于列表视图(ListVie ...
- 【原创】Android ExpandableListView使用
ExpandableView的使用可以绑定到SimpleExpandableListAdapter,主要是看这个Adapter怎么用. 这个类默认的构造函数有9个参数, 很好地解释了什么叫做又臭又长. ...
- android原生ExpandableListView
android原生可扩展ExpandableListView就是可以伸缩的listView,一条标题下面有多条内容. 这个list的adapter对的数据要求与普通ListView的数据要求也有一些差 ...
- 可滑动的ExpandableListView
可以向左滑动的扩展列表 向左滑动源码是参照GitHub上的里的 ListView的思路写出来的,按照他的思路,由于本人水平有限,只写了关键代码,能够完美运行,adapter改变之后能自动收回. 滑出状 ...
- Android中ExpandableListView的使用
ExpandableListView是Android中可以实现下拉list的一个控件,具体的实现方法如下: 首先:在layout的xml文件中定义一个ExpandableListView < L ...
随机推荐
- gcd,最大公约数,lcm,最小公倍数
int gcd(int a,int b){ ?a:gcd(b,a%b); } 关于lcm,若写成a*b/gcd(a,b) ,a*b可能会溢出! int lcm(int a,int b){ return ...
- “华尔街之狼”:ICO是“史上最大骗局”
勘探船进村的那个夏季,父亲从城里带回了那把手电.手电的金属外壳镀了镍,看上去和摸起来一样冰凉.父亲进城以前采了两筐枸杞子,他用它们换回了那把锃亮的东西.父亲一个人哼着<十八摸>上路,鲜红透 ...
- HTML笔记<note2>
文本标记 我是正常的文本段落 我是用b标记的加粗文本 我是用strong定义的强调文本 i标记的倾斜文本 em强调文本 del标记的删除线 del标记的下划线文本 特殊字符标记 显示 说明 空格&am ...
- Tomcat 笔记-目录简介
bin:启动和关闭tomcat的bat文件 conf:配置文件 server.xml该文件用于配置server相关的信息,比如tomcat启动的端口号,配置主机(Host) web.xml文件配置与w ...
- python分布式环境下的限流器
项目中用到了限流,受限于一些实现方式上的东西,手撕了一个简单的服务端限流器. 服务端限流和客户端限流的区别,简单来说就是: 1)服务端限流 对接口请求进行限流,限制的是单位时间内请求的数量,目的是通过 ...
- 启动报错 Unsupported major.minor version 51.0
Unsupported major.minor version 51.0错误, 是使用jdk6启动jdk7编译的项目,更换jdk7就好了,或者用jdk6重新打包项目. 解决起来也很方便:打开excli ...
- 想成为一个高效的Web开发者吗?来看看大牛分享的经验吧~ #精选JAVASCRIPT前端开发
想成为一个高效的Web开发者吗?来看看大牛分享的经验吧~ 作为一个软(ku)件(bi)工(de)程(ma)师(nong),你有没有觉得做什么事都没时间?没时间学习新东西,没时间去回顾.整理原来写的烂代 ...
- GCD(欧拉函数)
GCD Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissio ...
- phpstorm2016.3+xdebug调试
1.首先打开PHP配置文件,php.in修改相关xedebug配置 ; XDEBUG Extension [xdebug] zend_extension ="d:/wamp64/bin/ph ...
- flask中使用xlsxwriter导出excel文件
最近需要使用flask导出xlsxwriter生成的excel文件,在文件比较小的情况下,可以直接导出. 首先,这里使用了StringIO,导出使用的模块 import xlsxwriter impo ...