接著上篇进萄,這里想分享ListAdapter已烤、RecyclerView的封裝。眾所周知苛坚,ListAdapter以及RecyclerView都是列表控件比被,Google更推薦大家使用RecyclerView。關(guān)于RecyclerView的基本使用泼舱,不在本篇的討論范圍內(nèi)等缀。
ListAdapter
ListAdapter作為ListView的數(shù)據(jù)適配器,為ListView提供數(shù)據(jù)源娇昙。在我們的頻繁使用中尺迂,發(fā)現(xiàn):對Adapter的編寫主要集中在幾部分:
- 實現(xiàn)
getView(int position, View convertView, ViewGroup parent)
方法 - 數(shù)據(jù)集合的增刪修改,頻繁手動調(diào)用
notifyDataSetChange()
方法
而在getView()
方法中,我們通常會做這么幾件事:
- 設(shè)置布局文件
- 數(shù)據(jù)與控件的綁定
- 控件事件注冊
轉(zhuǎn)化成代碼:
if (convertView == null) {
convertView = View.inflate(context, getLayoutId(), null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = convertView.getTag();
}
bindItem(); //綁定數(shù)據(jù)
setEvent(); //綁定事件
return convertView;
由于Adapter可多個itemType噪裕,因此封裝的時候繽紛兩路蹲盘,RecyclerAdapter的封裝也是如此。
Step1 封裝XListAdapter
膳音,作為所有Adapter的基類召衔,子類可實現(xiàn)getView()
方法
XListAdapter
中主要實現(xiàn)了數(shù)據(jù)集的增刪修改、常用操作严蓖、事件綁定接口 等功能薄嫡。
+ addData()
+ setData()
+ clearData
+ addElement()
+ removeElement()
+ getColor()
+ getDrawable()
+ visible()
+ gone()
+ invisible()
...
Step2 封裝SimpleListAdapter
,實現(xiàn)單viewType的需求
核心如下:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
H holder = null;
T item = data.get(position);
if (convertView == null) {
convertView = View.inflate(context, getLayoutId(), null);
holder = newViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (H) convertView.getTag();
}
convert(holder, item, position);
return convertView;
}
子類則擺脫了這段魔鬼一樣的代碼颗胡,只需要實現(xiàn)這三個方法:
protected abstract H newViewHolder(View convertView); //創(chuàng)建viewHolder
protected abstract int getLayoutId(); //設(shè)置布局資源id
protected abstract void convert(H holder, T item, int position); //數(shù)據(jù)綁定與事件綁定
Step3 事件綁定接口
為了方便事件的統(tǒng)一處理毫深,我抽象了一個抽象類ListItemCallback
public void onItemClick(int position, T model, int tag) {} //單擊
public void onItemLongClick(int position, T model, int tag) {} //長按
參數(shù):
- position : 就是getView中的position,位置
- model : 綁定的數(shù)據(jù)實體
- tag : 事件標(biāo)識毒姨,自己定義
a. 為什么定義的是抽象類哑蔫,而不是接口?
因為接口中的方法需要全部實現(xiàn)弧呐,而抽象類可以選擇性的override闸迷,顯然,我們通常只需要重寫
onItemClick
方法
b. 如何使用呢俘枫?
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getCallback() != null) {
getCallback().onItemClick(position, item, TAG_VIEW);
}
}
});
c. 為什么我不選擇很常見的SparseArray
那種封裝的CommonAdapter
因為我不喜歡那種編碼style腥沽,建議將Adapter單獨類
RecyclerView
RecyclerView的封裝一般體現(xiàn)在:
- 下拉刷新、上拉加載更多
- header鸠蚪、footer
- divider
- ...
鑒于此今阳,我之前搞了個ARecyclerView,主要有這些特性:
- ARecyclerView繼承自RecyclerView茅信,它就是一個封裝了常見功能的RecyclerView盾舌,而不是繼承FrameLayout
- ARecyclerView中實現(xiàn)了Header、Footer蘸鲸,header和Footer可以有多個
- ARecyclerView的每一個header妖谴、footer的viewType是不同的,而大部分開源庫的header酌摇、footer的viewtype是相同的膝舅,其直接后果是界面卡頓
- ARecyclerView可以做出幾乎任何的界面效果,可以取代ScrollView窑多,你只需要使用header或者footer
- ARecyclerView中實現(xiàn)了上拉加載更多铸史,可以自定義加載更多的效果,只需要實現(xiàn)LoadMoreUIHandler接口即可
- ARecyclerView并未實現(xiàn)下拉刷新功能怯伊,您可以選擇SwipeRefreshLayout或者其他的下拉刷新viewGroup包裹琳轿,即你可以自由選擇下拉刷新功能的實現(xiàn)判沟。
- 為了方便自定義使用,特別集成了XRecyclerContentLayout控件崭篡,你可以根據(jù)業(yè)務(wù)進(jìn)行擴(kuò)展挪哄,XRecyclerContentLayout只是一個示例,當(dāng)然也可以滿足絕大部分需求了
由于其實現(xiàn)相對復(fù)雜琉闪,推薦大家可以去看看源碼迹炼,app mudule中是完整的實例
在XDroid
中,我新增了SimpleRecAdapter
颠毙,應(yīng)對單itemType的需求斯入。具體思想和ListAdapter很相似
public abstract class SimpleRecAdapter<T, F extends RecyclerView.ViewHolder> extends RecyclerAdapter<T, F> {
public SimpleRecAdapter(Context context) {
super(context);
}
@Override
public F onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(getLayoutId(), parent, false);
return newViewHolder(view);
}
public abstract F newViewHolder(View itemView);
public abstract int getLayoutId();
}
T 是item的實體類,F(xiàn)是ViewHolder的實體類
下一篇會談?wù)?code>ContentLayout的實現(xiàn)過程蛀蜜。
XDroid項目是我在兩年的開發(fā)中積累的一個Android快速開發(fā)框架刻两,目前包含UI層、緩存滴某、圖片加載磅摹、日志、路由霎奢、Api請求户誓、事件訂閱、工具類等幕侠。下一步會進(jìn)行mvp帝美、rx全家桶、retrofit晤硕、權(quán)限適配等工作证舟。歡迎大家提出寶貴意見,指正不足窗骑。