#Android# 你還在寫麻煩的 Adapter 么?
這期文章,推薦一個類庫 ItemPool,它能很大程度上減少你的 Adapter 數量,它是一個解耦實現,能把 ViewHolder/ItemView 解耦出來。請記住,這讓所有 ItemView 變得可復用。
前言
自從 Android 的 RecyclerView 組件發布以來,RecyclerView 成為了 Android 開發中實現容器視圖的首選。要實現一個 RecyclerView,必須為其提供一個 RecyclerView.Adapter。我們來看看一個普通 Adapter 的寫法:
public class CommonAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {n private final List<String> list;nn public CommonAdapter(List<String> sampleData) {n this.list = sampleData;n }nn @Overriden public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {n View item = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_test, parent, false);n return new ViewHolder(item);n }nn @Overriden public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {n if (holder instanceof ViewHolder) {n ((ViewHolder) holder).bindData(list.get(position));n }n }nn @Overriden public int getItemCount() {n return list.size();n }nn public static class ViewHolder extends RecyclerView.ViewHolder {n private TextView text;nn public ViewHolder(View itemView) {n super(itemView);n text = (TextView) itemView.findViewById(R.id.textView);n }nn public void bindData(String data) {n text.setText(data);n }n }n}n
這段代碼已經十分簡單了,但它目前只包含一種類型的 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> {n TextView textView;nn @NonNulln @Overriden public View onCreateItemView(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {n View itemView = inflater.inflate(R.layout.item_test, parent, false);n textView = (TextView) itemView.findViewById(R.id.textView);n return itemView;n }nn @Overriden public void onBindItem(@NonNull final RecyclerView.ViewHolder holder, @NonNull String s, ItemEventHandler eventHandler) {n textView.setText(s);n }n}n
上面除去 IDE 自動生成的代碼,實際上僅僅需要自己寫 5 行代碼。這個 Item 通過 onCreateItemView() 函數來生成某個 ItemView,並掛鉤了 String 這個數據類型,然後通過 onBindItem() 函數來將 String 類型的數據傳遞給 ItemView 進行視圖更新。
好的,接下來我們可以給某個 RecyclerView 組裝 Item 了,它看起來是這樣的:
ItemPool items = new ItemPool();nitems.addType(TestItem.class);nitems.addType(TestItem2.class);nnitems.add(new Header());nitems.add("A");nitems.add("B");nnitems.attachTo(recyclerView);n
可以看出來我們並不要再寫 Adapter 了,甚至也不用額外定義一個 DataList 了,它通過以下的工作流程來生成對應的 ItemView:
簡而言之就是將指定類型的數據用指定類型的 Item 來展示。這十分容易理解,你只要記住哪個 Item 對應哪個數據類型,並往 ItemPool 中塞數據就行了。更詳細的描述可以移步 README 文檔。
末尾
當然,它並不是萬能的,一些情況下依然推薦使用 Adapter 實現。但不管怎樣,大多數情況下你都能用它,並且為你減少幾杯咖啡的工作時間~
(≡ω≡.)
推薦閱讀:
※Android開發中,有哪些讓你覺得相見恨晚的方法、類或介面?
※閱讀項目源碼時,一看到一大堆的類就頭暈怎麼辦?
※Android 開發者是如何解決不同解析度的兼容問題的?
※android 8.0的後台機制可不可以為國內用戶帶來ios般的體驗?