緣由
最近項目我在項目中使用了RecyclerView代替了ListView质帅。
其實,怎么說呢?就是懶,想少寫代碼,所以想研究一下能否簡化一下.
分兩種
-
第一種支持Butterknife(黃油刀)快速生成ViewHolder
封裝的父類RvBaseAdapter
public abstract class RvBaseAdapter<T, V extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<V> {
public List<T> data;
public Context context;
public RvBaseAdapter(List<T> data, Context context) {
this.data = data;
this.context = context;
}
@Override
public int getItemCount() {
return data == null ? 0 : data.size();
}
@Override
public V onCreateViewHolder(ViewGroup parent, int viewType) {
return onCreateViewHolder(LayoutInflater.from(context).inflate(getLayout(viewType), null));
}
/**
* 獲得布局文件
* @return
*/
protected abstract int getLayout(int viewType);
/**
* 創(chuàng)建一個ViewHolder
* @param convertView View
* @return
*/
protected abstract V onCreateViewHolder(View convertView);
/**
* 綁定ViewHolder
* @param holder ViewHolder
* @param position 位置
*/
@Override
public abstract void onBindViewHolder(V holder, int position);
}
子類使用實例方法
public class RvTestAdapter extends RvBaseAdapter<AdapterBean,RvTestAdapter.ViewHolder> {//要傳入兩個泛型進去
public RvTestAdapter(List<AdapterBean> data, Context context) {
super(data, context);
}
@Override
protected int getLayout(int viewType) { //獲得布局文件
return R.layout.rv_adapter;
}
@Override
protected ViewHolder onCreateViewHolder(View convertView) {//創(chuàng)建一個onCreateViewHolder
return new ViewHolder(convertView);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {//綁定onBindViewHolder
holder.mT1.setText(data.get(position).getName());//綁定數(shù)據(jù)和控件之間
ImageLoader.getInstance().displayCircleImage(context,R.mipmap.ic_launcher,holder.mI1);
...
}
static class ViewHolder extends RecyclerView.ViewHolder {//用插件快速生成的ViewHolder 诀浪,這樣很方便
@BindView(R.id.T_1)
TextView mT1;
@BindView(R.id.I_1)
ImageView mI1;
ViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
}
-
第二種情況不用寫ViewHolder
封裝的父類RvBaseAdapter于个,里面封住了一個ViewHolder模她,動態(tài)查找控件
public abstract class RvAdapter<T> extends RecyclerView.Adapter<RvAdapter.ViewHolder> {
public List<T> data;
public Context context;
public RvAdapter(List<T> data, Context context) {
this.data = data;
this.context = context;
}
@Override
public int getItemCount() {
return data == null ? 0 : data.size();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(context).inflate(getLayout(viewType), null);
ViewHolder holder = new ViewHolder(itemView, context);
return holder;
}
/**
* 獲得布局文件
*
* @return
*/
protected abstract int getLayout(int viewType);
public class ViewHolder extends RecyclerView.ViewHolder {
private HashMap<Integer, View> views;
private Context context;
public ViewHolder(View itemView, Context context) {
super(itemView);
this.views = new HashMap<>();//保存View的map
this.context = context;
}
public <T extends View> T findById(int id) { //查找控件
View view = views.get(id);
if (view == null) {
view = itemView.findViewById(id);
views.put(id, view);
}
return (T) view;
}
public RvAdapter.ViewHolder setText(int id, String txt) {//封裝常用的設(shè)置數(shù)據(jù)方法
TextView tv = findById(id);
tv.setText(txt);
return this;
}
public RvAdapter.ViewHolder setOnClickListener(int id, View.OnClickListener listener) {//設(shè)置監(jiān)聽
View view = findById(id);
view.setOnClickListener(listener);
return this;
}
public RvAdapter.ViewHolder setImage(int id, String url) {
ImageView img = findById(id);
ImageLoader.getInstance().displayCircleImage(context, url, img);
return this;
}
···//這里可以擴展添加常用的方法
public View getItemView() {
return itemView;
}
}
}
子類使用實例方法
看起來是不是很簡潔缭保,竊喜~
public class RvTestAdapter extends RvAdapter<AdapterBean> {
public RvTestAdapter(List<AdapterBean> data, Context context) {
super(data, context);
}
@Override
protected int getLayout(int viewType) {
return R.layout.rv_adapter;
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.setText(R.id.T_1, data.get(position).getName())
.setText(R.id.T_1, data.get(position).getName())
.setImage(R.id.I_1, data.get(position).getName())
.setImage(R.id.I_1, data.get(position).getName())
.setOnClickListener(R.id.T_2, new View.OnClickListener() {
@Override
public void onClick(View v) {
App.getInstance().showToast(data.get(position).getName());
}
});
}
}
結(jié)語:封裝之后代碼量顯著減少遥缕,看上去很簡潔
其實還可以在里面添加擴展功能 ==》
public void remove(int position) {
data.remove(position);
notifyItemRemoved(position);
}
public void add(int position, T item) {
data.add(position, item);
notifyItemInserted(position);
}