在某些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>

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

2012-12-4 17:23 上传

点击文件名下载附件
下载积分: e币 -10 元

 

http://www.eoeandroid.com/forum.php?mod=misc&action=attachcredit&aid=81469&formhash=2f2ef89c

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

android 实现QQ好友列表的更多相关文章

  1. iOS开发UI篇—使用UItableview完成一个简单的QQ好友列表(一)

    iOS开发UI篇—使用UItableview完成一个简单的QQ好友列表(一) 一.项目结构和plist文件 二.实现代码 1.说明: 主控制器直接继承UITableViewController // ...

  2. [iOS基础控件 - 6.9.3] QQ好友列表Demo TableView

    A.需求 1.使用plist数据,展示类似QQ好友列表的分组.组内成员显示缩进功能 2.组名使用Header,展示箭头图标.组名.组内人数和上线人数 3.点击组名,伸展.缩回好友组   code so ...

  3. 仿QQ好友列表界面的实现

    TableView有2种style:UITableViewStylePlain 和 UITableViewStyleGrouped. 但是QQ好友列表的tableView给人的感觉似乎是2个style ...

  4. ExpandableListView仿QQ好友列表

    本例中,对ExpandableListView中的数据进行了封装,分为两个JavaBean,一个为Group类表示组信息,一个Child类表示该组下子列表信息: Group: public class ...

  5. (二十七)QQ好友列表的实现

    QQ好友列表通过plist读取,plist的结构为一组字典,每个字典内有本组的信息和另外一组字典代表好友. 要读取plist,选择合适的数据结构,例如NSArray,然后调用initWithConte ...

  6. 基于Qt的相似QQ好友列表抽屉效果的实现

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/shuideyidi/article/details/30619167     前段时间在忙毕业设计, ...

  7. swift 实现QQ好友列表功能

    最近项目中有类似QQ好友列表功能,整理了一下,话不多说,直接上代码 import UIKit class QQFriend: NSObject { var name: String? var intr ...

  8. Windows UIA自动化测试框架学习--获取qq好友列表

    前段时间应公司要求开发一款针对现有WPF程序的自动化测试工具,在网上查资料找了一段时间,发现用来做自动化测试的框架还是比较多的,比如python的两个模块pywinauto和uiautomation, ...

  9. OS开发UI篇—使用UItableview完成一个简单的QQ好友列表

    本文转自:http://www.cnblogs.com/wendingding/p/3763330.html 一.项目结构和plist文件 二.实现代码 1.说明: 主控制器直接继承UITableVi ...

随机推荐

  1. hdu 2121

    朱刘算法求无根最小树形图 可以任意选一个根,求最小的权和以及当时的根. 先建一个超级根,它连向所有点,边权为所有边的边权和加1(即sumw+1),然后求以它为根的最小树形图,再根据树形图权和与2*(s ...

  2. MySQL规约(阿里巴巴)

    建表规约 [强制]表达是与否概念的字段,必须使用 is _ xxx 的方式命名,数据类型是 unsigned tinyint ( 1 表示是,0 表示否 ) ,此规则同样适用于 odps 建表. 说明 ...

  3. HDU 4267 A Simple Problem with Integers 多个树状数组

    A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  4. Date与String间的转换

    一.Date-->String :格式化过程 1. DateFormat :String format(Date d) 2.SimpleDateFormat是继承DateFormat(抽象类)的 ...

  5. 从零开始搭建linux下laravel 5.5所需环境(三)

    好的,我们已经安装好了nginx+mysql+php了,打开[ Laravel 5.5 文档 ] 快速入门 —— 安装配置篇 我们看到这里需要安装Composer,好的,我们现在就来安装Compose ...

  6. [转载] MFC绘制动态曲线,用双缓冲绘图技术防闪烁

    转载的原文地址 先上效果图 随着时间的推移,曲线向右平移,同时X轴的时间坐标跟着更新. 一.如何绘制动态曲线 所谓动画,都是一帧一帧的图像连续呈现在用户面前形成的.所以如果你掌握了如何绘制静态曲线,那 ...

  7. 2) broadcast,这是启动完毕之后,集群中的服务器开始接收客户端的连接一起工作的过程,如果客户端有修改数据的改动,那么一定会由leader广播给follower,所以称为”broadcast”.

    2) broadcast,这是启动完毕之后,集群中的服务器开始接收客户端的连接一起工作的过程,如果客户端有修改数据的改动,那么一定会由leader广播给follower,所以称为”broadcast” ...

  8. 使用Redis实现抢购的一种思路(list队列实现)

    原文:https://my.oschina.net/chinaxy/blog/1829233 抢购是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如 ...

  9. 扩展redisTemplate实现分布式锁

    原文:https://blog.csdn.net/qq1010267837/article/details/79697572 依赖jar包 compile group: 'redis.clients' ...

  10. android中PopupMenu的使用

    PopupMenu可以非常方便的在指定view的下面显示一个弹出菜单,类似于actionbar溢出菜单的效果.它的菜单选项可以来自于menu资源,因此非常方便.下面是在网上找的一个PopupMenu的 ...