我们在写列表的时候都要用到适配器Adapter,如果每一个列表都去创建一个Adapter以及相应的ViewHolder,则重复代码太多,效率低下,为了改变这种情况,我们需要做到尽可能多的复用Adapter以及ViewHolder,我们称之为万能适配器。网上也有各种各样实现的万能适配器,本文将给出一种万能适配器实现方案。
在自定义Adapter时,都需要继承系统的适配器RecyclerView.Adapter,以及系统的RecyclerView.ViewHolder。以下是定义的万能适配器代码:
public abstract class BaseListAdapter<T ,VH extends BaseListViewHolder> extends RecyclerView.Adapter<VH> {
private List<T> datas;
public void setDatas(List<T> datas) {
this.datas = datas;
}
public List<T> getDatas() {
if (null == datas) {
return new ArrayList<>();
}
return datas;
}
@NonNull
@Override
public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return onCreateMyViewHolder(parent,viewType);
}
@Override
public void onBindViewHolder(@NonNull VH holder, int position) {
onBindMyViewHolder(holder,position);
}
public abstract VH onCreateMyViewHolder(ViewGroup parent,int viewType);
public abstract void onBindMyViewHolder(VH holder , int position);
@Override
public int getItemCount() {
return datas.size();
}
}
范型T是定义的数据类型,VH可以自定义的ViewHolder,但是必须要继承自BaseListViewHolder,当然VH也可以是BaseListViewHolder,BaseListViewHolder是继承自系统ViewHolder的,后面会给出实现方式。代码中定义了两个抽象方法
public abstract VH onCreateMyViewHolder(ViewGroup parent,int viewType)、public abstract void onBindMyViewHolder(VH holder , int position),VH都是我们可以自定义的ViewHolder,onCreateMyViewHolder创建VH,由系统方法onCreateViewHolder调用;onBindMyViewHolder绑定数据并渲染UI,由系统onBindViewHolder调用。
BaseListViewHolder实现如下:
public class BaseListViewHolder extends RecyclerView.ViewHolder {
// 缓存子View,减少findViewById的次数
private SparseArray<View> mViews;
public BaseListViewHolder(@NonNull View itemView) {
super(itemView);
mViews = new SparseArray<>();
}
public <V extends View> V getView(int viewId){
View view = mViews.get(viewId);
if (null==view){
view = itemView.findViewById(viewId);
mViews.put(viewId,view);
}
return (V)view;
}
}
SparseArray<View> mViews用来缓存View,当viewId相同时就直接从parseArray<View> mViews取出,避免重复findViewById,提高列表性能。
BaseListAdapter的使用示例如下:
public class TestActivity extends Activity {
private BaseListAdapter<DataClass, BaseListViewHolder> mAdapter;
private RecyclerView mRecyclerView;
private List<DataClass> datas;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRecyclerView = new RecyclerView(this);
setContentView(mRecyclerView);
initData();
initView();
}
private void initData(){
datas = new ArrayList<>();
for (int i=0;i<2;i++){
DataClass data = new DataClass();
data.setType(i);
data.setData("data"+i);
datas.add(data);
}
}
private void initView(){
mAdapter = new BaseListAdapter<DataClass, BaseListViewHolder>() {
@Override
public int getItemViewType(int position) {
return getDatas().get(position).getType();
}
@Override
public BaseListViewHolder onCreateMyViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == 0){
view = LayoutInflater.from(TestActivity.this).inflate(R.layout.layout1, parent, false);
}else {
view = LayoutInflater.from(TestActivity.this).inflate(R.layout.layout2, parent, false);
}
return new BaseListViewHolder(view);
}
@Override
public void onBindMyViewHolder(BaseListViewHolder holder, int position) {
TextView textView;
if (getDatas().get(position).getType() == 0){
textView = holder.getView(R.id.textView1);
}else {
textView = holder.getView(R.id.textView2);
}
textView.setText(getDatas().get(position).getData());
}
};
mAdapter.setDatas(datas);
mRecyclerView.setAdapter(mAdapter);
}
public class DataClass{
private int type;
private String data;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getData() {
return null == data ? "" : data;
}
public void setData(String data) {
this.data = data;
}
}
}
示例代码中layout1和layout2都只是放了一个TextView的xml文件,很简单,所以就不给出xml文件了,示例代码很简单,就不做分析了。
,