getviewtype()实现recyclerview分组

直接进入主题,要实现的效果如下图:
使用的是recyclerview的分组,getviewtype()方法返回不同布局。

[外链图片转存中…(img-dG1kQsW6-1569828948498)]

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都可以实现,不过封装太好了我是没看懂所以自己想办法写的。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值