首先我們還是來看一些案例,還是拿搜狐新聞用戶端,因為我天天上下班沒事愛看這個東東,上班又沒時間看新聞,上下班路途之餘浏覽下新聞打發時間嘛.

看這個效果挺棒吧,其實實作起來也不難,我簡單說明下.
首先我們用到的控件是: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了.
嗯,效果還可以吧,就介紹這麼多了,如有問題或好的建議請吉留言.