Android(安卓)封装RecyclerView.Adapter,省其ViewHolder
16lz
2021-01-26
RecyclerView大家都使用过的话会有些不方便,现在对其封装一下,让其可以:
1.可以像ListView一样方便使用OnItemClickListener;
2.可省去ViewHolder,快速开发;
3.分割线问题,即提供万能分割线。
先看效果图:
贴上如何使用:
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<Data> { public DataAdapter(Context context, List list) { super(context, list); } public DataAdapter(Context context) { super(context); for (int i = 0; i < 20; i++) { Data data = 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()); }}
涉及到的circle_bg.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#56f53f"/> <corners android:radius="6dp"/>shape>
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 holder ViewHolder * @param object Item数据对象 * @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 viewId The 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 viewId The view id. * @param progress The progress. * @param max The 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 max The 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 max The 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 tag The 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 key The key of tag; * @param tag The 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 viewId The 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 viewId The 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 viewId The 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 viewId The 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 viewId The 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); } } }}
更多相关文章
- [安卓开发Android] RecyclerView 类型与点击事件的用法
- 高德地图自定义marker图片相关
- Android-Product-Makefiles
- Android开发之自定义动画
- Android(安卓)NDK开发环境配置
- android中自定义属性三步骤
- Android使用枚举单例实现Toast快速刷新(自定义吐司)
- Android(安卓)7.0导航栏上添加图标
- Android(安卓)程式开发:(二十)内容提供者 —— 20.6 自定义ContentP