/**
* 作者:Pich
* 原文鏈接:http://me.woblog.cn/
* QQ群:129961195
* 微信公眾號(hào):woblog
* Github:https://github.com/lifengsofts
*/
詳解RecyclerView系列文章目錄
概述
如果你經(jīng)常使用RecyclerView,那么你會(huì)發(fā)現(xiàn)他的使用方法比ListView復(fù)雜多了,需要手動(dòng)設(shè)置布局管理器,設(shè)置分割線,設(shè)置條目動(dòng)畫,還得處理點(diǎn)擊事件,長(zhǎng)按事件等。那么這節(jié)課就是要來解決這些問題,封裝一些常用的東西。
添加數(shù)據(jù),ViewHolder泛型
public abstract class BaseRecyclerViewAdapter<D,V extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<V> {
}
可以看到我們給BaseRecyclerViewAdapter添加了兩個(gè)泛型,D用來標(biāo)示數(shù)據(jù)的類型,也就是bindData這個(gè)方法中藥顯示的數(shù)據(jù)類型,添加他的目的是,我們還要在這個(gè)類添加getData這樣的方法,這樣在需要用數(shù)據(jù)的時(shí)候不需要將Object類型轉(zhuǎn)為自己的類型了,后面的V標(biāo)示ViewHolder的類型,這樣就可以在onCreateViewHolder,onBindViewHolder拿到自己當(dāng)時(shí)定義的類型,免去了強(qiáng)轉(zhuǎn)。
添加數(shù)據(jù)源容器
我們添加一個(gè)容器的好處是,好處就是不會(huì)空指針。同時(shí)可以在父類實(shí)現(xiàn)getItemCount這樣的通用方法
private List<D> data = new ArrayList<>();
public void addData(List<D> data) {
this.data.addAll(data);
notifyItemRangeChanged(data.size() - 1, data.size());
}
public void setData(List<D> data) {
this.data.clear();
this.data.addAll(data);
notifyDataSetChanged();
}
public D getData(int position) {
return data.get(position);
}
@Override
public int getItemCount() {
return data.size();
}
@Override
public long getItemId(int position) {
return position;
}
添加了一些常用的方法。方便開發(fā)的的時(shí)候快速使用。
添加點(diǎn)擊事件
定義接口這里就不貼代碼了,直接上重要的代碼。
@Override
public void onBindViewHolder(final V holder, final int position) {
//點(diǎn)擊事件
if (onItemClickListener != null) {
holder.itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClickListener!=null) {
onItemClickListener.onItemClick(holder,position);
}
}
});
}
//常按事件
if (onItemLongClickListener != null) {
holder.itemView.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return onItemLongClickListener.onItemLongClick(holder,position);
}
});
}
}
添加所有的ViewHolder的父類
這樣做的目的是,所有的ViewHolder都繼承自我們的類,這樣一來我們就可以在父類使用像butterknife這樣的框架。
public abstract class ViewHolder extends RecyclerView.ViewHolder{
public ViewHolder(View itemView) {
super(itemView);
//TODO 可以在這里加入butterknife這樣的框架。
}
@Nullable
public final View findViewById(@IdRes int id) {
return itemView.findViewById(id);
}
}
使用自己的Adapter
public class UseCustomAdapter extends BaseRecyclerViewAdapter<String,UseCustomAdapter.ViewHolder> {
public UseCustomAdapter(Context context) {
super(context);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(getInflater().inflate(android.R.layout.simple_list_item_1,parent,false));
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
holder.bindData(getData(position));
}
class ViewHolder extends BaseRecyclerViewAdapter.ViewHolder{
private final TextView tv;
public ViewHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(android.R.id.text1);
}
public void bindData(String data) {
tv.setText(data);
}
}
}
可以看到這次少了很多任務(wù),這個(gè)Adapter類也就簡(jiǎn)化了很多,從而提高開發(fā)效率。
RecyclerView rv= (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
UseCustomAdapter useCustomAdapter = new UseCustomAdapter(this);
rv.setAdapter(useCustomAdapter);
ArrayList<String> data = new ArrayList<>();
for (int i = 0; i < 50; i++) {
data.add("Item " + i);
}
useCustomAdapter.setData(data);
下一期講解如果實(shí)現(xiàn)類似ListView的EmptyView效果。并提供必要的封裝。
完整版代碼,已被不時(shí)之需。請(qǐng)查看原文有字?jǐn)?shù)限制。