通用RecylerAdapter,內建XRecyclerView,相容上下拉與動畫,高複用,一個Adapter通用所有頁面,支援空頁面,懶人專屬

戀貓de小郭發表於2016-11-25

 Hello大家好,郭老司機又來了。以前都是看文章的小喵同志,如今終於體也會到碼字的不易,作為一個沉默寡言的程式猿,對於碼文無數的前輩深表敬佩((/- -)/。

 
這是歡迎各位踐踏的Github:github.com/CarGuo

我叫DEMO:github.com/CarGuo/Lazy…

 RecylerView相信大家都聽過(你確定要說沒聽過 = =),在ListView橫行的年代裡,RecyclerView攜帶了褒貶不一的評價,開始進入了我們的視線,那時候剛好開始了新的專案,正好就拿它練手了。下方進入介紹使用流程,建議對著Demo擼起來。( ・᷄-・᷅ )

通用RecylerAdapter,內建XRecyclerView,相容上下拉與動畫,高複用,一個Adapter通用所有頁面,支援空頁面,懶人專屬
一個列表多種型別的item

 正常情況下,對於每一個不同的列表,我們經常需要實現不同的Adapter ,來處理對應的邏輯,這樣導致了我們有著許多重複的程式碼,在優化程式碼()這種動力的驅動下,個人實現了一個通用的Adapter。後面所說的Holder,可以理解為列表中一個Item,屬於它的邏輯處理類,每一種型別的Item有一種Holder

 只需要一個Adapter,你就可以實現各種型別的列表,在一個列表裡相容不同型別的Item,你需要做的,僅僅是維護你的Holder(類似List裡的一個Item)和Model,無需再關心其他,實現高複用與多樣式邏輯,外帶支援自定義動畫,多種上下拉實現方式,不需要再寫任何Adapter程式碼(^o^)/。

1、 CommonRecyclerManager :繫結layoutId和你的Holder類名。
 這個管理類是用於繫結Holder和R.layout.xxx,這樣在後面CommonRecyclerAdapter 用它通過資料ModellayoutId,找到對應的Holder並建立它。

//將佈局的ID和holder型別關聯
commonRecyclerManager.addType(TextHolder.ID, TextHolder.class.getName());複製程式碼

2、 RecyclerBaseHolder :繼承這個Holder,實現你的需求。
 RecyclerBaseHolder的所有Holder的基類,他繼承了RecyclerView.ViewHolder,並定義寫兩個方法,所以你繼承它就對了,在createView的時候找到控制元件,在onBind讀取資料填充畫面。這裡就是實現你夢想的地方!

//實現的hodler繼承RecyclerBaseHolder,過載下面方式實現你的需求
public class TextHolder extends RecyclerBaseHolder {
    //佈局id,一般我習慣吧這個Holder需要處理的id都寫在這裡,方便管理
    public final static int ID = R.layout.text_item;
    @BindView(R.id.item_text)
    TextView itemText;

    public TextHolder(Context context, View v) {
        super(context, v);
    }    

    //view建立好了
    @Override 
    public void createView(View v) {
        ButterKnife.bind(this, v);
    }

    //view建立好了,更具資料處理邏輯
    @Override
    public void onBind(RecyclerBaseModel model, int position) {
        //轉化為你的model
        TextModel textModel = (TextModel) (model);
        itemText.setText(textModel.getText());
    }

    //不需要可以不寫
    @Override
    public AnimatorSet getAnimator(View view) {
        //實現你的動畫
        return null;
    }
}複製程式碼

3、 CommonRecyclerAdapter :通用的介面卡
 只需要傳入資料ListCommonRecyclerManager,就會根據Model的順序,通過資料的layoutId,在RecyclerView中自動生成對應的Holder,其他的功能只需要簡單的配置即可。

//用資料和manager建立
adapteradapter = new CommonRecyclerAdapter(getActivity(), commonRecyclerManager, datas);

//支援需要載入更多
adapter.setNeedLoadMore(true);

//支援空資料顯示 空頁面
adapter.setShowNoData(true);

//設定item顯示動畫支援開啟
adapter.setNeedAnimation(true);複製程式碼

4、RecyclerBaseModel :資料model的積累,必須繼承它,不離不棄。
 繼承它的作用是,因為整個Adapter都是以它為基類,你需要繼承他,最終的是,你需要這個Model對應的佈局Id,這樣它才能找到屬於自己的Holder。

//繼承RecyclerBaseModel實現你需要的資料型別
public class TextModel extends RecyclerBaseModel {
    private String text = "";

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}複製程式碼

總結起來就是

 
1、實現你的Holder並繼承RecyclerBaseHolder,這裡是你實現需求的地方,相當於Item的邏輯。

2、讓你的資料model繼承RecyclerBaseModel,設定Model的LayoutId(很重要),這樣model就會通過CommonRecyclerManager,找到LayoutId對應關聯的Holder,並生成它。

3、你需要一個CommonRecyclerManager來繫結你的LayoutId和處理這佈局的Holder類名。

4、通過CommonRecyclerManager和Model的資料列表生成CommonRecyclerAdapter。

5、把Adapter交給Recycler。

 邏輯看起來是不是有些複雜?其實就是model的LayoutId,CommonRecyclerManager通過關聯了處理它的Holder。這樣我們只需要在資料List裡,根據資料設定不同的LayoutId的model,Adapter就會自動匹配對應的Holder。

通用RecylerAdapter,內建XRecyclerView,相容上下拉與動畫,高複用,一個Adapter通用所有頁面,支援空頁面,懶人專屬
效果GIF

 如此一來,<( ̄︶ ̄)>你只需要實現好Holder和組裝好Model,任何列表都可以使用起來,不需要再寫Adapter邏輯了。根據model的順序,Adapter自動生成對應的Holder,並且同一個Holder是可以繫結不同的LayoutId,以後你只需要維護和相容你的Holder,在各個列表裡通用的你holder邏輯了,是不是瞬間程式碼乾淨了好多?

下拉重新整理與上拉載入更多

 
普通的列表,直接使用系統的SwipeRefreshLayout就可以啦,簡單有好用。下拉載入更多直接新增下方方法,輕鬆實現上下拉重新整理<( ̄︶ ̄),簡單粗暴,就是記得要加個鎖避免重複進入。

//開啟支援需要載入更多
adapter.setNeedLoadMore(true);

recycler.addOnScrollListener(new LoadMoreScrollListener() {
    @Override
    public void onLoadMore() {
        //注意加鎖
        if (!isLoadMore) {
            isLoadMore = true;
            recycler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    isLoadMore = false;
                    loadMore();
                }

            }, 2000);
        }
    }

    //當前第一個可視的是哪個item
    @Override
    public void onScrolled(int firstPosition) {
    }
});複製程式碼

其他配置

 
你還可以配置是否顯示動畫效果,配置上拉loading的顏色,單擊和長按等,看下面。

//支援空資料顯示 空頁面
adapter.setShowNoData(true);

//顯示空資料model,不設定顯示預設空頁面
adapter.setNoDataModel(noDataModel);

//顯示空資料頁面佈局,不設定顯示預設,佈局id需要通過CommonRecyclerManager關聯hodler
adapter.setNoDataLayoutId(noDataLayoutId);

//設定動畫支援開啟
adapter.setNeedAnimation(true);

//新增點選
adapter.setOnItemClickListener();複製程式碼
XRecyclerView相容支援

  

通用RecylerAdapter,內建XRecyclerView,相容上下拉與動畫,高複用,一個Adapter通用所有頁面,支援空頁面,懶人專屬

 這裡新增了XRecyclerView,並且對其進行了修改。XRecyclerView內建了內部Adapter,使其支援新增頭部,自帶上下拉效果的控制元件,部分調整之後,全面支援CommonRecyclerAdapter

 不需要監聽滑動,不需要SwipeRefreshLayout,輕鬆新增重新整理與載入更多。而且更是支援動態配置,上下拉的各種樣式支援,具體在ProgressStyle下有多種型別支援配置,解決了Adapter對瀑布流上拉的支援不夠相容的問題。

 這裡使用方式,和普通的RecyclerView一樣,支援和CommonRecyclerAdapter的配合,而且它同樣支援空頁面顯示,還支援新增各種頭部,唯一需要注意的是,新增分割線類addItemDecoration點選的時候,需要針對新增了頭部,和重新整理的絕對的position,換算成相對的位置,此處曾經把自己坑哭了╥﹏╥...,下面看程式碼吧。


//是否遮蔽下拉
//xRecycler.setPullRefreshEnabled(false);
//上拉載入更多樣式,也可以設定下拉
xRecycler.setLoadingMoreProgressStyle(ProgressStyle.SysProgress);
//設定管理器,關聯佈局與holder類名,不同id可以管理一個holder
CommonRecyclerManager commonRecyclerManager = new CommonRecyclerManager();
commonRecyclerManager.addType(ImageHolder.ID, ImageHolder.class.getName());
commonRecyclerManager.addType(TextHolder.ID, TextHolder.class.getName());
commonRecyclerManager.addType(ClickHolder.ID, ClickHolder.class.getName());
//初始化通用管理器
commonRecyclerAdapter = new CommonRecyclerAdapter(getActivity(), commonRecyclerManager, dataList);
xRecycler.setAdapter(commonRecyclerAdapter);

ImageView imageView = new ImageView(getActivity());
imageView.setImageResource(R.drawable.xxx1);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setMinimumHeight(dip2px(getActivity(), 100));
//新增頭部
xRecycler.addHeaderView(imageView);
//本身也支援設定空區域性
//xRecycler.setEmptyView();
xRecycler.setLoadingListener(new XRecyclerView.LoadingListener() {
    @Override
    public void onRefresh() {
        xRecycler.postDelayed(new Runnable() {
            @Override
            public void run() {
                xRecycler.refreshComplete();
            }
        }, 2000);
    }

    @Override
    public void onLoadMore() {
        xRecycler.postDelayed(new Runnable() {
            @Override
            public void run() {
                loadMore();
            }
        }, 2000);
    }
});

commonRecyclerAdapter.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(Context context, int position) {
        //需要減去你的header和重新整理的view的數量
        Toast.makeText(getActivity(), "點選了!! " + (position - 2), Toast.LENGTH_SHORT).show();
    }
});複製程式碼

最後

  
 到這裡你已經知道了大致的用法了吧。詳細的內部實現,可以通過DEMO檢視。大致邏輯是 CommonRecyclerManager 關聯接layoutId和Holder類名,CommonRecyclerAdapter通過Model的layoutId找到這個Holder,然後用layoutId建立view,把View、position、model傳入到Holder裡面實現資料填充。所layoutId也是*型別id,注意:

使用的時候切記要給你的model設定setResLayoutId(),這是最容易讓人遺忘的。

我叫DEMO:github.com/CarGuo/Lazy…

通用RecylerAdapter,內建XRecyclerView,相容上下拉與動畫,高複用,一個Adapter通用所有頁面,支援空頁面,懶人專屬
看明白了嗎?

相關文章