Android 封装RecyclerView.Adapter,省其ViewHolder

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

先看效果图:
Android 封装RecyclerView.Adapter,省其ViewHolder_第1张图片

贴上如何使用:

      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


<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,OpenCode)