返回
DataBind抛弃Adapter和ViewHolder,重新定义列表控件交互方式
Android
2023-09-23 19:04:42
现在,在列表控件的使用上,一般都会采用Adapter加ViewHolder的方式,这种方式虽然相对于最初的列表控件使用有了极大的进步,但是仍然存在很多问题,比如:
- ViewHolder生命周期跟Adapter不一致。
- 多种Item布局需要新建多个ViewHolder。
- 不易解耦。
- 占用空间大。
- 无法充分利用DataBinding。
- 继承代价太大。
本文将抛弃Adapter和ViewHolder,重新定义列表控件交互方式,并基于DataBinding实现可扩展且解耦的列表控件解决方案。
ItemViewModel
类似于MVVM模式中ViewModel,这里将Item的layoutId当作Item的viewType,同时包含Item相关的数据,它扮演类似于ViewHolder的角色,因此将其命名为ItemViewModel。
class UserInfo {
private String name;
private int age;
public UserInfo(String name, int age) {
this.name = name;
this.age = age;
}
public int getLayoutId() {
// 根据数据返回不同的layoutId
if (age > 18) {
return R.layout.item_adult;
} else {
return R.layout.item_child;
}
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
DataBindingAdapter
DataBindingAdapter用于将ItemViewModel和layout进行绑定,这样就能在layout中直接使用ItemViewModel中的数据了。
class DataBindingAdapter {
@BindingAdapter("android:layout")
public static void setLayout(View view, int layoutId) {
view.setTag(R.id.layoutId, layoutId);
}
}
BaseRecyclerAdapter
BaseRecyclerAdapter是一个通用的RecyclerAdapter,它实现了基本的Adapter功能,如数据绑定、Item点击事件等。
class BaseRecyclerAdapter extends RecyclerView.Adapter {
private List<ItemViewModel> items;
public BaseRecyclerAdapter(List<ItemViewModel> items) {
this.items = items;
}
@Override
public int getItemViewType(int position) {
return items.get(position).getLayoutId();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
return new BindingViewHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ItemViewModel item = items.get(position);
DataBindingUtil.bind(holder.itemView).setVariable(BR.item, item);
holder.itemView.setOnClickListener(v -> {
// Item点击事件
});
}
@Override
public int getItemCount() {
return items.size();
}
}
使用方式
List<UserInfo> users = new ArrayList<>();
// 省略数据初始化代码
RecyclerView recyclerView = findViewById(R.id.recyclerView);
BaseRecyclerAdapter adapter = new BaseRecyclerAdapter(users);
recyclerView.setAdapter(adapter);
优势
- 生命周期一致。
- 无需创建多个ViewHolder。
- 易于解耦。
- 占用空间小。
- 充分利用DataBinding。
- 继承代价小。
总结
本文抛弃Adapter和ViewHolder,重新定义列表控件交互方式,并基于DataBinding实现可扩展且解耦的列表控件解决方案。这种方式具有生命周期一致、无需创建多个ViewHolder、易于解耦、占用空间小、充分利用DataBinding、继承代价小的优点,在实际项目中具有很强的适用性。