getviewtype()实现recyclerview分组
来源:互联网 发布:如何编写js插件 编辑:程序博客网 时间:2024/06/13 14:47
直接进入主题,要实现的效果如下图:
使用的是recyclerview的分组,getviewtype()方法返回不同布局。
listview实现就是listview嵌套gridview,把每个分组当成一个listview的一个item,想象就很麻烦,接下来用recycler来实现这个效果。
首先recyclerview的基本用法要会,这里我就不想说recyclerview的基本用法了不太了解的可以看看鸿洋的博客点这里,讲的挺详细的,看完基本使用应该没问题了。
实现思路:
其实以前也做过类似的效果就是用的listview加gridview,所以我才说很麻烦,listview中adapter中有个方法是getItemViewType()根据item返回不同的layout,在getview()中加载不同布局,再来看看那下面的图片,
实现一:
首先就是数据list集合。1-8这些所有的数据是放在一个list< Entity >中的,Entity就是服务器返回的数据,只不过在其中加了一个key用于标识当前item是分组还是组员,再根据这个key在getItemViewType()返回不同的type,一般服务器返回的格式如下
{ "resultMsg":{ "groupList":[ { "childList":[ { "childName":"组员1", "openTime":"2017-04-20 11:40:18" }, { "childName":"组员2", "openTime":"2017-04-20 11:40:18" }, { "childName":"组员3", "openTime":"2017-04-20 11:40:18" } ], "groupName":"分组1" }, { "childList":[ { "childName":"组员1", "openTime":"2017-07-06 10:05:16" }, { "childName":"组员2", "openTime":"2017-07-06 10:05:16" } ], "groupName":"分组2" } ] }}
思路二
将上述json数据添加到一个list中,看看上面的数据,一层套着一层,grouplist中套着childlist,一般分组的数据都是这样的json格式。
这里就需要用到map,以key-vale的形式将json数据保存下来,map最好用LinkedHashMap;
LinkedHashMap是有序的存储的你存和取得顺序是一致的,key是groupName; value是组员的list集合,代码如下:
private LinkedHashMap<String, ArrayList<ChildListBean>> groupMap = new LinkedHashMap<String, ArrayList<ChildListBean>>();
实现三
数据保存下来后就调用adapter的setList()方法刷新数据,在setList()方法方法中遍历map将所有数据添加到一个list中代码如下:
/** * @param map */ public void setList(LinkedHashMap<String, ArrayList<ChildListBean>> map) { Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { String key = iterator.next().toString(); //遍历数组 if (map.get(key).size() > 0) { //这里是将group当成一个child一起加到mList中 //也就是mList中包含了group和child,只不过group //所在的positon有个标识当前position是否为分组 mList.add(new ChildListBean(key, true)); } mList.addAll(map.get(key)); } notifyDataSetChanged(); }
再来看看实体类代码,这个有必要贴出来,主要就是ChildListBean 的两个构造方法,如果group还有其他的信息都可以这样加进来,需要什么setXXX什么显示的时候在getXXX,这样就把group信息和child信息添加到一个list中了。
public class GroupChildBean { private ResultMsgBean resultMsg; public ResultMsgBean getResultMsg() { return resultMsg; } public void setResultMsg(ResultMsgBean resultMsg) { this.resultMsg = resultMsg; } public static class ResultMsgBean { private List<GroupListBean> groupList; public List<GroupListBean> getGroupList() { return groupList; } public void setGroupList(List<GroupListBean> groupList) { this.groupList = groupList; } public static class GroupListBean { private String groupName; private List<ChildListBean> childList; public String getGroupName() { return groupName; } public void setGroupName(String groupName) { this.groupName = groupName; } public List<ChildListBean> getChildList() { return childList; } public void setChildList(List<ChildListBean> childList) { this.childList = childList; } public static class ChildListBean { private String childName; private String openTime; private boolean isGroup; /** * 添加child * * @param childName */ public ChildListBean(String childName) { this.childName = childName; } /** * 把group当成child * * @param childName * @param isGroup */ public ChildListBean(String childName, boolean isGroup) { this.childName = childName; this.isGroup = isGroup; } public boolean isGroup() { return isGroup; } public void setGroup(boolean group) { isGroup = group; } public String getChildName() { return childName; } public void setChildName(String childName) { this.childName = childName; } public String getOpenTime() { return openTime; } public void setOpenTime(String openTime) { this.openTime = openTime; } } } }}
实现四
有了list集合那就很简单了,接下来就是recyclerview的基本用法了.
就是需要在getViewType中判断是否为分组返回不同的type
@Override public int getItemViewType(int position) { if (mList.get(position).isGroup()) { return GROUP_ITEM_TYPE; } else { return CHILD_ITEM_TYPE; } }
在onBindViewHolder返回不同的viewHolder
@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { final ChildListBean bean = mList.get(position); int type = holder.getItemViewType(); if (type == GROUP_ITEM_TYPE) { GroupViewHolder holder1 = (GroupViewHolder) holder; holder1.textView.setText(bean.getChildName()); holder1.cardView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, bean.getChildName(), Toast.LENGTH_SHORT).show(); } }); } else { ChildViewHolder holder1 = (ChildViewHolder) holder; holder1.textView.setText(bean.getChildName()); holder1.cardView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, bean.getChildName(), Toast.LENGTH_SHORT).show(); } }); } }
/** * 分组 */ class GroupViewHolder extends RecyclerView.ViewHolder { TextView textView; CardView cardView; public GroupViewHolder(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.header); cardView = (CardView) itemView.findViewById(R.id.card_view); } } /** * 成员 */ class ChildViewHolder extends RecyclerView.ViewHolder { TextView textView; CardView cardView; public ChildViewHolder(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.tv); cardView = (CardView) itemView.findViewById(R.id.card_view); } }
在来看看Activity的代码,主要就是initView()中的代码
private void initView() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); initToolBar(toolbar, "分组recycler", true); mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); mRecyclerView.setLayoutManager(new GridLayoutManager(this,2)); mAdapter = new GroupRecyAdapter(this); initData(); mRecyclerView.setAdapter(mAdapter); mAdapter.setList(groupMap); }
运行代码效果如下
和想象的不一样,因为我们之前是将group当成child一起添加到list中,所以在使用GridLayoutManager并且显示两列的时候并没有判断isGroup这个字段,所以group就跟child一样显示了,这样我们就需要加个判定了,当是group时就让他显示一列,如果是child就让他显示两列,GridLayoutManager有个方法setSpanSizeLookup()就需要我们自己去写了,代码如下,一看就懂
final GridLayoutManager manager = new GridLayoutManager(this, 2, OrientationHelper.VERTICAL, false); manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { //当是group时就让他显示一列,如果是child就让他显示两列 return mAdapter.getItemViewType(position) == GroupRecyAdapter.GROUP_ITEM_TYPE ? manager.getSpanCount() : 1; } }); mRecyclerView.setLayoutManager(manager);
manager.getSpanCount()就是上面设置的默认列数
final GridLayoutManager manager = new GridLayoutManager(this, 2, OrientationHelper.VERTICAL, false);
再次运行,完美实现了recyclerview分组的效果。
总结:
recyclerview之所有强大就是因为你完全可以自定义view改如何显示,分组的方法还有很多种,这里只是其中一种。这种实现方式最主要的就两个地方,第一个就是数据处理,将group当成child添加到一个集合list中;第二呢就是 需要重写getSpanSize()方法,判断当前item是否为分组返回不同的列数。这里只有两种type,如果布局更复杂,也可以加,思路差不多。
第一次写这么长的博客,写的有点乱,凑合看吧,如有写的不好的地方希望大佬们指出。有问题可以留言或者加QQ821651400。
源码地址:https://github.com/caobin821651400/Study 在com.example.androidremark.ui2.grouprecycler目录下
这是我的一个小项目,里面包含了好多好的布局或者工具,喜欢的就start下,谢谢~
如果想直接使用可以去github搜MultiType,SLTableView都可以实现,不过封装太好了我是没看懂所以自己想办法写的。
- getviewtype()实现recyclerview分组
- RecyclerView分组之BaseRecyclerViewAdapterHelper(实现分组功能)
- RecyclerView实现分组展示信息
- RecyclerView分组列表的实现及demo
- RecyclerView轻松实现悬浮头部分组列表
- Group分组列表的实现 RecyclerView(二)
- Android开发技巧——使用RecyclerView实现分组列表
- RecyclerView 分组管理
- RecyclerView+GridView分组效果
- RecyclerView头部分组列表
- 用Recyclerview实现列表分组、下拉刷新以及上拉加载更多
- 用Recyclerview实现列表分组、下拉刷新以及上拉加载--源码
- RecyclerView 分组 item显示不同view
- Android-->RecyclerView分组悬浮标题(分割线)
- android RecyclerView一步步打造分组效果、类似QQ分组、折叠菜单、分组效果(一)
- android RecyclerView一步步打造分组效果、类似QQ分组、折叠菜单、分组效果(二)
- 实现分组小计
- Union 实现自定义分组
- 职业性格
- 写代码怎能不会这些 Linux 命令?
- PAT甲级 1042
- HTML5 离线缓存 Web Workr
- Spring Boot -- 微信企业号开发03-aes解密失败
- getviewtype()实现recyclerview分组
- LINUX驱动之SPI子系统之一概述
- Android LayoutInflater原理分析,带你一步步深入了解View(一)
- CSAPP3e-第二章Homework
- HTML5 拖放
- 首字母大写
- 彻底理解了call()方法,apply()方法和bind()方法
- ubuntu禁用/启用触摸板命令
- 如何获取元素的相对于屏幕的距离?