开发者社区> 云栖-lxl> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

android 实现QQ好友列表

简介: 在某些Android开发群里,看到有些新手问怎么实现QQ好友列表,其实网上一搜挺多的。接触Android,也才一年的时间,大部分时间花在工作上(解bug。。。),界面上开发很少参与。自己维护的系统应用里,有个ExpandableListView的界面(其实android例子APIDemo也有类似的例子)就在这里写个Demo供新手参考。
+关注继续查看

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

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Android弹幕实现:基于B站弹幕开源系统(3)-文本弹幕的完善和细节调整
 Android弹幕实现:基于B站弹幕开源系统(3) 本文在附录1,2的基础上再次对异步获取弹幕并显示弹幕完善逻辑和代码,集中在上层Java代码部分: package zhangphil.
879 0
【Android 应用开发】Android开发技巧--Application, ListView排列,格式化浮点数,string.xml占位符,动态引用图片
【Android 应用开发】Android开发技巧--Application, ListView排列,格式化浮点数,string.xml占位符,动态引用图片
155 0
Android大数据、断点续传、耗时下载之DownloadManager开发简介(1)
 Android大数据、断点续传、耗时下载之DownloadManager开发简介(1) Android涉及到的网络数据请求,如果是零星数据、且数据量较小(几十KB到几百KB,1MB以内),一般的,可以自己使用Android原生HTTP或者第三方开源框架如Volley(相关文章:http://blog.
935 0
Android开发重要参考资料
=======================博客============================= 秋百万 有心课堂 郭霖 源码 安装ffmpeg 胡凯 官方培训课程 litesuitsway 爱哥 trinea robinRobin Hu...
850 0
+关注
云栖-lxl
java程序员
文章
问答
文章排行榜
最热
最新
相关电子书
更多
手机卫士性能优化方案-Android篇
立即下载
《深入探索Android热修复技术原理》
立即下载
《深入探索Android热修复技术原理》电子书
立即下载