通用RecylerAdapter,內置XRecyclerView,兼容上下拉與動畫,高複用,一個Adapter通用全部頁面,支持空頁面,懶人專屬

 Hello你們好,郭老司機又來了。之前都是看文章的小喵同志,現在終於體也會到碼字的不易,做爲一個沉默寡言的程序猿,對於碼文無數的前輩深表敬佩((/- -)/。

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

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

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

一個列表多種類型的item

 正常狀況下,對於每個不一樣的列表,咱們常常須要實現不一樣的Adapter ,來處理對應的邏輯,這樣致使了咱們有着許多重複的代碼,在優化代碼()這種動力的驅動下,我的實現了一個通用的Adapter。後面所說的Holder,能夠理解爲列表中一個Item,屬於它的邏輯處理類,每一種類型的Item有一種Holdergithub

 只須要一個Adapter,你就能夠實現各類類型的列表,在一個列表裏兼容不一樣類型的Item,你須要作的,僅僅是維護你的Holder(相似List裏的一個Item)和Model,無需再關心其餘,實現高複用與多樣式邏輯,外帶支持自定義動畫,多種上下拉實現方式,不須要再寫任何Adapter代碼(^o^)/。api

一、 CommonRecyclerManager :綁定layoutId和你的Holder類名。
 這個管理類是用於綁定Holder和R.layout.xxx,這樣在後面CommonRecyclerAdapter 用它經過數據ModellayoutId,找到對應的Holder並建立它。ide

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

二、 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;
    }
}複製代碼

三、 CommonRecyclerAdapter :通用的適配器
 只須要傳入數據ListCommonRecyclerManager,就會根據Model的順序,經過數據的layoutId,在RecyclerView中自動生成對應的Holder,其餘的功能只須要簡單的配置便可。post

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

//支持須要加載更多
adapter.setNeedLoadMore(true);

//支持空數據顯示 空頁面
adapter.setShowNoData(true);

//設置item顯示動畫支持打開
adapter.setNeedAnimation(true);複製代碼

四、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;
    }
}複製代碼

總結起來就是

 
一、實現你的Holder並繼承RecyclerBaseHolder,這裏是你實現需求的地方,至關於Item的邏輯。動畫

二、讓你的數據model繼承RecyclerBaseModel,設置Model的LayoutId(很重要),這樣model就會經過CommonRecyclerManager,找到LayoutId對應關聯的Holder,並生成它。

三、你須要一個CommonRecyclerManager來綁定你的LayoutId和處理這佈局的Holder類名。

四、經過CommonRecyclerManager和Model的數據列表生成CommonRecyclerAdapter。

五、把Adapter交給Recycler。

 邏輯看起來是否是有些複雜?其實就是model的LayoutId,CommonRecyclerManager經過關聯了處理它的Holder。這樣咱們只須要在數據List裏,根據數據設置不一樣的LayoutId的model,Adapter就會自動匹配對應的Holder。

效果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兼容支持

  

 這裏添加了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…

看明白了嗎?
相關文章
相關標籤/搜索