当前位置: 代码迷 >> Android >> Android之BaseExpandableListAdapter运用心得(QQ续一)
  详细解决方案

Android之BaseExpandableListAdapter运用心得(QQ续一)

热度:81   发布时间:2016-05-01 13:28:23.0
Android之BaseExpandableListAdapter使用心得(QQ续一)

        前段时间跟大家分享了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);		}	}


 

5楼wangheng58392418432分钟前
每次都要哥哥来给你占位子
4楼jan90031小时前
每次都板凳..
3楼skyxuyan昨天 23:25
麻烦问下 你用的是什么数据库 是SQlite 的话 用的什么n显示插件 请教!!
Re: weidi19892小时前
回复skyxuyann服务器数据库是MySQL,我用的显示软件是SQLyog Communityn手机客户端数据库没得选择SQLite,显示软件是SQLite Expert Professional
Re: skyxuyan1小时前
回复weidi1989n 嗯 多谢啦
2楼qqcsdr昨天 23:23
我也来占座
1楼NUPTboyZHB昨天 18:37
我也来占座
Re: weidi1989昨天 19:51
回复NUPTboyZHBn欢迎大侠指点啊~呵呵~
  相关解决方案