前段时间跟大家分享了ExpandableListView的使用,不知道的童鞋,可以去这里看一下:http://blog.csdn.net/weidi1989/article/details/7995552
但是我最近做那个QQ项目是遇到一个问题,如果给这个ExpandableListView添加动态从网上获取的数据呢?前面跟大家分享的时候,是用了静态的数据,很好处理。大组跟小组就类似于一个一维数组和二维数组,但我们从服务器获取的数据可能并不是这样!比如我做的这个QQ从服务器获取的就是一个List<User>,这么一个用户数组,那些分组信息都包含在每个用户之中,像这样的数据又该如何添加到适配器里面呢?好了,下面跟大家分享一下我的处理办法。先看一张效果图,有图有真相,哈哈:

下面是对应好友在数据库中的分组,自己本人默认为在第一组。QQ好像也是这么处理的

先看一下我们自定义的适配器代码,看看需要什么样的数据,然后根据需求,传递对应的数据。
/**
* 自定义ExpandableListView的适配器
*
* @author way
*
*/
public class MyExAdapter extends BaseExpandableListAdapter {
private int[] imgs = { R.drawable.icon, R.drawable.f1, R.drawable.f2,
R.drawable.f3, R.drawable.f4, R.drawable.f5, R.drawable.f6,
R.drawable.f7, R.drawable.f8, R.drawable.f9 };// 头像资源数组
private Context context;
private List<GroupFriend> group;// 传递过来的经过处理的总数据
public MyExAdapter(Context context, List<GroupFriend> group) {
super();
this.context = context;
this.group = group;
}
// 得到大组成员的view
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.member_listview, null);
}
TextView title = (TextView) convertView.findViewById(R.id.content_001);
title.setText(getGroup(groupPosition).toString());// 设置大组成员名称
ImageView image = (ImageView) convertView.findViewById(R.id.tubiao);// 是否展开大组的箭头图标
if (isExpanded)// 大组展开时的箭头图标
image.setBackgroundResource(R.drawable.group_unfold_arrow);
else
// 大组合并时的箭头图标
image.setBackgroundResource(R.drawable.group_fold_arrow);
return convertView;
}
// 得到大组成员的id
public long getGroupId(int groupPosition) {
return groupPosition;
}
// 得到大组成员名称
public Object getGroup(int groupPosition) {
return group.get(groupPosition).getGroupName();
}
// 得到大组成员总数
public int getGroupCount() {
return group.size();
}
// 得到小组成员的view
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.item, null);
}
final TextView title = (TextView) convertView
.findViewById(R.id.name_item);// 显示用户名
final TextView title2 = (TextView) convertView
.findViewById(R.id.id_item);// 显示用户id
ImageView icon = (ImageView) convertView
.findViewById(R.id.imageView_item);// 显示用户头像,其实还可以判断是否在线,选择黑白和彩色头像,我这里未处理,没资源,呵呵
final String name = group.get(groupPosition).getChild(childPosition)
.getName();
final String id = group.get(groupPosition).getChild(childPosition)
.getId()
+ "";
final int img = group.get(groupPosition).getChild(childPosition)
.getImg();
title.setText(name);// 大标题
title2.setText(id);// 小标题
icon.setImageResource(imgs[img]);
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 下面是添加到最近会话列表处理
RecentChatEntity entity = new RecentChatEntity(img, 0, name,
MyDate.getDateEN(), "");
FriendListActivity.mRecentList.add(entity);
FriendListActivity.mRecentAdapter = new RecentChatAdapter(
context, FriendListActivity.mRecentList);
FriendListActivity.mRecentListView
.setAdapter(FriendListActivity.mRecentAdapter);
// 下面是切换到聊天界面处理
User u = new User();
u.setName(name);
u.setId(Integer.parseInt(id));
u.setImg(img);
Intent intent = new Intent(context, ChatActivity.class);
intent.putExtra("user", u);
context.startActivity(intent);
// Toast.makeText(Tab2.this, "开始聊天", 0).show();
}
});
return convertView;
}
// 得到小组成员id
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
// 得到小组成员的名称
public Object getChild(int groupPosition, int childPosition) {
return group.get(groupPosition).getChild(childPosition);
}
// 得到小组成员的数量
public int getChildrenCount(int groupPosition) {
return group.get(groupPosition).getChildSize();
}
/**
* Indicates whether the child and group IDs are stable across changes to
* the underlying data. 表明大組和小组id是否稳定的更改底层数据。
*
* @return whether or not the same ID always refers to the same object
* @see Adapter#hasStableIds()
*/
public boolean hasStableIds() {
return true;
}
// 得到小组成员是否被选择
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
/**
* 这个方法是我自定义的,用于下拉刷新好友的方法
*
* @param group
* 传递进来的新数据
*/
public void updata(List<GroupFriend> group) {
this.group = null;
this.group = group;
}
}
从自定义适配器可以看出,需要一个List<GroupFriend>,这实际上也是我自定义的一个对象GroupFriend数组,为了方便处理,我把大组成员以及每个大组对应的小组成员都封装到GroupFriend这个对象中,下面我们来看一下GroupFriend的这个对象代码:
/**
* 自定义的GroupFriend对象,用来封装大组名称和分配对应的数据
*
* @author way
*
*/
public class GroupFriend {
private String groupName;// 大组名称
private List<User> groupChild;// 对应大组的小组成员对象数组
public GroupFriend() {
super();
}
public GroupFriend(String groupName, List<User> groupChild) {
super();
this.groupName = groupName;
this.groupChild = groupChild;
}
public void add(User u) {// 往小组中添加用户
groupChild.add(u);
}
public void remove(User u) {// 根据用户对象移除用户
groupChild.remove(u);
}
public void remove(int index) {// 根据下标移除用户
groupChild.remove(index);
}
public int getChildSize() {// 小组的大小
return groupChild.size();
}
public User getChild(int index) {// 根据下标得到用户
return groupChild.get(index);
}
// get...set...
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public List<User> getGroupChild() {
return groupChild;
}
public void setGroupChild(List<User> groupChild) {
this.groupChild = groupChild;
}
}
好了,适配都根据我们的需求整完了,下面我们就处理一下服务器传递过来的List<User>对象(代码出自我的QQ项目中,我这里只截取其中重要的一部分):
private List<GroupFriend> group;//需要传递给适配器的数据
private String[] groupName = { "我的好友", "我的同学", "我的家人" };// 大组成员名
/**
* 处理服务器传递过来的用户数组数据,
*
* @param list
* 从服务器获取的用户数组
*/
private void initListViewData(List<User> list) {
group = new ArrayList<GroupFriend>();// 实例化
for (int i = 0; i < groupName.length; ++i) {// 根据大组的数量,循环给各大组分配成员
List<User> child = new ArrayList<User>();// 装小组成员的list
GroupFriend groupInfo = new GroupFriend(groupName[i], child);// 我们自定义的大组成员对象
for (User u : list) {
if (u.getGroup() == i)// 判断一下是属于哪个大组
child.add(u);
}
group.add(groupInfo);// 把自定义大组成员对象放入一个list中,传递给适配器
}
}
经过这个数据加工厂后生成的List<GroupFriend>,我们就可以用来实例化适配器对象了:
// 下面是处理好友列表界面处理
myListView = (MyListView) lay2.findViewById(R.id.tab2_listView);//获取我们自定义的可以下拉刷新的ListView对象
myExAdapter = new MyExAdapter(this, group);//实例化适配器
myListView.setAdapter(myExAdapter);//为我们自定义的ListView设置适配器
myListView.setGroupIndicator(null);// 不设置大组指示器图标,因为我们自定义设置了
myListView.setDivider(null);// 设置图片可拉伸的
myListView.setFocusable(true);// 聚焦才可以下拉刷新
myListView.setonRefreshListener(new MyRefreshListener());//监听下拉刷新状态
OK,大功告成,应该处理数据还有很多其他的办法,这只是我个人的一点思路而已,仅供参考,谢谢大家。
由于上面提到了我们自定义下拉刷新的ListView,下面顺便贴出,下拉刷新后的处理代码:
/**
* 好友列表下拉刷新监听与实现,异步任务
*
* @author way
*
*/
public class MyRefreshListener implements MyListView.OnRefreshListener {
@Override
public void onRefresh() {
new AsyncTask<Void, Void, Void>() {
List<User> list;
protected Void doInBackground(Void... params) {
// 从服务器重新获取好友列表
if (GetMsgService.isStart) {
ClientOutputThread out = GetMsgService.client
.getClientOutputThread();
TranObject o = new TranObject(TranObjectType.REFRESH);
o.setFromUser(Integer.parseInt(util.getId()));
out.setMsg(o);
// 为了及时收到服务器发过来的消息,我这里直接通过监听收消息线程,获取好友列表,就不通过接收广播了
ClientInputThread in = GetMsgService.client
.getClientInputThread();
in.setMessageListener(new MessageListener() {
@Override
public void Message(TranObject msg) {
// TODO Auto-generated method stub
if (msg != null
&& msg.getType() == TranObjectType.REFRESH) {
list = (List<User>) msg.getObject();//获取到的数据
if (list.size() > 0) {
// System.out.println("Friend:" + list);
initListViewData(list);//交给写好的方法加工一下
myExAdapter.updata(group);//调用自定义更新的方法
userDB.updateUser(list);// 保存到数据库
}
}
}
});
}
return null;
}
@Override
protected void onPostExecute(Void result) {
myExAdapter.notifyDataSetChanged();//通知更新了
myListView.onRefreshComplete();//下拉刷新结束
Toast.makeText(FriendListActivity.this, "刷新成功", 0).show();
}
}.execute(null);
}
}
分享到:
相关推荐
NULL 博文链接:https://xieruilin.iteye.com/blog/726494
在Android开发中,`BaseExpandableListAdapter`是一个用于创建可扩展列表视图(ExpandableListView)的数据适配器。这个适配器允许开发者构建复杂的列表结构,其中包含可展开和折叠的组(groups),每个组内又包含多...
在Android开发中,有时我们需要创建一个可展开和折叠的列表,以展示层次结构的数据,比如模仿QQ的好友分组功能。这就是ExpandableListView的作用。它是一个特殊的ListView,能够支持子项的扩展和收缩,非常适合用来...
在Android开发中,创建仿QQ多级列表是一项常见的任务,特别是在构建导航或者分类视图时。这个项目旨在实现一个两层的多级列表,模仿QQ应用中的层级展示方式,为用户提供清晰、直观的浏览体验。下面我们将深入探讨...
在Android开发中,实现一个类似QQ的好友列表通常涉及到多个技术点,包括UI设计、数据结构、事件处理等。这个实例使用了ExpandableListView控件,这是一个强大的组件,可以展示可展开/折叠的子列表,非常适合构建层次...
本示例"可扩展listview demo BaseExpandableListAdapter"将详细讲解如何使用`BaseExpandableListAdapter`来实现一个功能完善的可扩展ListView。 首先,我们需要理解`ExpandableListView`的工作原理。它扩展了`...
在Android开发中,`ExpandableListView`是一种常用的控件,用于展示可以展开和折叠的列表,特别适合于呈现具有层级关系的数据,例如多级目录、组织结构等。本篇文章将详细探讨如何利用`ExpandableListView`来实现...
在某些android开发群里,看到有些新手问怎么实现QQ好友列表,其实网上一搜挺多的。接触Android,也才一年的时间,大部分时间花在工作上(解bug。。。),界面上开发很少参与。自己维护的系统应用里,有个...
在Android开发中,模拟QQ的扩展列表功能是一项常见的需求,特别是在构建社交应用或者有层级结构展示数据的应用中。本框架正是为了满足这一需求而设计,它简化了开发过程,使得开发者能够快速、轻松地实现类似QQ扩展...
在Android开发中,创建一个类似QQ的好友列表分组功能是一项常见的需求,它涉及到数据的组织、UI的呈现以及用户交互。在这个“Android仿QQ好友列表分组实现增删改及持久化Demo”中,我们将深入探讨如何实现这样一个...
在Android开发中,为了优化用户体验,我们经常需要实现列表的动态收缩与展开功能,这在很多社交应用中尤为常见,比如QQ好友列表。这个功能可以让用户更方便地管理和浏览大量信息,提高操作效率。本篇将详细介绍如何...
在Android开发中,ExpandableListView是一个非常实用的控件,它可以模拟折叠效果,类似于QQ好友列表,用户可以展开或收起各个组,显示或隐藏子项。本教程将详细介绍如何在Android应用中使用ExpandableListView来创建...
`ExpandableListView`是Android提供的一个可扩展的列表视图,它可以展示分组数据,每组数据下还可以包含多个子项,这种结构与QQ的分组列表用户信息展示方式非常相似。在本项目中,我们将利用`ExpandableListView`来...
本示例"android QQ好友列表 ListView"是模仿QQ应用中的好友列表,旨在帮助初学者理解和掌握ListView的使用,以及实现类似下拉列表的功能。这个demo包含了如何创建一个可扩展的ListView,即QQExpandableListView,它...
在Android开发中,ExpandableListView是一种可折叠的列表视图,它允许用户展开或折叠组项,每个组项下还可以包含多个子项。这个控件非常适合用来展示层次结构清晰的数据,比如目录结构、菜单或者分类信息。在...
"基于Android的模仿QQ的扩展型很好的ExpandableListView.zip" 这个标题揭示了我们正在处理一个Android开发项目,该项目旨在模仿QQ应用中的ExpandableListView组件。ExpandableListView是Android SDK提供的一种视图...
在Android开发中,"防QQ好友列表二层listview可置顶"是一个常见的需求,它涉及到对用户界面(UI)的优化,特别是对于那些需要显示大量数据并支持分层次展示的应用。这个标题所指的其实是如何创建一个具有类似QQ好友...
收集的一些关于Android的学习...Android之Adapter用法总结,Android中图片的处理,BaseExpandableListAdapter的使用,反编译android app,详解 Android 的 Activity 组件,需要的朋友可以下载查看(直接双击html文件查看即可)