Android UI篇——RecyclerView BaseAdapter封装

Android开发中RecyclerView几乎全面取代ListView、GridView,是日常开发中使用频率比较高的控件,谈到RecyclerView那Adapter必不可少,但是在开发中使用Android API提供的Adapter需要写不少重复的代码,所以有必要对其做一定的封装,以减少开发工作量,下面是我针对RecyclerView Adapter封装的一个BaseAdapter和BaseViewHolder。

优点:

  1. 基本和onCreateViewHolder、getItemCount等方法说拜拜
  2. 统一设置Item监听和ItemView监听并能按需实现
  3. 统一封装控件各种常用设置方法,只需直接使用即可,eg设置标题 在bind方法中viewHolder.setText(R.id.tv,"标题")即可
  4. 统一封装Adapter常用方法,子类直接使用即可
  5. 其他
代码如下(代码中有相应的注释,有不明白的地方直接查看即可):
BaseAdapter:
/**
 * BaseAdapter
 * @param 
 */
public abstract class BaseAdapter extends RecyclerView.Adapter {

    protected List mDataList;
    protected Context mContext;
    @LayoutRes
    protected int mItemLayoutRes;
     /**
     * 为了在一个Activity/Fragment有多个Adapter时区分不同类型
     */
    protected Object mType;
    private BaseViewHolder.OnItemClickListener mOnItemClickListener;
    private BaseViewHolder.OnItemViewClickListener mOnItemViewClickListener;
    protected LayoutInflater mLayoutInflater;

    public BaseAdapter(Context context, @LayoutRes int itemLayoutRes, @Nullable Object type) {
        mContext = context;
        mItemLayoutRes = itemLayoutRes;
        mType = type;
        mDataList = new ArrayList<>();
        mLayoutInflater = LayoutInflater.from(context);
    }

    /**
     * 设置监听
     * @param onItemClickListener
     */
    public void setOnItemClickListener(BaseViewHolder.OnItemClickListener onItemClickListener) {
        mOnItemClickListener = onItemClickListener;
    }

    public void setOnItemViewClickListener(BaseViewHolder.OnItemViewClickListener onItemViewClickListener) {
        mOnItemViewClickListener = onItemViewClickListener;
    }

    /**
     * 适合分页加载
     *
     * @param dataList
     * @param isFirst
     */
    public void refreshAdapter(@NonNull List dataList, boolean isFirst) {
        if (isFirst) {//第一次添加
            mDataList.clear();
            mDataList.addAll(dataList);
            notifyDataSetChanged();
        } else {
            int preSize = mDataList.size();
            mDataList.addAll(dataList);
            notifyItemRangeInserted(preSize, Config.LOAD_PAGE_SIZE);
        }
    }

    /**
     * 适合初始加载
     *
     * @param dataList
     */
    public void refreshAdapter(@NonNull List dataList) {
        if (dataList == null) return;
        mDataList.clear();
        mDataList.addAll(dataList);
        notifyDataSetChanged();
    }

    public void removeItem(int position) {
        mDataList.remove(position);
        notifyItemRemoved(position);
    }

    public void clearAdaper() {
        mDataList.clear();
        notifyDataSetChanged();
    }

    public boolean isNonEmpty() {
        return !mDataList.isEmpty();
    }

    public List getDataList() {
        return mDataList;
    }

    public ImageLoader getImageLoader() {
        return ImageLoader.getInstance();
    }

    public void refreshAdapter(int position) {
        notifyItemChanged(position);
    }

    public T getItemDataByPosition(@IntRange(from = 0) int position) {
        return mDataList.get(position);
    }

    public Context getContext() {
        return mContext;
    }

    @NonNull
    @Override
    public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        View layout = mLayoutInflater.inflate(mItemLayoutRes, viewGroup, false);
        return new BaseViewHolder(layout);
    }

    @Override
    public void onBindViewHolder(@NonNull BaseViewHolder t, int i) {
        T itemData = mDataList.get(i);
        setOnItemClickListener(t, itemData, i);
        bind(t, itemData, i);
    }


    protected void setOnItemClickListener(@NonNull final BaseViewHolder viewHolder, final T itemData, final int position) {
        /**
         * 为了避免单独设置监听,只要Activity设置了监听这里就直接转换设置了
         */
        if (mContext instanceof BaseViewHolder.OnItemClickListener) {
            mOnItemClickListener = (BaseViewHolder.OnItemClickListener) mContext;
        }
        if (mOnItemClickListener != null) {
            viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mOnItemClickListener.onItemClick(viewHolder, position, itemData, mType);
                }
            });
            viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    mOnItemClickListener.onItemLongClick(viewHolder, position, itemData, mType);
                    return true;
                }
            });
        }
    }

    protected void setOnItemViewClickListener(@NonNull final BaseViewHolder viewHolder, View view, final T itemData, final int position) {
        if (mContext instanceof BaseViewHolder.OnItemViewClickListener) {
            mOnItemViewClickListener = (BaseViewHolder.OnItemViewClickListener) mContext;
        }
        if (mOnItemViewClickListener != null) {
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mOnItemViewClickListener.onItemViewClick(viewHolder, view, position, itemData, mType);
                }
            });
            view.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    mOnItemViewClickListener.onItemViewLongClick(viewHolder, view, position, itemData, mType);
                    return true;
                }
            });

        }
    }

    @Override
    public int getItemCount() {
        return mDataList.size();
    }

    /**
     * 子类实现并在里填充数据
     *
     * @param viewHolder
     * @param itemData
     * @param position
     */
    public abstract void bind(@NonNull BaseViewHolder viewHolder, T itemData, int position);
}
BaseViewHolder:

/**
 * BaseViewHolder
 */
public class BaseViewHolder extends RecyclerView.ViewHolder {
    private SparseArray mViewSparseArray;

    public BaseViewHolder(View itemView) {
        super(itemView);
    }

    public interface OnItemClickListener {
        void onItemClick(BaseViewHolder viewHolder, int position, T itemData, Object type);

        void onItemLongClick(BaseViewHolder viewHolder, int position, T itemData, Object type);
    }

    public interface OnItemViewClickListener {
        void onItemViewClick(BaseViewHolder viewHolder, View view, int position, T itemData, Object type);

        void onItemViewLongClick(BaseViewHolder viewHolder, View view, int position, T itemData, Object type);
    }

    /**
     * 获取Item里的控件
     * @param viewId
     * @param 
     * @return
     */
    public  V getView(@IdRes int viewId) {
        if (mViewSparseArray == null) {
            mViewSparseArray = new SparseArray<>();
        }
        View view = mViewSparseArray.get(viewId);
        if (view == null) {
            view = itemView.findViewById(viewId);
            mViewSparseArray.put(viewId, view);
        }
        return (V) view;
    }
    /****************************************各种设置方法******************************************************/
    public void setText(@IdRes int viewId, @StringRes int text) {
        this.getView(viewId).setText(text);
    }

    public void setText(@IdRes int viewId, String text) {
        this.getView(viewId).setText(text);
    }

    public void setImageBitmap(@IdRes int viewId, Bitmap bitmap) {
        this.getView(viewId).setImageBitmap(bitmap);
    }

    public void setImageResource(@IdRes int viewId, @DrawableRes int resId) {
        this.getView(viewId).setImageResource(resId);
    }

    public void setBackgroundColor(@IdRes int viewId, @ColorRes int colorRes) {
        this.getView(viewId).setBackgroundColor(Utils.getColor(colorRes));
    }

    public void setBackground(@IdRes int viewId, @DrawableRes int resId) {
        this.getView(viewId).setBackground(Utils.getDrawable(resId));
    }

    public void setBackgroundAlpha(@IdRes int viewId, @IntRange(from = 0, to = 255) int alpha) {
        this.getView(viewId).getBackground().mutate().setAlpha(alpha);
    }

    public void setVisibility(@IdRes int viewId, boolean isShow) {
        if (isShow) {
            this.getView(viewId).setVisibility(View.VISIBLE);
        } else {
            this.getView(viewId).setVisibility(View.GONE);
        }
    }
}

代码没有什么难点,这里再举一个使用栗子

Adapter使用:
public class ExhibitionAdapter extends BaseAdapter {
    public ExhibitionAdapter(Context context, int itemLayoutRes, @Nullable Object type) {
        super(context, itemLayoutRes, type);
    }

    @Override
    public void bind(@NonNull BaseViewHolder viewHolder, ExhibitionResponseListBody itemData, int position) {

        //星级评价
        LinearLayout liEvaluate = viewHolder.getView(R.id.li_item_exhibition_spot_evaluate);
        liEvaluate.removeAllViews();
        int star = itemData.getStar();
        if (star > Config.EXHIBITION_STAR || star < 0) {
            star = Config.EXHIBITION_STAR;
        }

        for (int i = 0; i < Config.EXHIBITION_STAR; i++) {
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams((int) Utils.getDimen(R.dimen.spot_evaluate_width)
                    , (int) Utils.getDimen(R.dimen.spot_evaluate_height));
            layoutParams.rightMargin = (int) Utils.getDimen(R.dimen.spot_evaluate_margin);
            ImageView imageView = new ImageView(getContext());
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            //星级
            if (i < star) {
                imageView.setImageResource(R.mipmap.icon_spot_evaluate_selcted);
            } else {
                imageView.setImageResource(R.mipmap.icon_spot_evaluate_unseclcted);
            }
            //补全星级
            imageView.setLayoutParams(layoutParams);
            liEvaluate.addView(imageView);
        }

        getImageLoader().load(getContext(),
                viewHolder.getView(R.id.img_item_exhibition_spot_img)
                , itemData.getCover(), R.mipmap.icon_default_pic, R.mipmap.icon_default_pic, Config.IMAGE_CORNER);

        viewHolder.setText(R.id.tv_item_exhibition_spot_age, "年代:" + StringUtil.setText(itemData.getAge()));

        viewHolder.setText(R.id.tv_item_exhibition_spot_name, StringUtil.setText(itemData.getName()));

    }
}
设置监听:
public class ExhibitionFragment extends BaseMVPFragment
        implements ExhibitionContract.View, BaseViewHolder.OnItemClickListener, OnRefreshListener, OnLoadMoreListener {
    @Override
    public void onItemClick(BaseViewHolder viewHolder, int position, ExhibitionResponseListBody itemData, Object type) {
        //TODO 
    }
    @Override
    public void onItemLongClick(BaseViewHolder viewHolder, int position, ExhibitionResponseListBody itemData, Object type) {
          //TODO 
    }
}

以上就是针对RecyclerView Adapter的封装,可减少较多重复代码,读者有什么不同观点或疑问请留言指出!!!

你可能感兴趣的:(Android UI篇——RecyclerView BaseAdapter封装)