ListView的万能适配器:
https://github.com/JoanZapata/base-adapter-helper
首先介绍QuickAdapter.VH的实现:
static class VH extends RecyclerView.ViewHolder{
private SparseArray<View> mViews;
private View mConvertView;
private VH(View v){
super(v);
mConvertView = v;
mViews = new SparseArray<>();
}
public static VH get(ViewGroup parent, int layoutId){
View convertView = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
return new VH(convertView);
}
public <T extends View> T getView(int id){
View v = mViews.get(id);
if(v == null){
v = mConvertView.findViewById(id);
mViews.put(id, v);
}
return (T)v;
}
public void setText(int id, String value){
TextView view = getView(id);
view.setText(value);
}
}
其中的关键点在于通过SparseArray<View>
存储item view的控件,getView(int id)
的功能就是通过id获得对应的View(首先在mViews中查询是否存在,如果没有,那么findViewById()
并放入mViews中,避免下次再执行findViewById()
)。
QuickAdapter的实现如下:
public abstract class QuickAdapter<T> extends RecyclerView.Adapter<QuickAdapter.VH>{
private List<T> mDatas;
public QuickAdapter(List<T> datas){
this.mDatas = datas;
}
public abstract int getLayoutId(int viewType);
@Override
public VH onCreateViewHolder(ViewGroup parent, int viewType) {
return VH.get(parent,getLayoutId(viewType));
}
@Override
public void onBindViewHolder(VH holder, int position) {
convert(holder, mDatas.get(position), position);
}
@Override
public int getItemCount() {
return mDatas.size();
}
public abstract void convert(VH holder, T data, int position);
static class VH extends RecyclerView.ViewHolder{
private SparseArray<View> mViews;
private View mConvertView;
private VH(View v){
super(v);
mConvertView = v;
mViews = new SparseArray<>();
}
public static VH get(ViewGroup parent, int layoutId){
View convertView = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
return new VH(convertView);
}
public <T extends View> T getView(int id){
View v = mViews.get(id);
if(v == null){
v = mConvertView.findViewById(id);
mViews.put(id, v);
}
return (T)v;
}
public void setText(int id, String value){
TextView view = getView(id);
view.setText(value);
}
}
}
其中:
getLayoutId(int viewType)
是根据viewType返回布局ID。convert()
做具体的bind操作。
就这样,万能适配器实现完成了。
通过万能适配器能通过以下方式快捷地创建一个Adapter:
mAdapter = new QuickAdapter<String>(data) {
@Override
public int getLayoutId(int viewType) {
return R.layout.item;
}
@Override
public void convert(VH holder, String data, int position) {
holder.setText(R.id.text, data);
//holder.itemView.setOnClickListener(); 此处还可以添加点击事件
}
};
是不是很方便。当然复杂情况也可以轻松解决。
mAdapter = new QuickAdapter<Model>(data) {
@Override
public int getLayoutId(int viewType) {
switch(viewType){
case TYPE_1:
return R.layout.item_1;
case TYPE_2:
return R.layout.item_2;
}
}
@Override
public int getItemViewType(int position) {
if(position % 2 == 0){
return TYPE_1;
} else{
return TYPE_2;
}
}
@Override
public void convert(VH holder, Model data, int position) {
int type = getItemViewType(position);
switch(type){
case TYPE_1:
holder.setText(R.id.text, data.text);
break;
case TYPE_2:
holder.setImage(R.id.image, data.image);
break;
}
}
};