在某些Android开发群里,看到有些新手问怎么实现QQ好友列表,其实网上一搜挺多的。接触Android,也才一年的时间,大部分时间花在工作上(解bug。。。),界面上开发很少参与。自己维护的系统应用里,有个ExpandableListView的界面(其实android例子APIDemo也有类似的例子)就在这里写个Demo供新手参考。 ExpandableListView的用法:难点就是重写BaseExpandableListAdapter及提供的数据源。
下面看看继承BaseExpandableListAdapter的适配器:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
<SPAN xmlns=
"http://www.w3.org/1999/xhtml"
>
package
com.xyz.expande;
import
java.util.List;
import
android.app.AlertDialog;
import
android.content.Context;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.view.ViewGroup;
import
android.widget.BaseExpandableListAdapter;
import
android.widget.ImageView;
import
android.widget.TextView;
public
class
ExpandAdapter
extends
BaseExpandableListAdapter {
private
Context mContext;
private
LayoutInflater mInflater =
null
;
private
String[] mGroupStrings =
null
;
private
List<List<Item>> mData =
null
;
public
ExpandAdapter(Context ctx, List<List<Item>> list) {
mContext = ctx;
mInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mGroupStrings = mContext.getResources().getStringArray(R.array.groups);
mData = list;
}
public
void
setData(List<List<Item>> list) {
mData = list;
}
@Override
public
int
getGroupCount() {
// TODO Auto-generated method stub
return
mData.size();
}
@Override
public
int
getChildrenCount(
int
groupPosition) {
// TODO Auto-generated method stub
return
mData.get(groupPosition).size();
}
@Override
public
List<Item> getGroup(
int
groupPosition) {
// TODO Auto-generated method stub
return
mData.get(groupPosition);
}
@Override
public
Item getChild(
int
groupPosition,
int
childPosition) {
// TODO Auto-generated method stub
return
mData.get(groupPosition).get(childPosition);
}
@Override
public
long
getGroupId(
int
groupPosition) {
// TODO Auto-generated method stub
return
groupPosition;
}
@Override
public
long
getChildId(
int
groupPosition,
int
childPosition) {
// TODO Auto-generated method stub
return
childPosition;
}
@Override
public
boolean
hasStableIds() {
// TODO Auto-generated method stub
return
false
;
}
@Override
public
View getGroupView(
int
groupPosition,
boolean
isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if
(convertView ==
null
) {
convertView = mInflater.inflate(R.layout.group_item_layout,
null
);
}
GroupViewHolder holder =
new
GroupViewHolder();
holder.mGroupName = (TextView) convertView
.findViewById(R.id.group_name);
holder.mGroupName.setText(mGroupStrings[groupPosition]);
holder.mGroupCount = (TextView) convertView
.findViewById(R.id.group_count);
holder.mGroupCount.setText(
"["
+ mData.get(groupPosition).size() +
"]"
);
return
convertView;
}
@Override
public
View getChildView(
int
groupPosition,
int
childPosition,
boolean
isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if
(convertView ==
null
) {
convertView = mInflater.inflate(R.layout.child_item_layout,
null
);
}
ChildViewHolder holder =
new
ChildViewHolder();
holder.mIcon = (ImageView) convertView.findViewById(R.id.img);
holder.mIcon.setBackgroundResource(getChild(groupPosition,
childPosition).getImageId());
holder.mChildName = (TextView) convertView.findViewById(R.id.item_name);
holder.mChildName.setText(getChild(groupPosition, childPosition)
.getName());
holder.mDetail = (TextView) convertView.findViewById(R.id.item_detail);
holder.mDetail.setText(getChild(groupPosition, childPosition)
.getDetail());
return
convertView;
}
@Override
public
boolean
isChildSelectable(
int
groupPosition,
int
childPosition) {
// TODO Auto-generated method stub
<SPAN style=
"COLOR: #cc0000"
>
/*很重要:实现ChildView点击事件,必须返回true*/
</SPAN>
return
true
;
}
private
class
GroupViewHolder {
TextView mGroupName;
TextView mGroupCount;
}
private
class
ChildViewHolder {
ImageView mIcon;
TextView mChildName;
</LinearLayout></SPAN></SPAN>
|
TextView mDetail;
}
}
</SPAN>[/mw_shl_code]
里面用到的有两个布局,GroupView(子list没展开的view)如图:
<IGNORE_JS_OP>
布局group_item_layout.xml如下:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<SPAN xmlns=
"http://www.w3.org/1999/xhtml"
><SPAN xmlns=
"http://www.w3.org/1999/xhtml"
><?xml version=
"1.0"
encoding=
"utf-8"
?>
<LinearLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"?android:attr/listPreferredItemHeight"
android:orientation=
"horizontal"
>
<TextView
android:id=
"@+id/group_name"
android:layout_width=
"wrap_content"
android:layout_height=
"?android:attr/listPreferredItemHeight"
android:textAppearance=
"?android:attr/textAppearanceMedium"
android:layout_marginLeft=
"35dip"
android:gravity=
"center_vertical"
android:singleLine=
"true"
/>
<TextView
android:id=
"@+id/group_count"
android:layout_width=
"wrap_content"
android:layout_height=
"?android:attr/listPreferredItemHeight"
android:textAppearance=
"?android:attr/textAppearanceMedium"
android:layout_marginLeft=
"5dip"
android:gravity=
"center_vertical"
android:singleLine=
"true"
/>
</LinearLayout></SPAN></SPAN>
|
另外一个就是ChildView,本例仿QQ好友列表,如图:
<IGNORE_JS_OP>
布局child_item_layout.xml如下:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
<SPAN xmlns=
"http://www.w3.org/1999/xhtml"
><SPAN xmlns=
"http://www.w3.org/1999/xhtml"
><?xml version=
"1.0"
encoding=
"utf-8"
?>
<LinearLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:minHeight=
"@dimen/min_Height"
<SPAN style=
"COLOR: #ff0000"
>android:descendantFocusability=
"blocksDescendants"
</SPAN> android:orientation=
"horizontal"
>
<ImageButton
android:id=
"@+id/img"
android:layout_width=
"@dimen/image_width"
android:layout_height=
"@dimen/image_width"
android:layout_marginLeft=
"2dip"
android:layout_marginRight=
"10dip"
android:layout_gravity=
"center_vertical"
/>
<LinearLayout
android:layout_width=
"wrap_content"
android:layout_height=
"match_parent"
android:descendantFocusability=
"blocksDescendants"
android:orientation=
"vertical"
>
<TextView
android:id=
"@+id/item_name"
android:layout_width=
"wrap_content"
android:layout_height=
"0.0dip"
android:gravity=
"center_vertical"
android:layout_weight=
"1"
/>
<TextView
android:id=
"@+id/item_detail"
android:layout_width=
"wrap_content"
android:layout_height=
"0.0dip"
android:gravity=
"center_vertical"
android:singleLine=
"true"
android:ellipsize=
"end"
android:layout_weight=
"1"
/>
</LinearLayout>
</LinearLayout></SPAN></SPAN>
|
适配器弄好了,ExpandableListView就用系统的,现在只剩下显示的问题啦
先来几张效果图:
<IGNORE_JS_OP>
<IGNORE_JS_OP>
<IGNORE_JS_OP>
<IGNORE_JS_OP>
主Activity如下:
onChildClick
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
<SPAN xmlns=
"http://www.w3.org/1999/xhtml"
><SPAN xmlns=
"http://www.w3.org/1999/xhtml"
>
package
com.xyz.expande;
import
java.util.ArrayList;
import
java.util.List;
import
android.app.Activity;
import
android.app.AlertDialog;
import
android.content.DialogInterface;
import
android.content.DialogInterface.OnClickListener;
import
android.os.Bundle;
import
android.view.View;
import
android.view.ViewGroup.LayoutParams;
import
android.widget.ExpandableListView;
import
android.widget.ExpandableListView.OnChildClickListener;
public
class
HomeActivity
extends
Activity
implements
OnChildClickListener {
private
ExpandableListView mListView =
null
;
private
ExpandAdapter mAdapter =
null
;
private
List<List<Item>> mData =
new
ArrayList<List<Item>>();
private
int
[] mGroupArrays =
new
int
[] {
R.array.tianlongbabu,
R.array.shediaoyingxiongzhuan,
R.array.shendiaoxialv };
private
int
[] mDetailIds =
new
int
[] {
R.array.tianlongbabu_detail,
R.array.shediaoyingxiongzhuan_detail,
R.array.shendiaoxialv_detail };
private
int
[][] mImageIds =
new
int
[][] {
{ R.drawable.img_00,
R.drawable.img_01,
R.drawable.img_02 },
{ R.drawable.img_10,
R.drawable.img_11,
R.drawable.img_12,
R.drawable.img_13,
R.drawable.img_14,
R.drawable.img_15,
R.drawable.img_16 },
{ R.drawable.img_20,
R.drawable.img_21 } };
/** Called when the activity is first created. */
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
initData();
mListView =
new
ExpandableListView(
this
);
mListView.setLayoutParams(
new
LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
setContentView(mListView);
mListView.setGroupIndicator(getResources().getDrawable(
R.drawable.expander_floder));
mAdapter =
new
ExpandAdapter(
this
, mData);
mListView.setAdapter(mAdapter);
mListView
.setDescendantFocusability(ExpandableListView.FOCUS_AFTER_DESCENDANTS);
mListView.setOnChildClickListener(
this
);
}
<SPAN style=
"COLOR: #ff0000"
>
/*
* ChildView 设置 布局很可能onChildClick进不来,要在 ChildView layout 里加上
* android:descendantFocusability="blocksDescendants",
* 还有isChildSelectable里返回true
*/
</SPAN>
@Override
public
boolean
onChildClick(ExpandableListView parent, View v,
int
groupPosition,
int
childPosition,
long
id) {
// TODO Auto-generated method stub
Item item = mAdapter.getChild(groupPosition, childPosition);
new
AlertDialog.Builder(
this
)
.setTitle(item.getName())
.setMessage(item.getDetail())
.setIcon(android.R.drawable.ic_menu_more)
.setNegativeButton(android.R.string.cancel,
new
OnClickListener() {
@Override
public
void
onClick(DialogInterface dialog,
int
which) {
// TODO Auto-generated method stub
}
}).create().show();
return
true
;
}
private
void
initData() {
for
(
int
i =
0
; i < mGroupArrays.length; i++) {
List<Item> list =
new
ArrayList<Item>();
String[] childs = getStringArray(mGroupArrays<I>);
String[] details = getStringArray(mDetailIds<I>);
for
(
int
j =
0
; j < childs.length; j++) {
Item item =
new
Item(mImageIds<I>[j], childs[j], details[j]);
list.add(item);
}
mData.add(list);
}
}
private
String[] getStringArray(
int
resId) {
return
getResources().getStringArray(resId);
}
}</SPAN></SPAN>
|
这这个demo的时候,想实现ChildView的点击事件,实现接口onChildClick,发现不进来,很尴尬。。。最后还是在网上找到答案了,第一,在适配器里isChildSelectable 必须返回true,第二,ChildView布局child_item_layout.xml最外层的layout设置个属性
细心的同学会发现 Item 是啥?也贴出来吧
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
package
com.xyz.expande;
public
class
Item {
private
int
resId;
private
String name;
private
String detail;
public
Item(
int
resId, String name, String detail) {
this
.resId = resId;
this
.name = name;
this
.detail = detail;
}
public
void
setImageId(
int
resId) {
this
.resId = resId;
}
public
int
getImageId() {
return
resId;
}
public
void
setName(String name) {
this
.name = name;
}
public
String getName() {
return
name;
}
public
void
setDetail(String detail) {
this
.detail = detail;
}
public
String getDetail() {
return
detail;
}
public
String toString() {
return
"Item["
+ resId +
", "
+ name +
", "
+ detail +
"]"
;
}
}
|
源码下载: <IGNORE_JS_OP>
ExpandeList.zip (670.11 KB, 下载次数: 988)
http://www.eoeandroid.com/forum.php?mod=misc&action=attachcredit&aid=81469&formhash=2f2ef89c
原文:http://blog.csdn.net/zhouyuanjing/article/details/8254421
