你還在寫麻煩的 Adapter 麼

這期文章,推薦一個類庫 ItemPool,它能很大程度上減小你的 Adapter 數量,它是一個解耦實現,能把 ViewHolder/ItemView 解耦出來。請記住,這讓全部 ItemView 變得可複用html

前言

自從 Android 的 RecyclerView 組件發佈以來,RecyclerView 成爲了 Android 開發中實現容器視圖的首選。要實現一個 RecyclerView,必須爲其提供一個 RecyclerView.Adapter。咱們來看看一個普通 Adapter 的寫法:git

做者:nekocode
連接:https://zhuanlan.zhihu.com/p/22146783
來源:知乎
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
public class CommonAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private final List<String> list;

    public CommonAdapter(List<String> sampleData) {
        this.list = sampleData;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View item = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_test, parent, false);
        return new ViewHolder(item);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof ViewHolder) {
            ((ViewHolder) holder).bindData(list.get(position));
        }
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        private TextView text;

        public ViewHolder(View itemView) {
            super(itemView);
            text = (TextView) itemView.findViewById(R.id.textView);
        }

        public void bindData(String data) {
            text.setText(data);
        }
    }
}

這段代碼已經十分簡單了,但它目前只包含一種類型的 ItemView,當咱們須要更多不一樣的 ItemView 時,須要添加新的 ViewHolder 並更改 onCreateViewHolder() 和 onBindViewHolder() 函數下的代碼。

這暫且來講尚未什麼大礙。可是當你要實現另一個相似的 Adapter 時,假設裏面有一些在舊 Adapter 中已經出現過的 ItemView,你會發現你沒有辦法複用以前寫過的代碼,你只能從新定義一個 Adapter 類並複製舊的 ViewHolder 代碼到新的 Adapter 上。這執行起來十分機械,而且當某個 ItemView 發生更改時,你須要同步更改全部對應 Adapter 中的 ViewHolder。github

咱們須要作點工做把 ViewHolder 代碼從 Adapter 中抽離並獨立出來,而 ItemPool 能幫你完成這點工做。ide

ItemPool

使用 ItemPool 後,咱們把寫 ViewHolder 改變成了寫 Item。不一樣的 Item 用來將不一樣類型的 Data 映射到相應的 ItemView 上。更重要的是,這些 Item 是可複用的,這意味着你在另一個 RecyclerView 中也能直接使用該 Item。一個經典的 Item 以下:函數

public class TestItem extends Item<String> {
    TextView textView;

    @NonNull
    @Override
    public View onCreateItemView(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
        View itemView = inflater.inflate(R.layout.item_test, parent, false);
        textView = (TextView) itemView.findViewById(R.id.textView);
        return itemView;
    }

    @Override
    public void onBindItem(@NonNull final RecyclerView.ViewHolder holder, @NonNull String s, ItemEventHandler eventHandler) {
        textView.setText(s);
    }
}

上面除去 IDE 自動生成的代碼,實際上僅僅須要本身寫 5 行代碼。這個 Item 經過 onCreateItemView() 函數來生成某個 ItemView,並掛鉤了 String 這個數據類型,而後經過 onBindItem() 函數來將 String 類型的數據傳遞給 ItemView 進行視圖更新。this

好的,接下來咱們能夠給某個 RecyclerView 組裝 Item 了,它看起來是這樣的:spa

ItemPool items = new ItemPool();
items.addType(TestItem.class);
items.addType(TestItem2.class);

items.add(new Header());
items.add("A");
items.add("B");

items.attachTo(recyclerView);


能夠看出來咱們並不要再寫 Adapter 了,甚至也不用額外定義一個 DataList 了,它經過如下的工做流程來生成對應的 ItemView:3d

簡而言之就是將指定類型的數據用指定類型的 Item 來展現。這十分容易理解,你只要記住哪一個 Item 對應哪一個數據類型,並往 ItemPool 中塞數據就好了code

完整商城源碼下載地址: http://www.tp-shop.cn/download.htmlhtm

相關文章
相關標籤/搜索