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

看这个效果挺棒吧,其实实现起来也不难,我简单说明下.
首先我们用到的控件是:expandablelistview
布局文件:
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!--
android:groupindicator="@null" 取消默认图片
android:childindicatorleft 设置孩子左边间距
android:dividerheight 这个高度一定要设置,不然显示不出来分割线,估计默认为0 吧
android:childdivider="@drawable/child_bg" 这个直接引color,或者图片会导致整个孩子背景都为这个颜色 ,不知道原因,如果有谁知道,请give me say.
-->
<expandablelistview
android:id="@+id/expandablelist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cachecolorhint="@null"
android:childdivider="@drawable/child_bg"
android:childindicatorleft="0dp"
android:divider="@color/grey"
android:dividerheight="1dp"
android:groupindicator="@null"
android:scrollbaralwaysdrawhorizontaltrack="true" >
</expandablelistview>
</relativelayout>
myexpandablelistadapter.java
/***
* 数据源
*
* @author administrator
*/
class myexpandablelistadapter extends baseexpandablelistadapter {
private context context;
private layoutinflater inflater;
public myexpandablelistadapter(context context) {
this.context = context;
inflater = layoutinflater.from(context);
}
// 返回父列表个数
@override
public int getgroupcount() {
return grouplist.size();
// 返回子列表个数
public int getchildrencount(int groupposition) {
return childlist.get(groupposition).size();
public object getgroup(int groupposition) {
return grouplist.get(groupposition);
public object getchild(int groupposition, int childposition) {
return childlist.get(groupposition).get(childposition);
public long getgroupid(int groupposition) {
return groupposition;
public long getchildid(int groupposition, int childposition) {
return childposition;
public boolean hasstableids() {
return true;
public view getgroupview(int groupposition, boolean isexpanded,
view convertview, viewgroup parent) {
groupholder groupholder = null;
if (convertview == null) {
groupholder = new groupholder();
convertview = inflater.inflate(r.layout.group, null);
groupholder.textview = (textview) convertview
.findviewbyid(r.id.group);
groupholder.imageview = (imageview) convertview
.findviewbyid(r.id.image);
groupholder.textview.settextsize(15);
convertview.settag(groupholder);
} else {
groupholder = (groupholder) convertview.gettag();
}
groupholder.textview.settext(getgroup(groupposition).tostring());
if (isexpanded)// ture is expanded or false is not isexpanded
groupholder.imageview.setimageresource(r.drawable.expanded);
else
groupholder.imageview.setimageresource(r.drawable.collapse);
return convertview;
public view getchildview(int groupposition, int childposition,
boolean islastchild, view convertview, viewgroup parent) {
convertview = inflater.inflate(r.layout.item, null);
textview textview = (textview) convertview.findviewbyid(r.id.item);
textview.settextsize(13);
textview.settext(getchild(groupposition, childposition).tostring());
public boolean ischildselectable(int groupposition, int childposition) {
}
@override
public boolean ongroupclick(final expandablelistview parent, final view v,
int groupposition, final long id) {
return false;
上面实现起来比较简单.相信对listview熟悉的朋友看这个一定很熟悉,无外乎就是多了个孩子.
selector_group.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/grey" android:state_pressed="true"></item>
<item android:drawable="@color/grey" android:state_selected="true"></item>
<item android:drawable="@color/lightgray"></item>
</selector>
selector_item.xml 同理.
效果图:
效果虽然丑了点,不过就是这么回事,至于显示group的item,还是孩子的item,你可以随意定制.
不想敲的同学,可以下载源码,稍作调整.
/********************************listview模拟expandablelistview**************************************************************/
下面我们接着看一些案例:
其实就是:点击listview的一个item,展开其孩子,点击另一个item,打开其孩子,关闭之前那个孩子.
这个眨一看是expandablelistview这个东东,可是本人比较笨戳,整了好久没有弄出来,最终放弃,google下,发现有人用listview来模拟实现,也就跟着做了下.
布局文件:(后面多个隐藏text.)
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:background="@color/white"
android:gravity="center_vertical"
android:orientation="vertical" >
<relativelayout
android:layout_height="wrap_content"
android:background="@drawable/selector_group"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="5dp" >
<textview
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centervertical="true"
android:textcolor="@color/black" />
<imageview
android:id="@+id/image"
android:layout_alignparentright="true"
android:src="@drawable/collapse" />
</relativelayout>
<textview
android:id="@+id/hint_item"
android:layout_width="fill_parent"
android:padding="10dp"
android:textcolor="@color/black"
android:visibility="gone" />
</linearlayout>
myadpter.java
* @author zhangjia
class myadpter extends baseadapter {
private int change_index = -1;// 改变项
public myadpter(context context) {
super();
inflater = (layoutinflater) context
.getsystemservice(context.layout_inflater_service);
public int getcount() {
public object getitem(int position) {
return grouplist.get(position);
public long getitemid(int position) {
return position;
public view getview(int position, view convertview, viewgroup parent) {
groupholder.hint_item = (textview) convertview
.findviewbyid(r.id.hint_item);
groupholder.textview.settext(grouplist.get(position));
groupholder.hint_item.settext(childlist.get(position));
if (change_index == position)
groupholder.hint_item.setvisibility(view.visible);
groupholder.hint_item.setvisibility(view.gone);
/***
* 这个方法用于更改子item的状态
*/
public void changeimagevisable(view view, int position) {
// 隐藏提示
if (change_index == position) {
groupholder groupholder = (groupholder) view.gettag();
if (groupholder.hint_item.getvisibility() == view.visible)
groupholder.hint_item.setvisibility(view.gone);
else
groupholder.hint_item.setvisibility(view.visible);
change_index = position;
notifydatasetchanged();// restart getview
这个数据源很简单,只是多了个用于控制孩子隐藏与显示的方法changeimagevisable.代码很简单,相信不用过多解释.
效果:
上面模拟显示的孩子是一个textview(缺点:隐藏textview显示时候点击会影响到其父控件,大家尝试一下,不过肯定有解决办法的.),
下面我来介绍下,如果孩子是listview应该怎么办.
首先配置文件:
<!-- android:descendantfocusability="blocksdescendants"这个属性就可以让父listview获取焦点 -->
android:descendantfocusability="blocksdescendants"
android:text="精品推荐"
<listview
android:textcolor="@color/black" />
* initdata
*/
void initdata() {
grouplist = new arraylist<string>();
grouplist.add("ios");
grouplist.add("android");
grouplist.add("window");
childlist = new arraylist<arraylist<string>>();
for (int i = 0; i < grouplist.size(); i++) {
arraylist<string> childtemp;
if (i == 0) {
childtemp = new arraylist<string>();
childtemp.add("iphone 4");
childtemp.add("iphone 5");
} else if (i == 1) {
childtemp.add("anycall");
childtemp.add("htc");
childtemp.add("motorola");
} else {
childtemp.add("lumia 800c ");
childlist.add(childtemp);
}
* 父数据源
public view getview(final int position, view convertview,
viewgroup parent) {
convertview = inflater.inflate(r.layout.group_item, null);
groupholder.hint_item = (listview) convertview
groupholder.hint_item.setadapter(getlistview(childlist
.get(position)));
groupholder.hint_item
.setonitemclicklistener(new onitemclicklistener() {
@override
public void onitemclick(adapterview<?> parent,
view view, int position_id, long id) {
toast.maketext(context,
childlist.get(position).get(position_id), 1)
.show();
}
});
// 动态设置listview 的高度
setlistviewheightbaseonchildren(groupholder.hint_item);
else {
上面代码和刚才的差不多,唯一需要我们注意的是“listview嵌套listview,我们需要注意哪些问题”.
第一:listview和listview嵌套,子listview只显示一个多一点点,不能正常显示,解决办法:对listview重新设置起高度.(相信同学们对这个方法一点也不陌生.)
* 动态设置listview的高度
* @param listview
public void setlistviewheightbaseonchildren(listview listview) {
listadapter listadapter = listview.getadapter();
if (listadapter == null)
return;
int totalheight = 0;// 总高度
for (int i = 0; i < listadapter.getcount(); i++) {
view listitem = listadapter.getview(i, null, listview);
listitem.measure(0, 0);
totalheight += listitem.getmeasuredheight();
int totaldividerheight = 0;
totaldividerheight = listview.getdividerheight()
* (listadapter.getcount() - 1);
viewgroup.layoutparams layoutparams = listview.getlayoutparams();
layoutparams.height = totalheight + totaldividerheight;
listview.setlayoutparams(layoutparams);
第二个问题:listview 嵌套listview的时候,子listview会屏蔽掉父listview的焦点.使得父listview无法点击.
解决办法很简单:我们只需要在父listview的adapter里面的配置文件最顶部的如linearlayout加入一行: android:descendantfocusability="blocksdescendants"就ok了.
嗯,效果还可以吧,就介绍这么多了,如有问题或好的建议请吉留言.