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閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容