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

ExpandableListView的用法:难点就是重写BaseExpandableListAdapter及提供的数据源。

下面看看继承BaseExpandableListAdapter的适配器:

package com.xyz.expande;
import java.util.List;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
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 ExpandeAdapter extends BaseExpandableListAdapter {
private Context mContext;
private LayoutInflater mInflater = null;
private String[] mGroupStrings = null;
private List<List<Item>> mData = null;
public ExpandeAdapter(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.setBackgroundDrawable(getRoundCornerDrawable(
getChild(groupPosition, childPosition).getImageId(), 10));
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
/* 很重要:实现ChildView点击事件,必须返回true */
return true;
}
private Drawable getRoundCornerDrawable(int resId, float roundPX /* 圆角的半径 */) {
Drawable drawable = mContext.getResources().getDrawable(resId);
int w = mContext.getResources().getDimensionPixelSize(R.dimen.image_width);
int h = w;
Bitmap bitmap = Bitmap
.createBitmap(w,h,
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
drawable.draw(canvas);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Bitmap retBmp = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas can = new Canvas(retBmp);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, width, height);
final RectF rectF = new RectF(rect);
paint.setColor(color);
paint.setAntiAlias(true);
can.drawARGB(0, 0, 0, 0);
can.drawRoundRect(rectF, roundPX, roundPX, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
can.drawBitmap(bitmap, rect, rect, paint);
return new BitmapDrawable(retBmp);
}
private class GroupViewHolder {
TextView mGroupName;
TextView mGroupCount;
}
private class ChildViewHolder {
ImageView mIcon;
TextView mChildName;
TextView mDetail;
}
}

里面用到的有两个布局,GroupView(ChildViewt没展开的情况)如图:  

布局group_item_layout.xml如下:

<?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>

另外一个就是ChildView,本例仿QQ好友列表,如图:

哈哈,熟悉吧。布局child_item_layout.xml如下:

<?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"
android:descendantFocusability="blocksDescendants"
    android:orientation="horizontal" >
<ImageView
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: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>

适配器弄好了,ExpandableListView就用系统的,现在只剩下显示的问题啦

先来几张效果图:

主Activity如下:

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 ExpandeAdapter 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 ExpandeAdapter(this, mData);
mListView.setAdapter(mAdapter);
mListView.setOnChildClickListener(this);
}
/*
* ChildView 设置 布局很可能onChildClick进不来,要在 ChildView layout 里加上
* android:descendantFocusability="blocksDescendants",
* 还有isChildSelectable里返回true
*/
    @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);
}
}

写这个demo的时候,想实现ChildView的点击事件,实现接口onChildClick,发现不进来,很尴尬。。。最后还是在网上找到答案了,第一,在适配器里isChildSelectable 必须返回true,第二,ChildView布局child_item_layout.xml最外层的layout设置个属性:

android:descendantFocusability="blocksDescendants"

上面已标示红色的啦。

细心的同学会发现 Item 是啥?也贴出来吧

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 + "]";
}
}

。。。这不是面向对象程序设计(OOP)类及类的实现最简单的例子么。

有不对的地方请指正,互相学习!(ChildView左边的图片处理成圆角:请看函数getRoundCornerDrawable:具体细节请看:Android --- 图片的特效处理

免分下载源码路径:http://download.csdn.net/detail/zhouyuanjing/4843520

~~完~~

android 实现QQ好友列表(扩展listview:ExpandableListView)相关推荐

  1. Android学QQ聊天列表展示ListView

    Android学QQ聊天列表展示ListView 稍微修改下实现的,比完全copy感觉爽多了 布局文件:activity_main.xml <RelativeLayout xmlns:andro ...

  2. android 仿qq好友列表分组效果及联系人分组效果

     历史记录仿QQ好友列表的动态效果 以及联系人的分组效果 QQ朋友分组的功能做的不错,大家都很认可,那么到底他的分组并且滑动的时候,标题能停留在顶部是如何实现的呢?今天从网上搜索了一下资料,自己运行了 ...

  3. android 实现QQ好友列表

    在某些android开发群里,看到有些新手问怎么实现QQ好友列表,其实网上一搜挺多的.接触Android,也才一年的时间,大部分时间花在工作上(解bug...),界面上开发很少参与.自己维护的系统应用 ...

  4. Android仿QQ好友列表分组实现增删改及持久化

    Android自带的控件ExpandableListView实现了分组列表功能,本案例在此基础上进行优化,为此控件添加增删改分组及子项的功能,以及列表数据的持久化. Demo实现效果:     Dem ...

  5. android获取qq消息列表,2018-03-23—ListView实现QQ消息列表

    把生活的优质寄托于别人,一昧的祈求别人同情和怜悯,短时间可能会有所收获,但随着时间,同情和怜悯最终只会变成反感和厌恶.而真正能够改变自己命运的,只有自己努力. 你若精彩,蝴蝶自来.           ...

  6. Android:仿手机QQ好友动态的ListView

    1.介绍: 本博客使用XListView模仿Android版QQ好友动态的ListView效果.效果截图如下: 效果图1 效果图2 这里面主要涉及的是ListView的布局问题,让我们看一下Item的 ...

  7. Android 仿QQ好友分组列表、ExpandableListView的使用详解

    ListView只能显示一级列表,如果我们需要像QQ好友列表的那样的效果,就需要用到ExpandableListView,入门新手可能对该控件不是很熟悉,下面就详解一下基本用法,其实跟ListView ...

  8. android 仿qq好友动态,Android UI仿QQ好友列表分组悬浮效果

    本文实例为大家分享了Android UI仿QQ好友列表分组悬浮效果的具体代码,供大家参考,具体内容如下 楼主是在平板上測试的.图片略微有点大,大家看看效果就好 接下来贴源代码: PinnedHeade ...

  9. Android中实现类似qq好友列表展开收起的效果

    最近两天学习实现了一个功能,感觉很好,一定要记录下来. 在网上找了一些资料,林林总总,总是不那么齐全,有的代码做成小Demo还会报错,需要自己调试半天.也幸好如此,我将此功能涉及到的一些知识点理解的更 ...

最新文章

  1. Java多线程之阻塞I/O如何中断
  2. 【插件】jQuery.iviewer----图片浏览(滚动放大缩小问题解决)
  3. 网络性能测试工具iperf的使用与参数解析
  4. Kobject结构体分析
  5. mysql修改字段为现在时间_mysql如何修改字段自动生成时间
  6. GDCM:从ELSCINT1读取Wave Information标签的测试程序
  7. 已知两边和夹角求第三边长_数学九年级上册3.4.2节利用两边及夹角判定三角形相似微课视频|知识点...
  8. 【数据结构与算法】之深入解析“零钱兑换”的求解思路与算法示例
  9. 系统设计知识:系统设计的基本原理介绍
  10. 物联网项目:将Arduino连接到Ubidots和Android –第1部分
  11. 轨道坐标系_天文坐标系分类
  12. 三星 SGH-G810 多普达 P800 多普达 Touch Diamond(S900) 多普达 P860 多普达 Touch(T3238) 对比...
  13. Sharepoint学习笔记—Ribbon系列-- 2. 在Ribbon中添加新Tab
  14. axivion和astree_基于LabVIEW的IVI编程 IVI Programme Based on LabVIEW.pdf
  15. MQ详解及四大MQ比较
  16. android无法实例化服务器,android – 无法实例化类型PagerAdapter
  17. php hscan,hgetall 替代 hscan的用法详解。
  18. Linux下安装配置JDK6
  19. 电赛公开课整理(二),电路基础,截图+模电知识【16000字】【原创】
  20. 尚雯婕演唱会上变芭比娃娃

热门文章

  1. Unirech:阿里云国际版账户无法登陆,为什么账户会被风控?
  2. c语言报错(二)expected initializer before “int“
  3. 用 HealthKit 来开发一个健身 App
  4. opencv VideoWriter保存摄像头视频、本地视频等
  5. 学术应用使用node-http-proxy集成谷歌学术
  6. 关于基线长度对双天线GNSS测姿精度的影响
  7. [乐意黎原创]Win10 升级1909版本后,内存占用率居高不下的解决办法
  8. 美国劳工部揭露中国女人大数据,看完彻底傻眼了(文末有福利)
  9. (H5)canvas实现裁剪图片和马赛克功能,以及又拍云上传图片
  10. rest php,prest