RecyclerView实现按时间分组手机相册效果

RecyclerView通常只有一个header和footer,但是像手机相册这种布局每个item都会有一个header该怎么办,其中一种办法就是RecyclerView嵌套RecyclerView,虽然能实现但是并不怎么友好,如何只创建一个RecyclerView就实现这种布局呢?
在github上找到了SectionedRecyclerView,不需要改动RecyclerView,定义adapter的时候只需要继承SectionedRecyclerViewAdapter即可,首先来看效果图
在这里插入图片描述
在这里插入图片描述
但是SectionedRecyclerViewAdapter使用的时候比平时的adapter多一些方法,下面简单介绍一下:

  1. SectionedRecyclerView这个库提供了两种adapter,一个是SectionedRecyclerViewAdapter,功能比较完成,有footer,另一个是SimpleSectionedAdapter,顾名思义就是简化版,只是有header,不需要footer
  2. 继承SectionedRecyclerViewAdapter时,通过hasFooterInSection设置是否显示footer布局
    下面贴出继承两种adapter的代码,方法的注释都写在上面了,只是比普通的adapter多了header和footer布局

继承SectionedRecyclerViewAdapter:

/**
 * @Description: 完整的adapter
 * 注意:通过hasFooterInSection()这个方法来设置是否需要显示footer
 * @author: ZhangYW
 * @time: 2019/1/24 9:39
 */
public class MyAdapter extends SectionedRecyclerViewAdapter<MyAdapter.MyHeaderViewHolder, MyAdapter.MyItemViewHolder, MyAdapter.MyFooterViewHolder> {

    private Context mContext;
    private List<MyBean> mList;

    public MyAdapter(Context context, List<MyBean> list) {
        this.mContext = context;
        this.mList = list;
    }

    /**
     * header或者footer的个数
     * @return
     */
    @Override
    protected int getSectionCount() {
        return mList.size();
    }

    /**
     * 每个header或者footer中包含具体的内容个数
     * @return
     */
    @Override
    protected int getItemCountForSection(int section) {
        return mList.get(section).getList().size();
    }

    /**
     * 是否显示footer
     * @param section
     * @return
     */
    @Override
    protected boolean hasFooterInSection(int section) {
        return true;
    }

    /**
     * 渲染具体的HeaderViewHolder
     *
     * @param parent   HeaderViewHolder的容器
     * @param viewType 一个标志,我们根据该标志可以实现渲染不同类型的ViewHolder
     * @return
     */
    @Override
    protected MyHeaderViewHolder onCreateSectionHeaderViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.item_rv_header, parent, false);
        return new MyHeaderViewHolder(itemView);
    }

    /**
     * 渲染具体的FooterViewHolder
     *
     * @param parent   FooterViewHolder的容器
     * @param viewType 一个标志,我们根据该标志可以实现渲染不同类型的ViewHolder
     * @return
     */
    @Override
    protected MyFooterViewHolder onCreateSectionFooterViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.item_rv_footer, parent, false);
        return new MyFooterViewHolder(itemView);
    }

    /**
     * 渲染具体的ItemViewHolder
     *
     * @param parent   ItemViewHolder的容器
     * @param viewType 一个标志,我们根据该标志可以实现渲染不同类型的ViewHolder
     * @return
     */
    @Override
    protected MyItemViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.item_rv_content, parent, false);
        return new MyItemViewHolder(itemView);
    }

    /**
     * 绑定HeaderViewHolder的数据。
     *
     * @param holder
     * @param section 数据源list的下标
     */
    @Override
    protected void onBindSectionHeaderViewHolder(MyHeaderViewHolder holder, int section) {
        MyBean bean = mList.get(section);
        if (null == bean)
            return;
        holder.tv_header_title.setText(bean.getHeader());
    }

    /**
     * 绑定FooterViewHolder的数据。
     *
     * @param holder
     * @param section 数据源list的下标
     */
    @Override
    protected void onBindSectionFooterViewHolder(MyFooterViewHolder holder, int section) {
        MyBean bean = mList.get(section);
        if (null == bean)
            return;
        holder.tv_footer_title.setText(bean.getFooter());
    }

    /**
     * 绑定ItemViewHolder的数据。
     *
     * @param holder
     * @param section 数据源list的下标
     */
    @Override
    protected void onBindItemViewHolder(MyItemViewHolder holder, int section, int position) {
        MyBean bean = mList.get(section);
        if (null == bean)
            return;
        holder.tv_name.setText(bean.getList().get(position).getContent());
        GlideApp.with(mContext)
                .load(R.mipmap.group)
                .placeholder(R.mipmap.ic_launcher)
                .error(R.mipmap.ic_launcher)
                .centerCrop()
                .into(holder.iv_head);
    }

    /**
     * ItemViewHolder
     */
    public class MyItemViewHolder extends RecyclerView.ViewHolder {
        private ImageView iv_head;
        private TextView tv_name;

        public MyItemViewHolder(View itemView) {
            super(itemView);
            iv_head = (ImageView)itemView.findViewById(R.id.item_iv);
            tv_name = (TextView)itemView.findViewById(R.id.item_tv_title);
        }
    }

    /**
     * HeaderViewHolder
     */
    public class MyHeaderViewHolder extends RecyclerView.ViewHolder {
        private TextView tv_header_title;
        public MyHeaderViewHolder(View itemView) {
            super(itemView);
            tv_header_title = (TextView)itemView.findViewById(R.id.item_header_title);
        }
    }

    /**
     * FooterViewHolder
     */
    public class MyFooterViewHolder extends RecyclerView.ViewHolder {
        private TextView tv_footer_title;
        public MyFooterViewHolder(View itemView) {
            super(itemView);
            tv_footer_title = (TextView)itemView.findViewById(R.id.item_footer_title);
        }
    }

继承SimpleSectionedAdapter:

/**
 * @Description: 简单用法 没有footer
 * @author: ZhangYW
 * @time: 2019/1/24 9:38
 */
public class SimpleHeaderAdapter extends SimpleSectionedAdapter<SimpleHeaderAdapter.MyItemViewHolder> {

    private Context mContext;
    private List<MyBean> mList;

    public SimpleHeaderAdapter(Context context, List<MyBean> list) {
        this.mContext = context;
        this.mList = list;

    }


    @Override
    protected String getSectionHeaderTitle(int section) {
        return mList.get(section).getHeader();
    }

    /**
     * header或者footer的个数
     * @return
     */
    @Override
    protected int getSectionCount() {
        return mList.size();
    }

    /**
     * 每个header或者footer中包含具体的内容个数
     * @return
     */
    @Override
    protected int getItemCountForSection(int section) {
        return mList.get(section).getList().size();
    }

    @Override
    protected MyItemViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.item_rv_content, parent, false);
        return new SimpleHeaderAdapter.MyItemViewHolder(itemView);
    }

    @Override
    protected void onBindItemViewHolder(MyItemViewHolder holder, int section, int position) {
        MyBean bean = mList.get(section);
        if (null == bean)
            return;
        holder.tv_name.setText(bean.getList().get(position).getContent());
        GlideApp.with(mContext)
                .load(R.mipmap.group)
                .placeholder(R.mipmap.ic_launcher)
                .error(R.mipmap.ic_launcher)
                .centerCrop()
                .into(holder.iv_head);
    }

    /**
     * ItemViewHolder
     */
    public class MyItemViewHolder extends RecyclerView.ViewHolder {
        private ImageView iv_head;
        private TextView tv_name;

        public MyItemViewHolder(View itemView) {
            super(itemView);
            iv_head = (ImageView)itemView.findViewById(R.id.item_iv);
            tv_name = (TextView)itemView.findViewById(R.id.item_tv_title);
        }
    }
}

在这里插入图片描述
下载地址:TestSectionedRecyclerView

猜你喜欢

转载自blog.csdn.net/zyw0101/article/details/85046347
今日推荐