博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android 实现QQ好友列表
阅读量:7194 次
发布时间:2019-06-29

本文共 11967 字,大约阅读时间需要 39 分钟。

在某些群里,看到有些新手问怎么实现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>

1354586842_7926.png (28.18 KB, 下载次数: 3)

 

2012-12-4 17:17 上传

 

布局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>

1354587095_4168.png (53.2 KB, 下载次数: 4)

 

2012-12-4 17:19 上传

 

布局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>

1354587948_2449.png (256.92 KB, 下载次数: 2)

 

2012-12-4 17:20 上传

 

    <IGNORE_JS_OP>

1354587973_5081.png (327.25 KB, 下载次数: 7)

 

2012-12-4 17:21 上传

 

<IGNORE_JS_OP>

1354587996_4188.png (305.77 KB, 下载次数: 0)

 

2012-12-4 17:21 上传

 

   <IGNORE_JS_OP>

1354588011_1830.png (174.7 KB, 下载次数: 0)

 

2012-12-4 17:21 上传

 

主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> (670.11 KB, 下载次数: 988)

2012-12-4 17:23 上传
点击文件名下载附件
下载积分: e币 -10 元
 

原文:http://blog.csdn.net/zhouyuanjing/article/details/8254421

你可能感兴趣的文章
Linux:用gcc编译为32位程序
查看>>
教你如何实现android上的九点连线锁
查看>>
学习数组的代码
查看>>
java学习笔记第一章
查看>>
基础控件之UIButton.UIImageView基本属性与方法概览
查看>>
TYVJ P3522 &&洛谷 P1135 奇怪的电梯 Label:bfs
查看>>
C# 会可能需要的扩展
查看>>
彻底卸载Oracle
查看>>
bzoj2434
查看>>
银联支付集成之 ---- 安卓
查看>>
递归函数打印斐波那契数列
查看>>
rabbitmq的简单介绍二
查看>>
go语言之指针
查看>>
浅谈Cocos2d-js ListView滑动防止误触
查看>>
当、你想给一个目标挂上一个事件时
查看>>
模板:树链剖分
查看>>
JQ和Js获取span标签的内容
查看>>
8. java操作mongodb——查询数据
查看>>
NHProfiler使用方法
查看>>
《C和指针》读书笔记 第3章-数据
查看>>