使用DataBinding实现方便的RecyclerView.A
2017-12-06 本文已影响41人
真胖大海
注意:阅读本文需要DataBinding基础
一. 直接继承RecylcerView.Adpater(如下,MyAdapterMultiType),会出现大量的模板代码。
说明
- 创建类似的ViewHolder类
- 在ViewHolder中获取各个控件的应用
- onCreateViewHolder 创建ViewHolder的实例
- 在onBindViewHolder绑定数据
代码
public class MyAdapterMultiType extends RecyclerView.Adapter{
public static final int TYPE_ONE=1;
public static final int TYPE_TWO=2;
private List<String> mNames;
public MyAdapterMultiType(List<String> names) {
this.mNames=names;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType==1) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_item_type_one, parent, false);
OneViewHolder myViewHolder=new OneViewHolder(view);
return myViewHolder;
}else{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_item_type_two, parent, false);
TwoViewHolder myViewHolder=new TwoViewHolder(view);
return myViewHolder;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof OneViewHolder){
OneViewHolder oneViewHolder= (OneViewHolder) holder;
oneViewHolder.mTextView.setText(mNames.get(position));
}else if(holder instanceof TwoViewHolder){
TwoViewHolder twoViewHolder= (TwoViewHolder) holder;
twoViewHolder.mTextView.setText(mNames.get(position));
}
}
@Override
public int getItemCount() {
return mNames.size();
}
@Override
public int getItemViewType(int position) {
if(position%2==0){
return TYPE_ONE;
}
return TYPE_TWO;
}
class OneViewHolder extends RecyclerView.ViewHolder{
TextView mTextView;
public OneViewHolder(View itemView) {
super(itemView);
mTextView= (TextView) itemView.findViewById(R.id.text_view);
}
}
class TwoViewHolder extends RecyclerView.ViewHolder{
TextView mTextView;
public TwoViewHolder(View itemView) {
super(itemView);
mTextView= (TextView) itemView.findViewById(R.id.text_view);
}
}
}
二. 使用DataBinding简化代码
说明
- 一个通用的MyViewHolder,持有一个DataBinding,因为DataBinding会持有视图,所以不需要写findXXXBy()来获取每一个视图对象了,同时MyViewModel暴露一个bindViewModel(Object o)方法,来给DataBinding布局文件绑定数据。
public static class MyViewHolder extends RecyclerView.ViewHolder {
private final ViewDataBinding binding;
public MyViewHolder(ViewDataBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
public void bindViewModel(Object viewModel) {
binding.setVariable(BR.viewmodel, viewModel);
binding.executePendingBindings();
}
public ViewDataBinding getBinding() {
return binding;
}
}
- 这里使用布局文件的id直接作为viewType的值返回
@Override
public int getItemViewType(int position) {
return getLayoutIdForPosition(position);
}
- 在onCreateViewHolder中使用viewType(其实是布局文件的id),创建ViewDataBinding,最终创建MyViewHolder
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
LayoutInflater layoutInflater =
LayoutInflater.from(parent.getContext());
ViewDataBinding binding = DataBindingUtil.inflate(
layoutInflater, viewType, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(binding);
initViewHolder(myViewHolder,viewType);
onCreatedViewHolder(myViewHolder);
return myViewHolder;
}
4.在onBindViewHolder中后去数据,包装成ViewModel,调用MyViewHolder.bindViewModel(Object o)方法给ViewDataBinding布局文件绑定数据
public void onBindViewHolder(MyViewHolder holder,
int position) {
Object viewModel = getViewModelForPosition(holder, position);
holder.bindViewModel(viewModel);
bindOtherViewModel(holder, position);
}
代码
public abstract class RecyclerViewBaseAdapter<T> extends RecyclerView.Adapter<RecyclerViewBaseAdapter.MyViewHolder> {
private static final String TAG = "RecyclerViewBaseAdapter";
List<T> mDataList;
private RemoveInterface mRemoveInterface;
public RecyclerViewBaseAdapter() {
this(new ArrayList<T>(0));
}
public RecyclerViewBaseAdapter(List<T> mDataList) {
this.mDataList = mDataList;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
LayoutInflater layoutInflater =
LayoutInflater.from(parent.getContext());
ViewDataBinding binding = DataBindingUtil.inflate(
layoutInflater, viewType, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(binding);
initViewHolder(myViewHolder,viewType);
onCreatedViewHolder(myViewHolder);
return myViewHolder;
}
public void initViewHolder(MyViewHolder myViewHolder,
int viewType){}
public void onCreatedViewHolder(MyViewHolder myViewHolder){
}
@Override
public void onBindViewHolder(MyViewHolder holder,
int position) {
Object viewModel = getViewModelForPosition(holder, position);
holder.bindViewModel(viewModel);
}
@Override
public int getItemViewType(int position) {
return getLayoutIdForPosition(position);
}
protected abstract Object getViewModelForPosition(MyViewHolder viewHolder, int position);
protected abstract int getLayoutIdForPosition(int position);
protected int getAllCount() {
return mDataList != null ? mDataList.size() : 0;
}
@Override
public int getItemCount() {
return getAllCount();
}
public T getItem(int posotion) {
return mDataList.get(posotion);
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
private final ViewDataBinding binding;
public MyViewHolder(ViewDataBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
public void bindViewModel(Object viewModel) {
binding.setVariable(BR.viewmodel, viewModel);
binding.executePendingBindings();
}
public ViewDataBinding getBinding() {
return binding;
}
}
public void setDatas(List<T> datas) {
mDataList = datas;
notifyDataSetChanged();
}
public List<T> getDataList() {
return mDataList;
}
}
使用实例
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
RecyclerViewBaseAdapter recyclerViewBaseAdapter;
recyclerView.setAdapter(recyclerViewBaseAdapter = new RecyclerViewBaseAdapter<String>() {
@Override
protected Object getViewModelForPosition(MyViewHolder viewHolder, int position) {
if (position % 2 == 0) {
return new SimpleItemOneViewModel(getItem(position));
} else {
return new SimpleItemTwoViewModel(getItem(position));
}
}
@Override
protected int getLayoutIdForPosition(int position) {
if (position % 2 == 0) {
return R.layout.simple_one_item;
} else {
return R.layout.simple_two_item;
}
}
});
recyclerViewBaseAdapter.setDatas(new ArrayList(Arrays.asList("jack","lord","land")));
完整代码
运行时将DataBindingRecyclerViewActivity设置为启动页