基类RecyclerViewAdapter以及BaseViewHolder。减少适配器的重复代码量

对于adapter我们在熟悉不过了。往往适配器多了也写着烦,都是堆叠代码。。。


为了减少代码量,写一个合理的基类还是挺不错的。


正好,整合最近网上看到的一些资料,以及现在项目中使用的,也来一发。。。


首先还是先来看一下对比的最终效果:


1、正常的RecyclerViewAdapter的写法

public class BaseAdapter2 extends RecyclerView.Adapter<BaseAdapter2.ViewHolder> {


    private Context context;
    private Fragment fragment;
    private LayoutInflater mLayoutInflater;
    private List<String> mList;

    public BaseAdapter2(Fragment fragment, List<String> mList) {
        this.fragment = fragment;
        this.mList = mList;
        this.context = fragment.getActivity();
        mLayoutInflater = LayoutInflater.from(context);
    }


    /**
     * ItemClick的回调接口 ( 如果还有长按监听还得另加 )
     */
    public interface  OnItemClickListener{
        void OnItemClick(View view, int position);
    }


    private OnItemClickListener mOnItemClickListener;


    public void setOnItemClickListener(OnItemClickListener mOnItemClickListener){
        this.mOnItemClickListener=mOnItemClickListener;
    }


    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mLayoutInflater.inflate(R.layout.item_goods_order, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }


    /**
     * 绑定数据
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {

        if(mOnItemClickListener!=null){
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mOnItemClickListener.OnItemClick(holder.itemView,position);

                }
            });
        }

//此处省略一堆绑定数据


    }

    @Override
    public int getItemCount() {
        return mList == null ? 0 : mList.size();
    }


    public static class ViewHolder extends RecyclerView.ViewHolder {

 @Optional

TextView tv;

//此处省略一堆

        public ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.inject(this, itemView);
        }
    }


}


2、简化后的写法

public class ListRcvAdapter extends BaseRcvAdapter<BaseViewHolder> {

   public ListRcvAdapter(Context context, List<Object> mList) {
      super(context, mList);
   }

   public ListRcvAdapter(Fragment fragment, List<Object> mList) {
      super(fragment, mList);
   }

   @Override
   public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      View view = mLayoutInflater.inflate(R.layout.item_list, parent, false);
      return new BaseViewHolder(context, view);
   }

   @Override
   public void onBindViewHolder(BaseViewHolder holder, final int position) {
      super.onBindViewHolder(holder, position);
      //绑定数据
      holder.setText(R.id.tv, mList.get(position).toString())
            .setText(R.id.delete, "");

      //编辑模式
      holder.views.get(R.id.delete).setVisibility(isEdit ? View.VISIBLE : View.GONE);
      //点击事件
      holder.views.get(R.id.delete).setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            remove(position);
         }
      });
   }
}
 
 

如果适配器一多,每次都需要些这么多重复代码的话。


从几个方面开始优化的:新建一个BaseRcvAdapter继承RecyclerView.Adapter

1、接口,可以把item的点击事件和长按事件放在基类里。 重写他的onBindViewHolder方法

protected OnItemClickListener onItemClickListener;          //单击
protected View.OnLongClickListener onLongClickListener;     //长按

public interface OnItemClickListener {
   void onItemClick(View view, int position);
}

public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
   this.onItemClickListener = onItemClickListener;
}

public void setOnItemLongClickListener(View.OnLongClickListener onLongClickListener) {
   this.onLongClickListener = onLongClickListener;
}
@Override
public void onBindViewHolder(VH holder, final int position) {
   if (onItemClickListener != null) {
      holder.itemView.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            onItemClickListener.onItemClick(v, position);
         }
      });
   }

   if (onLongClickListener != null) {
      holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
         @Override
         public boolean onLongClick(View v) {
            onLongClickListener.onLongClick(v);
            return true;
         }
      });
   }
}
2、一些全局变量(Fragment、Context、list<Object>数据、LayoutInflater)放在基类里,并重写他的getItemCount()方法

3、可能考虑到长按的时候是整个RecyclerView的所有条目进入编辑模式。也可以考虑写入基类

protected boolean isEdit = false;                           //是否进入编辑模式
public void setEdit(boolean isEdit) {
   this.isEdit = isEdit;
   notifyDataSetChanged();
}
public boolean getEdit() {
   return isEdit;
}
4、对于数据的删除和添加

public void remove(int position) {
   mList.remove(position);
   notifyItemRemoved(position);
}
public void add(Integer position, Object item) {
   mList.add(position, item);
   notifyItemInserted(position);
}
public void add(Object item) {
   mList.add(item);
   notifyDataSetChanged();
}
5、来看看ViewHolder的写法

public class BaseViewHolder extends RecyclerView.ViewHolder {

   protected SparseArray<View> views;
   protected Context context;
   protected Resources resources;
   protected View convertView;

   public BaseViewHolder(Context context, View itemView) {
      super(itemView);
      this.context = context;
      this.convertView = itemView;
      resources = context.getResources();
      this.views = new SparseArray<View>();
   }

   /**
    * 设置TextView内容
    *
    * @param viewId
    * @param value
    * @return
    */
   public BaseViewHolder setText(int viewId, CharSequence value) {
      TextView view = getView(viewId);
      if (!TextUtils.isEmpty(value)) {
         view.setText(value);
      }
      return this;
   }

   public BaseViewHolder setText(int viewId, int value) {
      TextView view = getView(viewId);
      view.setText(resources.getString(value));
      return this;
   }

   /**
    * 设置SimpleDraweeView的图片
    *
    * @param viewId
    * @param url
    * @return
    */
   public BaseViewHolder setSimpleDraweeView(int viewId, String url) {
      SimpleDraweeView view = getView(viewId);
      if (!TextUtils.isEmpty(url)) {
         view.setImageURI(Uri.parse(url));
      }
      return this;
   }

   /**
    * 设置开/关两种状态的按钮
    *
    * @param viewId
    * @param checked
    * @return
    */
   public BaseViewHolder setCheck(int viewId, boolean checked) {
      View view = getView(viewId);
      if (view instanceof CompoundButton) {
         ((CompoundButton) view).setChecked(checked);
      } else if (view instanceof CheckedTextView) {
         ((CheckedTextView) view).setChecked(checked);
      }
      return this;
   }

   /**
    * 设置adapter(ListView/GridView都继承AdapterView)
    *
    * @param viewId
    * @param adapter
    * @return
    */
   public BaseViewHolder setAdapter(int viewId, Adapter adapter) {
      AdapterView view = getView(viewId);
      view.setAdapter(adapter);
      return this;
   }

   /**
    * 设置Rcv的adapter
    *
    * @param viewId
    * @param adapter
    * @return
    */
   public BaseViewHolder setRcvAdapter(int viewId, RecyclerView.Adapter adapter) {
      RecyclerView view = getView(viewId);
      view.setAdapter(adapter);
      return this;
   }

   /**
    * 得到相信的view
    *
    * @param viewId view的id
    * @param <T>    view本身
    * @return
    */
   public <T extends View> T getView(int viewId) {
      View view = views.get(viewId);
      if (view == null) {
         view = convertView.findViewById(viewId);
         views.put(viewId, view);
      }
      return (T) view;
   }
   //使用 SparseArray 做缓存
   //此处还能继续添加自己想要的控件的初始化赋值等,自行添加。注意:图片我用的是Fresco,可以自己修改
}

具体代码,可查看:https://github.com/zxp19920626/ZxpDemo    里面的BaseRcvAdapter和BaseViewHolder。。。用法可查看ListRcvAdapter






  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值