Android知识

使用DataBinding实现方便的RecyclerView.A

2017-12-06  本文已影响41人  真胖大海

注意:阅读本文需要DataBinding基础

一. 直接继承RecylcerView.Adpater(如下,MyAdapterMultiType),会出现大量的模板代码。

说明

  1. 创建类似的ViewHolder类
  2. 在ViewHolder中获取各个控件的应用
  3. onCreateViewHolder 创建ViewHolder的实例
  4. 在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简化代码

参考文章

说明

  1. 一个通用的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;
        }
    }
  1. 这里使用布局文件的id直接作为viewType的值返回
  @Override
  public int getItemViewType(int position) {

      return getLayoutIdForPosition(position);
  }
  1. 在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设置为启动页

上一篇下一篇

猜你喜欢

热点阅读