MultiItem进阶 实现Head Foot和加载更多-多类型RecyclerView Adapter

前言

本文是MultiItem系列的进阶文章,主要讲解header footer和下拉刷新加载更多功能的用法与实现详解,上篇文章MultiItem用法与详解-优雅的实现多类型RecyclerView Adapter讲解了一些基本的用法和依赖方式,没有看过的同学可以点击查看。
MutliItem主要解决多类型RecyclerView Adapter问题,在正常使用中做到了Adapter零编码,解放了复杂的Adapter类,提高扩展性。
本库的定位并不是大而全,但是会尽量做到简单实用。

源码地址

Github地址:https://github.com/free46000/MultiItem,请大家多多关注,更多更新会首先在GitHub上体现,也会在第一时间在本平台发布

效果截图

图片做过处理一张10几kb

headfoot
headfoot

fullspan
fullspan

loadmore
loadmore

用法

为列表添加header和footer

添加header footer提供两种方式,直接addView或者addItem方式:

//为XXBean数据源注册XXManager管理类
adapter.register(TextBean.class, new TextViewManager());

//添加header
TextView headView = new TextView(this);
headView.setText("通过addHeadView增加的head1");
//方式一:方便实际业务使用
adapter.addHeadView(headView);
//方式二:这种方式和直接addDataItem添加数据源原理一样
adapter.addHeadItem(new TextBean("通过addHeadItem增加的head2"));

//添加footer,方式同添加header
TextView footView = new TextView(this);
footView.setText("通过addFootView增加的foot1");
adapter.addFootView(footView);
adapter.addFootItem(new TextBean("通过addFootItem增加的foot2"));

为表格添加充满宽度的Item(含header和footer)

充满宽度详见ViewHolderManager#isFullSpan返回true即可,适用于head foot或任意数据源Item

//此处为TextBean数据源注册FullSpanTextViewManager管理类
adapter.register(TextBean.class, new FullSpanTextViewManager());

//添加header或者footer
TextView headView = new TextView(this);
headView.setText("通过addHeadView增加的head1");
//使用HeadFootHolderManager已经实现isFullSpan方法,默认充满宽度
adapter.addHeadView(headView);

//添加普通Item,详见FullSpanTextViewManager,默认充满宽度
adapter.addDataItem(new TextBean("FullSpanTextViewManager充满宽度Item"));

下拉刷新加载更多功能的用法

下拉刷新采用SwipeRefreshLayout这里就不在过多介绍,开启和处理加载更多功能比较简单,但是需要注意加载更多本质上是一个footer,并且对添加顺序敏感,所以需要先去addFoot后在调用开启方法:

//开启加载更多视图
adapter.enableLoadMore(new LoadMoreHolderManager(this::loadData));

//加载完成 isLoadAll:是否全部数据
adapter.setLoadCompleted(boolean isLoadAll);

//加载失败
adapter.setLoadFailed();

通过开启方法我们可以看出依赖于LoadMoreHolderManager,主要是处理不同状态下加载更多界面的变化,下面贴出代码,更多实现细节请参阅LoadMoreManager

/**
 * 加载更多视图管理类
 */
public class LoadMoreHolderManager extends LoadMoreManager {

    public LoadMoreHolderManager(OnLoadMoreListener onLoadMoreListener, boolean isAutoLoadMore) {
        super(onLoadMoreListener, isAutoLoadMore);
    }

    @Override
    protected int getItemLayoutId() {
        return R.layout.item_load_more;
    }

    @Override
    protected void updateLoadInitView() {
        ((TextView) getView(loadMoreView, R.id.text)).setText("");
    }

    @Override
    protected void updateLoadingMoreView() {
        ((TextView) getView(loadMoreView, R.id.text)).setText(R.string.loading_more);
    }

    @Override
    protected void updateLoadCompletedView(boolean isLoadAll) {
        ((TextView) getView(loadMoreView, R.id.text))
                .setText(isLoadAll ? R.string.load_all : R.string.load_has_more);
    }

    @Override
    protected void updateLoadFailedView() {
        ((TextView) getView(loadMoreView, R.id.text)).setText(R.string.load_failed);
    }
}

至此本库的header footer和下拉刷新加载更多功能的用法已经完成,并没有修改或继承RecyclerView Adapter类,完全使用默认实现BaseItemAdapter即可。

详解

header和footer

主要利用Multiitem的多类型特性,封装了实用api而已,在BaseItemAdapter中维护了headItems footItems两个集合,在getItem的时候根据顺序获取数据,如下:

/**
 * @param position int
 * @return 返回指定位置Item
 */
public Object getItem(int position) {
    if (position < headItems.size()) {
        return headItems.get(position);
    }

    position -= headItems.size();
    if (position < dataItems.size()) {
        return dataItems.get(position);
    }

    position -= dataItems.size();
    return footItems.get(position);
}

为表格添加充满宽度的Item

ViewHolderManager中封装了两个方法以适配表格布局的时候填充宽度:

/**
 * @return 是否填满父布局
 * @see StaggeredGridLayoutManager.LayoutParams#setFullSpan
 * @see GridLayoutManager#setSpanSizeLookup
 */
public boolean isFullSpan() {
    return fullSpan;
}

/**
 * 根据spanCount获取当前所占span大小(适用于表格布局)
 * 如果被设置过正整数则返回;如果是fullSpan则返回spanCount;其余返回1
 * GridLayoutManager模式下,调整本方法返回值达到不同Item占用不同宽度的功能
 *
 * @param spanCount span总数量
 * @return 当前所占span大小
 * @see GridLayoutManager#setSpanSizeLookup
 */
public int getSpanSize(int spanCount) {
    return spanSize > 0 ? spanSize : (isFullSpan() ? spanCount : 1);
}

加载更多

加载更多利用onBindViewHolder 这个 RecyclerView Adapter的回调方法实现了对加载更多视图状态的模板方法的封装,并提供了对应的处理方法,详见LoadMoreManager,这里贴出关键代码:

@Override
public void onBindViewHolder(@NonNull BaseViewHolder holder, @NonNull Object o) {
    if (isNeeLoadMore(holder)) {
        if (isAutoLoadMore()) {
            //当可以加载更多数据并开启自动加载后调用
            onLoadMore();
        }
    } else {
        updateLoadInitView();
    }
}

/**
 * 避免第一次可见时去加载数据
 * 若head和foot的数量小于当前loadMore的位置则证明没有ItemData数据,即为RecyclerView加载数据前
 *
 * @param holder
 * @return 是否需要加载更多
 */
protected boolean isNeeLoadMore(@NonNull BaseViewHolder holder) {
    int headFootCount = adapter.getHeadCount() + adapter.getFootCount();
    return headFootCount < holder.getItemPosition();
}

希望大家会喜欢,多多留言交流

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容