android|Android 封装RecyclerView.Adapter,省其ViewHolder

RecyclerView大家都使用过的话会有些不方便,现在对其封装一下,让其可以:
1.可以像ListView一样方便使用OnItemClickListener;
2.可省去ViewHolder,快速开发;
3.分割线问题,即提供万能分割线。
先看效果图:
android|Android 封装RecyclerView.Adapter,省其ViewHolder
文章图片

贴上如何使用:

LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); rvHorizontal.setLayoutManager(layoutManager); RecyclerViewDivider divder = new RecyclerViewDivider(false); // 创业分割,false为HORIZONTAL divder.setColor(0xff5ED0F2); // 分割线颜色 divder.setMargin(this, 0, 15, 0, 15); // 分割线边距 divder.setDividerHeight(this, 1); // 分割线宽度 rvHorizontal.addItemDecoration(divder); DataAdapter dataAdapter = new DataAdapter(this); rvHorizontal.setAdapter(dataAdapter); // layoutManager = new LinearLayoutManager(this); // layoutManager.setOrientation(LinearLayoutManager.VERTICAL); // rvVertical.setLayoutManager(layoutManager); // divder = new RecyclerViewDivider(true); // 创业分割,true为VERTICAL //divder.setMargin(10, 10, 10, 10); // 分割线边距 //divder.setDividerHeight(50); // 分割线宽度 50要大于(10+10) //// 分割线Drawable //divder.setDrawable(ContextCompat.getDrawable(this, R.drawable.circle_bg)); //rvVertical.addItemDecoration(divder); //DataAdapter dataAdapter1 = new DataAdapter(this); //rvVertical.setAdapter(dataAdapter1); OnItemClickListener listener = new OnItemClickListener() { @Override public void onItemClick(RecyclerHolder holder, int position) { Toast.makeText(MainActivity.this, String.valueOf(position), Toast.LENGTH_LONG).show(); } }; // 设置监听 dataAdapter.setOnItemClickListener(listener); dataAdapter1.setOnItemClickListener(listener);

如何方便定义RecyclerAdatper:
public class DataAdapter extends RecyclerAdatper {public DataAdapter(Context context, List list) { super(context, list); }public DataAdapter(Context context) { super(context); for (int i = 0; i < 20; i++) { Data data = https://www.it610.com/article/new Data(); data.setName("Name:" + i); getList().add(data); } }@Override public int getContentView(int viewType) { return R.layout.item_main_data; }@Override public void onInitView(RecyclerHolder holder, Data object, int position) { holder.setText(R.id.tv_item_main_name, object.getName()); }}

【android|Android 封装RecyclerView.Adapter,省其ViewHolder】涉及到的circle_bg.xml

demo地址:
TAO CODE: http://code.taobao.org/p/RecyclerViewDemo/src/
GitHub: https://github.com/scorpioyou/RecyclerViewDemo
主要由以下类:
OnItemClickListener
RecyclerAdatper
RecyclerHolder
RecyclerViewDivider
OnItemClickListener:
package com.recycler.lib; /** * creater:cyy * time:2017/2/8 * describe:定义{@link android.support.v7.widget.RecyclerView}OnItemClickListener点击事件 */ public interface OnItemClickListener { /** * @param holder 操作的ViewHolder * @param position 点击item的位置 */ void onItemClick(RecyclerHolder holder, int position); }

RecyclerAdatper:
package com.recycler.lib; import android.content.Context; import android.graphics.drawable.Drawable; import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; import java.util.List; /** * creater:cyy * time:2017/2/8 * describe:定义{@link android.support.v7.widget.RecyclerView}OnItemClickListener万能适配器 */ public abstract class RecyclerAdatper extends RecyclerView.Adapter {private Context mContext; private List mList; private OnItemClickListener mOnItemClickListener; public RecyclerAdatper(Context context) { this(context, new ArrayList()); }public RecyclerAdatper(Context context, List list) { mContext = context; mList = list; }public Context getContext() { return mContext; }public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.mOnItemClickListener = onItemClickListener; }@Override public RecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new RecyclerHolder(getLayoutInflater().inflate(getContentView(viewType), parent, false)); }@Override public int getItemViewType(int position) { return super.getItemViewType(position); }@Override public void onBindViewHolder(final RecyclerHolder holder, final int position) { onInitView(holder, getItem(position), position); if (null != mOnItemClickListener) { // 实现item点击事件回调 holder.getView().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mOnItemClickListener.onItemClick(holder, position); } }); } }@Override public int getItemCount() { if (null != mList) { return mList.size(); } return 0; }//---------------------------------abstract--------------------------------/** * item布局ID * * @param viewType 类别 * @return item布局ID */ public abstract int getContentView(int viewType); /** * item刷新的回调 * * @param holderViewHolder * @param objectItem数据对象 * @param position 刷新的位置 */ public abstract void onInitView(RecyclerHolder holder, T object, int position); //---------------------------------List-------------------------------- public List getList() { return mList; }public void setList(List list) { this.mList = list; notifyDataSetChanged(); }public void clear() { this.mList.clear(); notifyDataSetChanged(); }public void remove(int location) { if (location >= 0 && mList.size() > location) { this.mList.remove(location); notifyDataSetChanged(); } }public void add(int location, T object) { if (object != null) { this.mList.add(location, object); notifyDataSetChanged(); } }public void addLast(T object) { if (object != null) { this.mList.add(object); notifyDataSetChanged(); } }public void addHead(T object) { if (object != null) { this.mList.add(0, object); notifyDataSetChanged(); } }public void addAll(List list) { if (list != null) { this.mList.addAll(list); notifyDataSetChanged(); } }public T getItem(int position) { return mList.get(position); }//---------------------------------other-------------------------------- protected LayoutInflater getLayoutInflater() { return (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); }protected int getColor(int id) { return ContextCompat.getColor(getContext(), id); }protected String getString(int id) { return getContext().getResources().getString(id); }protected float getDimension(int id) { return getContext().getResources().getDimension(id); }protected Drawable getDrawable(int id) { return ContextCompat.getDrawable(getContext(), id); }}

RecyclerHolder:
package com.recycler.lib; import android.annotation.SuppressLint; import android.graphics.Bitmap; import android.graphics.Paint; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Build; import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.text.util.Linkify; import android.util.SparseArray; import android.view.View; import android.view.animation.AlphaAnimation; import android.widget.Adapter; import android.widget.AdapterView; import android.widget.Checkable; import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.RatingBar; import android.widget.TextView; /** * creater:cyy * time:2017/2/8 * describe: */ public class RecyclerHolder extends RecyclerView.ViewHolder {private View convertView; public RecyclerHolder(View itemView) { super(itemView); convertView = itemView; }public T getView(int viewId) { return retrieveView(viewId); }protected T retrieveView(int viewId) { SparseArray viewHolder = (SparseArray) convertView.getTag(); if (null == viewHolder) { viewHolder = new SparseArray(); convertView.setTag(viewHolder); } View childView = viewHolder.get(viewId); if (null == childView) { childView = convertView.findViewById(viewId); viewHolder.put(viewId, childView); } return (T) childView; }public RecyclerHolder setText(int viewId, CharSequence value) { TextView view = retrieveView(viewId); if (TextUtils.isEmpty(value)) { view.setText(""); } else { view.setText(value); } return this; }public RecyclerHolder setImageResource(int viewId, int imageResId) { ImageView view = retrieveView(viewId); view.setImageResource(imageResId); return this; }public RecyclerHolder setBackgroundColor(int viewId, int color) { View view = retrieveView(viewId); view.setBackgroundColor(color); return this; }public RecyclerHolder setBackgroundRes(int viewId, int backgroundRes) { View view = retrieveView(viewId); view.setBackgroundResource(backgroundRes); return this; }public RecyclerHolder setTextColor(int viewId, int textColor) { TextView view = retrieveView(viewId); view.setTextColor(textColor); return this; }public RecyclerHolder setTextColorRes(int viewId, int textColorRes) { TextView view = retrieveView(viewId); view.setTextColor(ContextCompat.getColor(view.getContext(), textColorRes)); return this; }public RecyclerHolder setImageDrawable(int viewId, Drawable drawable) { ImageView view = retrieveView(viewId); view.setImageDrawable(drawable); return this; }public RecyclerHolder setImageBitmap(int viewId, Bitmap bitmap) { ImageView view = retrieveView(viewId); view.setImageBitmap(bitmap); return this; }@SuppressLint("NewApi") public RecyclerHolder setAlpha(int viewId, float value) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { retrieveView(viewId).setAlpha(value); } else { // Pre-honeycomb hack to set Alpha value AlphaAnimation alpha = new AlphaAnimation(value, value); alpha.setDuration(0); alpha.setFillAfter(true); retrieveView(viewId).startAnimation(alpha); } return this; }public RecyclerHolder setVisible(int viewId, boolean visible) { View view = retrieveView(viewId); view.setVisibility(visible ? View.VISIBLE : View.GONE); return this; }public RecyclerHolder setVisible(int viewId, int visibility) { View view = retrieveView(viewId); view.setVisibility(visibility); return this; }/** * Add links into a TextView. * * @param viewId The id of the TextView to linkify. * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder linkify(int viewId) { TextView view = retrieveView(viewId); Linkify.addLinks(view, Linkify.ALL); return this; }/** * Apply the typeface to the given viewId, and enable subpixel rendering. */ public RecyclerHolder setTypeface(int viewId, Typeface typeface) { TextView view = retrieveView(viewId); view.setTypeface(typeface); view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG); return this; }/** * Apply the typeface to all the given viewIds, and enable subpixel * rendering. */ public RecyclerHolder setTypeface(Typeface typeface, int... viewIds) { for (int viewId : viewIds) { TextView view = retrieveView(viewId); view.setTypeface(typeface); view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG); } return this; }/** * Sets the progress of a ProgressBar. * * @param viewIdThe view id. * @param progress The progress. * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder setProgress(int viewId, int progress) { ProgressBar view = retrieveView(viewId); view.setProgress(progress); return this; }/** * Sets the progress and max of a ProgressBar. * * @param viewIdThe view id. * @param progress The progress. * @param maxThe max value of a ProgressBar. * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder setProgress(int viewId, int progress, int max) { ProgressBar view = retrieveView(viewId); view.setMax(max); view.setProgress(progress); return this; }/** * Sets the range of a ProgressBar to 0...max. * * @param viewId The view id. * @param maxThe max value of a ProgressBar. * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder setMax(int viewId, int max) { ProgressBar view = retrieveView(viewId); view.setMax(max); return this; }/** * Sets the rating (the number of stars filled) of a RatingBar. * * @param viewId The view id. * @param rating The rating. * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder setRating(int viewId, float rating) { RatingBar view = retrieveView(viewId); view.setRating(rating); return this; }/** * Sets the rating (the number of stars filled) and max of a RatingBar. * * @param viewId The view id. * @param rating The rating. * @param maxThe range of the RatingBar to 0...max. * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder setRating(int viewId, float rating, int max) { RatingBar view = retrieveView(viewId); view.setMax(max); view.setRating(rating); return this; }/** * Sets the tag of the view. * * @param viewId The view id. * @param tagThe tag; * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder setTag(int viewId, Object tag) { View view = retrieveView(viewId); view.setTag(tag); return this; }/** * Sets the tag of the view. * * @param viewId The view id. * @param keyThe key of tag; * @param tagThe tag; * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder setTag(int viewId, int key, Object tag) { View view = retrieveView(viewId); view.setTag(key, tag); return this; }/** * Sets the checked status of a checkable. * * @param viewIdThe view id. * @param checked The checked status; * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder setChecked(int viewId, boolean checked) { Checkable view = (Checkable) retrieveView(viewId); view.setChecked(checked); return this; }/** * Sets the adapter of a adapter view. * * @param viewIdThe view id. * @param adapter The adapter; * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder setAdapter(int viewId, Adapter adapter) { AdapterView view = retrieveView(viewId); view.setAdapter(adapter); return this; }/** * Sets the on click listener of the view. * * @param viewIdThe view id. * @param listener The on click listener; * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder setOnClickListener(int viewId, View.OnClickListener listener) { View view = retrieveView(viewId); view.setOnClickListener(listener); return this; }public RecyclerHolder setOnCheckedChangeListener(int viewId, CompoundButton.OnCheckedChangeListener listener) { CompoundButton view = retrieveView(viewId); view.setOnCheckedChangeListener(listener); return this; }/** * Sets the on touch listener of the view. * * @param viewIdThe view id. * @param listener The on touch listener; * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder setOnTouchListener(int viewId, View.OnTouchListener listener) { View view = retrieveView(viewId); view.setOnTouchListener(listener); return this; }/** * Sets the on long click listener of the view. * * @param viewIdThe view id. * @param listener The on long click listener; * @return The BaseAdapterHelper for chaining. */ public RecyclerHolder setOnLongClickListener(int viewId, View.OnLongClickListener listener) { View view = retrieveView(viewId); view.setOnLongClickListener(listener); return this; }/** * Retrieve the convertView */ public View getView() { return convertView; }}

RecyclerViewDivider:
package com.recycler.lib; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.annotation.ColorRes; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v4.view.ViewCompat; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.LinearLayout; /** * creater:cyy * time:2017/2/8 * describe: */ public class RecyclerViewDivider extends RecyclerView.ItemDecoration {private Drawable mDivider; private int mDividerHeight = 0; private Paint mPaint; private int mOrientation; private final Rect mBounds = new Rect(); private Rect mMarginBounds; public RecyclerViewDivider() { mOrientation = LinearLayout.VERTICAL; }public RecyclerViewDivider(boolean isVertical) { if (isVertical) { mOrientation = LinearLayout.VERTICAL; } else { mOrientation = LinearLayout.HORIZONTAL; } }public void setDividerHeight(int px) { this.mDividerHeight = px; }public void setDividerHeight(Context c, int dp) { this.mDividerHeight = (int) (dp * c.getResources().getDisplayMetrics().density); }public void setDrawable(@NonNull Drawable drawable) { mDivider = drawable; }public void setColor(int color) { mPaint = new Paint(); mPaint.setColor(color); }public void setColor(Context c, @ColorRes int colorId) { setColor(ContextCompat.getColor(c, colorId)); }public void setMargin(int left, int top, int right, int bottom) { mMarginBounds = new Rect(); mMarginBounds.left = left; mMarginBounds.top = top; mMarginBounds.right = right; mMarginBounds.bottom = bottom; }public void setMargin(Context c, int leftDp, int topDp, int rightDp, int bottomDp) { float density = c.getResources().getDisplayMetrics().density; mMarginBounds = new Rect(); mMarginBounds.left = (int) (leftDp * density); mMarginBounds.top = (int) (topDp * density); mMarginBounds.right = (int) (rightDp * density); mMarginBounds.bottom = (int) (bottomDp * density); }@Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { if (parent.getLayoutManager() == null) { return; } if (mOrientation == LinearLayout.VERTICAL) { drawVertical(c, parent); } else { drawHorizontal(c, parent); } }@SuppressLint("NewApi") private void drawVertical(Canvas canvas, RecyclerView parent) { canvas.save(); final int left; final int right; if (parent.getClipToPadding()) { left = parent.getPaddingLeft(); right = parent.getWidth() - parent.getPaddingRight(); canvas.clipRect(left, parent.getPaddingTop(), right, parent.getHeight() - parent.getPaddingBottom()); } else { left = 0; right = parent.getWidth(); }final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); parent.getDecoratedBoundsWithMargins(child, mBounds); final int bottom = mBounds.bottom + Math.round(ViewCompat.getTranslationY(child)); int top = bottom - mDividerHeight; if (null != mDivider) { int sicWidth = mDivider.getIntrinsicWidth(); if (sicWidth > 0) { top = bottom - sicWidth; } if (null != mMarginBounds) { mDivider.setBounds(left + mMarginBounds.left, top + mMarginBounds.top, right - mMarginBounds.right, bottom - mMarginBounds.bottom); } else { mDivider.setBounds(left, top, right, bottom); } mDivider.draw(canvas); } if (mPaint != null) { if (null != mMarginBounds) { canvas.drawRect(left + mMarginBounds.left, top + mMarginBounds.top, right - mMarginBounds.right, bottom - mMarginBounds.bottom, mPaint); } else { canvas.drawRect(left, top, right, bottom, mPaint); } } } canvas.restore(); }@SuppressLint("NewApi") private void drawHorizontal(Canvas canvas, RecyclerView parent) { canvas.save(); final int top; final int bottom; if (parent.getClipToPadding()) { top = parent.getPaddingTop(); bottom = parent.getHeight() - parent.getPaddingBottom(); canvas.clipRect(parent.getPaddingLeft(), top, parent.getWidth() - parent.getPaddingRight(), bottom); } else { top = 0; bottom = parent.getHeight(); }final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); parent.getLayoutManager().getDecoratedBoundsWithMargins(child, mBounds); int right = mBounds.right + Math.round(ViewCompat.getTranslationX(child)); int left = right - mDividerHeight; if (null != mDivider) { int sicWidth = mDivider.getIntrinsicWidth(); if (sicWidth > 0) { left = right - sicWidth; } if (null != mMarginBounds) { mDivider.setBounds(left + mMarginBounds.left, top + mMarginBounds.top, right - mMarginBounds.right, bottom - mMarginBounds.bottom); } else { mDivider.setBounds(left, top, right, bottom); } mDivider.draw(canvas); } if (mPaint != null) { if (null != mMarginBounds) { canvas.drawRect(left + mMarginBounds.left, top + mMarginBounds.top, right - mMarginBounds.right, bottom - mMarginBounds.bottom, mPaint); } else { canvas.drawRect(left, top, right, bottom, mPaint); } } } canvas.restore(); }@Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { if (mOrientation == LinearLayout.VERTICAL) { if (0 == mDividerHeight && null != mDivider) { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, 0, mDividerHeight); } } else { if (0 == mDividerHeight && null != mDivider) { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); } else { outRect.set(0, 0, mDividerHeight, 0); } } } }

    推荐阅读