android你還在寫麻煩的 Adapter麼

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

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。


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

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 進行視圖更新。

好的,接下來我們可以給某個 RecyclerView 組裝 Item 了,它看起來是這樣的:

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:

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章