美文网首页Android知识
使用DataBinding实现方便的RecyclerView.A

使用DataBinding实现方便的RecyclerView.A

作者: 真胖大海 | 来源:发表于2017-12-06 14:22 被阅读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设置为启动页

    相关文章

      网友评论

        本文标题:使用DataBinding实现方便的RecyclerView.A

        本文链接:https://www.haomeiwen.com/subject/pmokixtx.html