Android RecyclerView中Adapter和ViewHo
前情提要
最近專案我在專案中使用了RecyclerView代替了ListView.由於專案中有多出列表項使用RecyclerView,這就導致需要寫多個Adapter和ViewHolder.
其實,怎麼說呢?就是懶,想少寫程式碼,所以想研究一下能否簡化一下.
具體實現
封裝分為Adapter和ViewHolder兩部分,如下所示.
ViewHolder
抽象類BaseHolder繼承RecyclerView.ViewHolder,並依賴注入的資料型別M,即和ViewHolder繫結的資料型別為M.
該抽象類包含一個構造方法,用於獲取item對應的佈局.一個抽象函式用於將資料設定到item上面.
[程式碼]java程式碼:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
public abstract class BaseHolder
public BaseHolder(ViewGroup parent, @LayoutRes int resId) { super(LayoutInflater.from(parent.getContext()).inflate(resId, parent, false)); }
protected return (T) (itemView.findViewById(viewId)); }
protected Context getContext() { return itemView.getContext(); }
public abstract void setData(M data); } |
Adapter
Adapter類也為抽象類,繼承於RecyclerView.Adapter,並繫結了兩個泛型:
1. M : 用於該 Adapter 的列表的資料型別,即List
2. H : 即和 Adapter 繫結的 Holder 的型別.
並且,該 Adapter 自帶 List 資料集合,宣告時可以不用傳遞資料集合.也包含了 List 的相關操作.同時還給該 Adapter 繫結了一個 item 的點選事件,且為可選操作,不需要點選操作,直接傳null即可.
[程式碼]java程式碼:
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
public abstract class BaseAdapter
protected List protected OnItemClickListener
public BaseAdapter(@Nullable List this.dataList = list; if (this.dataList == null) { this.dataList = new ArrayList(); }
this.listener = listener; }
@Override public void onBindViewHolder(final H holder, int position) { holder.setData(dataList.get(position)); if (listener != null) { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onItemClick(holder); } }); } }
@Override public int getItemCount() { return dataList.size(); }
public void fillList(List dataList.clear(); dataList.addAll(list); }
public void updateItem(H holder, M data) { dataList.set(holder.getLayoutPosition(), data); }
public M getItem(H holder) { return dataList.get(holder.getLayoutPosition()); }
public M getItem(int position) { return dataList.get(position); }
public void appendItem(M data) { dataList.add(data); }
public void appendList(List dataList.addAll(list); }
public void preposeItem(M data) { dataList.add(0, data); }
public void preposeList(List dataList.addAll(0, list); } },> |
使用範例
使用範例為一種Item和多種Item這兩種型別.
一種Item
執行結果如下圖所示:
單個Item型別的ViewHolder如下:
[程式碼]java程式碼:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class SingleHolder extends BaseHolder
TextView nameView; TextView ageView;
public SingleHolder(ViewGroup parent, @LayoutRes int resId) { super(parent, resId);
nameView = getView(R.id.name_tv); ageView = getView(R.id.age_tv); }
@Override public void setData(Person data) { nameView.setText(data.getName()); ageView.setText(String.valueOf(data.getAge())); } } |
與之對應的Adapter如下:
[程式碼]java程式碼:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
public class SingleAdapter extends BaseAdapter
public SingleAdapter(SingleItemClickListener listener) { super(null, listener); }
@Override public SingleHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new SingleHolder(parent, R.layout.item_single); }
@Override public void onBindViewHolder(final SingleHolder holder, int position) { super.onBindViewHolder(holder, position); holder.nameView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ((SingleItemClickListener) listener).onNameClick(getItem(holder).getName()); } });
holder.ageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ((SingleItemClickListener) listener).onAgeClick(getItem(holder).getAge()); } }); }
public interface SingleItemClickListener extends OnItemClickListener
void onNameClick(String name);
void onAgeClick(int age); } },> |
多種Item
執行結果如下圖所示:
多個Item的ViewHolder的寫法,可以根據Item的View重合度來寫:
1. 如果多個item完全沒有相同的部分,則單獨繼承ViewHolder
2. 如果Item之間有相同的部分,可以抽出來一個父類來繼承ViewHolder
這裡的範例Item是具有重合部分的.模型來自聊天介面.
[程式碼]java程式碼:
1 2 3 4 5 6 7 8 9 |
Holder部分如下: |-ChatHolder //聊天View的Holder,包含公共部分 |-TextHolder //文字訊息的Holder,包含文字特有的部分 |-ImageHolder //圖片訊息的Holder,包含圖片特有的部分.
資料部分如下: |-ChatMsg //代表一條聊天訊息 |-TextMsg //代表一條文字訊息 |-ImageMsg //代表一條圖片訊息 |
ChatHolder程式碼如下,包含傳送者的名稱和時間:
[程式碼]java程式碼:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class ChatHolder extends BaseHolder
TextView senderNameTv; TextView createTimeTv;
public ChatHolder(ViewGroup parent, @LayoutRes int resId) { super(parent, resId);
senderNameTv = getView(R.id.name_tv); createTimeTv = getView(R.id.create_time_tv); }
@Override public void setData(ChatMsg data) { senderNameTv.setText(data.getSenderName()); createTimeTv.setText(data.getCreateTime()); } } |
TextHolder的程式碼如下,包含文字顯示的View
[程式碼]java程式碼:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 |
public class TextHolder extends ChatHolder {
TextView contentTv;
public TextHolder(ViewGroup parent, @LayoutRes int resId) { super(parent, resId);
contentTv = getView(R.id.content_tv); }
@Override public void setData(ChatMsg data) { super.setData(data); contentTv.setText(((TextMsg)data).getText()); } } |
其中的setData()方法預設呼叫父類的方法,可以直接設定傳送者的名稱和時間.
ImageHolder的程式碼如下,包含顯示圖片的View
[程式碼]java程式碼:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 |
public class ImageHolder extends ChatHolder {
ImageView contentIv;
public ImageHolder(ViewGroup parent, @LayoutRes int resId) { super(parent, resId); contentIv = getView(R.id.content_iv); }
@Override public void setData(ChatMsg data) { super.setData(data); contentIv.setImageResource(((ImageMsg)data).getResId()); } } |
最後是我們的Adapter,程式碼不多.
```java
public class ChatAdapter extends BaseAdapter
private static final int VIEW_TEXT = 0;
private static final int VIEW_IMAGE = 1;
public ChatAdapter(OnItemClickListener listener) {
super(null, listener);
}
@Override
public ChatHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ChatHolder holder;
if (viewType == VIEW_IMAGE) {
holder = new ImageHolder(parent, R.layout.item_msg_img_left);
} else {
holder = new TextHolder(parent, R.layout.item_msg_text_left);
}
return holder;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1868/viewspace-2814827/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- RecyclerView的Adapter中attach和detach探索ViewAPT
- RecyclerView-->通用的AdapterViewAPT
- 你還在用Adapter和ViewHolder寫RecyclerView嗎?Out了!APTView
- Android中的RecyclerViewAndroidView
- RecyclerView.Adapter的封裝(RecyclerAdapter)ViewAPT封裝
- Android RecyclerView的ViewHolder和AdaAndroidView
- Kotlin 打造一個RecyclerView的通用Adapter(一)KotlinViewAPT
- Android中RecyclerView與Scrollview組合使用(二)AndroidView
- 【Android Adapter】是時候開啟Adapter新時代了AndroidAPT
- RecyclerView基礎(一)Adapter與Holder的封裝之RvAdapter,RvHolderViewAPT封裝
- 基於 Multitype 開源庫封裝更好用的RecyclerView.Adapter封裝ViewAPT
- Android:打造“萬能”Adapter與ViewHolderAndroidAPTView
- Android TV開發——RecyclerView For TVAndroidView
- MultiItem用法與詳解-優雅的實現多型別RecyclerView Adapter多型型別ViewAPT
- Android開發之平板和橫豎屏適配-RecyclerViewAndroidView
- 說說在 Android 的 RecyclerView 中如何實現下拉刷AndroidView
- 【Android進階】RecyclerView之ItemDecoration(一)AndroidView
- Android開發 - RecyclerView 類詳解AndroidView
- Android開發——說說Adapter那點事AndroidAPT
- 【Android進階】RecyclerView之快取(二)AndroidView快取
- Android入門教程 | RecyclerView使用入門AndroidView
- Android入門教程 | RecyclerView實際使用AndroidView
- Android開發 - (介面卡)Adapter類中BaseAdapter實現類詳細解析AndroidAPT
- Android開發 - (介面卡)Adapter類中SimpleAdapter實現類詳細解析AndroidAPT
- Android recyclerview刪除item重新整理列表AndroidView
- Android RecyclerView 區域性重新整理原理AndroidView
- 【Android進階】RecyclerView之繪製流程(三)AndroidView
- 5.Android(RecyclerView控制元件總結)AndroidView控制元件
- Android實現RecyclerView巢狀流式佈局AndroidView巢狀
- android原生開發recyclerview基礎例項AndroidView
- android adapter.notifyDataSetChanged 資料重新整理無效AndroidAPT
- Android中RecyclerView用法,一步一步教你如何使用RecyclerView以及帶你走過編碼中可能會出現的坑~AndroidView
- [轉]Android輕鬆實現RecyclerView懸浮條AndroidView
- Adapter PatternAPT
- Android RecyclerView實現頭部懸浮吸頂效果AndroidView
- Android RecyclerView多型別佈局卡片解決方案AndroidView多型型別
- Android 時間軸的實現(RecyclerView更簡單)AndroidView
- Android入門教程 | RecyclerView響應子項點選AndroidView