RecyclerView全攻略进阶优化

时间:2020-12-06 08:00:44

        Google 发布的Material Design支持库,支持库应该直接用V4提升到V7了,引入了RecycleView。RecylcerView从去年5.0开始发布好一阵子,这货目前能兼容到API 7,直接继承自Viewgroup,比ListView更为轻量,使用得当的话,完全可以替代ListView/GridView。本文将基于RecyclerView实现ListView/GridView的一些基础特性,和下拉刷新,加载更多,PinnedHeader等一些高级特性。

       以前也用eclipse写过recyclerView这样的东西,但是现在用android stuido写的话更加方便,再也不要去拷贝jar去libs里面,也不会出现方法找不到的问题,木前呢我的用到了api23,然后我们开始写咯。

1、添加引用

 在Android Studio新建一个项目,修改App Module的build.gradle文件,把compileSdkVersion和targetSdkVersion改为23,因为Material Design支持库需要Android 5.0以上作为编译SDK。
同时要加入相关依赖包design和RecyclerView支持包。

apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"

defaultConfig {
applicationId "com.example.zengyu.recycleview"
minSdkVersion 21
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:recyclerview-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
}

2.生命周期

一个RecyclerView的Item加载是有顺序的,类似于Activity的生命周期(姑且这么叫),具体可以对adapter的每个方法进行重写打下日志进行查看,具体大致为:

getItemViewType(获取显示类型,返回值可在onCreateViewHolder中拿到,以决定加载哪种ViewHolder)

onCreateViewHolder(加载ViewHolder的布局)

onViewAttachedToWindow(当Item进入这个页面的时候调用)

onBindViewHolder(将数据绑定到布局上,以及一些逻辑的控制就写这啦)

onViewDetachedFromWindow(当Item离开这个页面的时候调用)

onViewRecycled(当Item被回收的时候调用)

3 基本使用

RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。

  • 你想要控制其显示的方式,请通过布局管理器LayoutManager
  • 你想要控制Item间的间隔(可绘制),请通过ItemDecoration
  • 你想要控制Item增删的动画,请通过ItemAnimator
  • 你想要控制点击、长按事件,请自己写(在adapter里面绑定控件加)

3.代码实现

看下主布局就是这么简单:activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">    <android.support.v7.widget.RecyclerView        android:id="@+id/recyclerView"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:scrollbars="none" /></RelativeLayout>
然后要想实现列表效果也是很简单,分几步走就好了

mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);// use this setting to improve performance if you know that changes// in content do not change the layout size of the RecyclerView//如果可以确定每个item的高度是固定的,设置这个选项可以提高性能 mRecyclerView.setHasFixedSize(true);// use a linear layout managermLayoutManager = new LinearLayoutManager(this);mRecyclerView.setLayoutManager(mLayoutManager);// specify an adapter (see also next example)myDataset = new String[]{"JAVA", "Objective-C", "C", "C++", "Swift","GO", "JavaScript", "Python", "Ruby", "HTML", "SQL"};mAdapter = new MyAdapter(myDataset);mRecyclerView.setAdapter(mAdapter);
          1.跟ListView 一样 需要一个 Adapter

  2.跟ListView 一样 需要一个 ViewHolder

  3.有点不同了, 需要一个LayoutManager

  然后可以自定义分割线和动画效果,而且不再有条目事件必须自己去写onclick里面的方法。

目前SDK中提供了三种自带的LayoutManager:

  • LinearLayoutManager

  • GridLayoutManager

  • StaggeredGridLayoutManager

然后实现就在于item增加、删除的动画也是可配置的。接下来看一下ItemAnimator,最简单的就是

SlideInOutLeftItemAnimator : which applies a slide in/out from/to the left animation        SlideInOutRightItemAnimator : which applies a slide in/out from/to the right animation        SlideInOutTopItemAnimator : which applies a slide in/out from/to the top animation        SlideInOutBottomItemAnimator : which applies a slide in/out from/to the bottom animation        ScaleInOutItemAnimator : which applies a scale animation        SlideScaleInOutRightItemAnimator : which applies a scale animation with a slide in/out from/to the right animation


如果你是需要更多的效果,github有很多代码是可以借鉴的。然后我们就来写一下分割线啦: 

package com.example.zengyu.recycleview.widget;import android.content.Context;import android.content.res.Resources;import android.content.res.TypedArray;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.DimenRes;import android.support.annotation.DrawableRes;import android.support.v4.view.ViewCompat;import android.support.v7.widget.RecyclerView;import android.view.View;public abstract class FlexibleDividerDecoration extends RecyclerView.ItemDecoration {    private static final int DEFAULT_SIZE = 2;    private static final int[] ATTRS = new int[]{            android.R.attr.listDivider    };    protected enum DividerType {        DRAWABLE, PAINT, COLOR    }    protected DividerType mDividerType = DividerType.DRAWABLE;    protected VisibilityProvider mVisibilityProvider;    protected PaintProvider mPaintProvider;    protected ColorProvider mColorProvider;    protected DrawableProvider mDrawableProvider;    protected SizeProvider mSizeProvider;    protected boolean mShowLastDivider;    private Paint mPaint;    protected FlexibleDividerDecoration(Builder builder) {        if (builder.mPaintProvider != null) {            mDividerType = DividerType.PAINT;            mPaintProvider = builder.mPaintProvider;        } else if (builder.mColorProvider != null) {            mDividerType = DividerType.COLOR;            mColorProvider = builder.mColorProvider;            mPaint = new Paint();            setSizeProvider(builder);        } else {            mDividerType = DividerType.DRAWABLE;            if (builder.mDrawableProvider == null) {                TypedArray a = builder.mContext.obtainStyledAttributes(ATTRS);                final Drawable divider = a.getDrawable(0);                a.recycle();                mDrawableProvider = new DrawableProvider() {                    @Override                    public Drawable drawableProvider(int position, RecyclerView parent) {                        return divider;                    }                };            } else {                mDrawableProvider = builder.mDrawableProvider;            }            mSizeProvider = builder.mSizeProvider;        }        mVisibilityProvider = builder.mVisibilityProvider;        mShowLastDivider = builder.mShowLastDivider;    }    private void setSizeProvider(Builder builder) {        mSizeProvider = builder.mSizeProvider;        if (mSizeProvider == null) {            mSizeProvider = new SizeProvider() {                @Override                public int dividerSize(int position, RecyclerView parent) {                    return DEFAULT_SIZE;                }            };        }    }    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        int lastChildPosition = -1;        int childCount = mShowLastDivider ? parent.getChildCount() : parent.getChildCount() - 1;        for (int i = 0; i < childCount; i++) {            View child = parent.getChildAt(i);            int childPosition = parent.getChildAdapterPosition(child);            if (childPosition < lastChildPosition) {                // Avoid remaining divider when animation starts                continue;            }            lastChildPosition = childPosition;            if (ViewCompat.getAlpha(child) < 1) {                // Avoid remaining divider when animation starts                continue;            }            if (mVisibilityProvider.shouldHideDivider(childPosition, parent)) {                continue;            }            Rect bounds = getDividerBound(childPosition, parent, child);            switch (mDividerType) {                case DRAWABLE:                    Drawable drawable = mDrawableProvider.drawableProvider(childPosition, parent);                    drawable.setBounds(bounds);                    drawable.draw(c);                    break;                case PAINT:                    mPaint = mPaintProvider.dividerPaint(childPosition, parent);                    c.drawLine(bounds.left, bounds.top, bounds.right, bounds.bottom, mPaint);                    break;                case COLOR:                    mPaint.setColor(mColorProvider.dividerColor(childPosition, parent));                    mPaint.setStrokeWidth(mSizeProvider.dividerSize(childPosition, parent));                    c.drawLine(bounds.left, bounds.top, bounds.right, bounds.bottom, mPaint);                    break;            }        }    }    @Override    public void getItemOffsets(Rect rect, View v, RecyclerView parent, RecyclerView.State state) {        int position = parent.getChildAdapterPosition(v);        setItemOffsets(rect, position, parent);    }    protected abstract Rect getDividerBound(int position, RecyclerView parent, View child);    protected abstract void setItemOffsets(Rect outRect, int position, RecyclerView parent);    /**     * Interface for controlling divider visibility     */    public interface VisibilityProvider {        /**         * Returns true if divider should be hidden.         *         * @param position Divider position         * @param parent   RecyclerView         * @return True if the divider at position should be hidden         */        boolean shouldHideDivider(int position, RecyclerView parent);    }    /**     * Interface for controlling paint instance for divider drawing     */    public interface PaintProvider {        /**         * Returns {@link Paint} for divider         *         * @param position Divider position         * @param parent   RecyclerView         * @return Paint instance         */        Paint dividerPaint(int position, RecyclerView parent);    }    /**     * Interface for controlling divider color     */    public interface ColorProvider {        /**         * Returns {@link android.graphics.Color} value of divider         *         * @param position Divider position         * @param parent   RecyclerView         * @return Color value         */        int dividerColor(int position, RecyclerView parent);    }    /**     * Interface for controlling drawable object for divider drawing     */    public interface DrawableProvider {        /**         * Returns drawable instance for divider         *         * @param position Divider position         * @param parent   RecyclerView         * @return Drawable instance         */        Drawable drawableProvider(int position, RecyclerView parent);    }    /**     * Interface for controlling divider size     */    public interface SizeProvider {        /**         * Returns size value of divider.         * Height for horizontal divider, width for vertical divider         *         * @param position Divider position         * @param parent   RecyclerView         * @return Size of divider         */        int dividerSize(int position, RecyclerView parent);    }    public static class Builder<T extends Builder> {        private Context mContext;        protected Resources mResources;        private PaintProvider mPaintProvider;        private ColorProvider mColorProvider;        private DrawableProvider mDrawableProvider;        private SizeProvider mSizeProvider;        private VisibilityProvider mVisibilityProvider = new VisibilityProvider() {            @Override            public boolean shouldHideDivider(int position, RecyclerView parent) {                return false;            }        };        private boolean mShowLastDivider = false;        public Builder(Context context) {            mContext = context;            mResources = context.getResources();        }        public T paint(final Paint paint) {            return paintProvider(new PaintProvider() {                @Override                public Paint dividerPaint(int position, RecyclerView parent) {                    return paint;                }            });        }        public T paintProvider(PaintProvider provider) {            mPaintProvider = provider;            return (T) this;        }        public T color(final int color) {            return colorProvider(new ColorProvider() {                @Override                public int dividerColor(int position, RecyclerView parent) {                    return color;                }            });        }        public T colorResId(@ColorRes int colorId) {            return color(mResources.getColor(colorId));        }        public T colorProvider(ColorProvider provider) {            mColorProvider = provider;            return (T) this;        }        public T drawable(@DrawableRes int id) {            return drawable(mResources.getDrawable(id));        }        public T drawable(final Drawable drawable) {            return drawableProvider(new DrawableProvider() {                @Override                public Drawable drawableProvider(int position, RecyclerView parent) {                    return drawable;                }            });        }        public T drawableProvider(DrawableProvider provider) {            mDrawableProvider = provider;            return (T) this;        }        public T size(final int size) {            return sizeProvider(new SizeProvider() {                @Override                public int dividerSize(int position, RecyclerView parent) {                    return size;                }            });        }        public T sizeResId(@DimenRes int sizeId) {            return size(mResources.getDimensionPixelSize(sizeId));        }        public T sizeProvider(SizeProvider provider) {            mSizeProvider = provider;            return (T) this;        }        public T visibilityProvider(VisibilityProvider provider) {            mVisibilityProvider = provider;            return (T) this;        }        public T showLastDivider() {            mShowLastDivider = true;            return (T) this;        }        protected void checkBuilderParams() {            if (mPaintProvider != null) {                if (mColorProvider != null) {                    throw new IllegalArgumentException(                            "Use setColor method of Paint class to specify line color. Do not provider ColorProvider if you set PaintProvider.");                }                if (mSizeProvider != null) {                    throw new IllegalArgumentException(                            "Use setStrokeWidth method of Paint class to specify line size. Do not provider SizeProvider if you set PaintProvider.");                }            }        }    }}
package com.example.zengyu.recycleview.widget;import android.content.Context;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.support.annotation.DimenRes;import android.support.v4.view.ViewCompat;import android.support.v7.widget.RecyclerView;import android.view.View;public class HorizontalDividerItemDecoration extends FlexibleDividerDecoration {    private MarginProvider mMarginProvider;    protected HorizontalDividerItemDecoration(Builder builder) {        super(builder);        mMarginProvider = builder.mMarginProvider;    }    @Override    protected Rect getDividerBound(int position, RecyclerView parent, View child) {        Rect bounds = new Rect(0, 0, 0, 0);        int transitionX = (int) ViewCompat.getTranslationX(child);        int transitionY = (int) ViewCompat.getTranslationY(child);        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();        bounds.left = parent.getPaddingLeft() +                mMarginProvider.dividerLeftMargin(position, parent) + transitionX;        bounds.right = parent.getWidth() - parent.getPaddingRight() -                mMarginProvider.dividerRightMargin(position, parent) + transitionX;        int dividerSize = getDividerSize(position, parent);        if (mDividerType == DividerType.DRAWABLE) {            bounds.top = child.getBottom() + params.topMargin + transitionY;            bounds.bottom = bounds.top + dividerSize;        } else {            bounds.top = child.getBottom() + params.topMargin + dividerSize / 2 + transitionY;            bounds.bottom = bounds.top;        }        return bounds;    }    @Override    protected void setItemOffsets(Rect outRect, int position, RecyclerView parent) {        outRect.set(0, 0, 0, getDividerSize(position, parent));    }    private int getDividerSize(int position, RecyclerView parent) {        if (mPaintProvider != null) {            return (int) mPaintProvider.dividerPaint(position, parent).getStrokeWidth();        } else if (mSizeProvider != null) {            return mSizeProvider.dividerSize(position, parent);        } else if (mDrawableProvider != null) {            Drawable drawable = mDrawableProvider.drawableProvider(position, parent);            return drawable.getIntrinsicHeight();        }        throw new RuntimeException("failed to get size");    }    /**     * Interface for controlling divider margin     */    public interface MarginProvider {        /**         * Returns left margin of divider.         *         * @param position Divider position         * @param parent   RecyclerView         * @return left margin         */        int dividerLeftMargin(int position, RecyclerView parent);        /**         * Returns right margin of divider.         *         * @param position Divider position         * @param parent   RecyclerView         * @return right margin         */        int dividerRightMargin(int position, RecyclerView parent);    }    public static class Builder extends FlexibleDividerDecoration.Builder<Builder> {        private MarginProvider mMarginProvider = new MarginProvider() {            @Override            public int dividerLeftMargin(int position, RecyclerView parent) {                return 0;            }            @Override            public int dividerRightMargin(int position, RecyclerView parent) {                return 0;            }        };        public Builder(Context context) {            super(context);        }        public Builder margin(final int leftMargin, final int rightMargin) {            return marginProvider(new MarginProvider() {                @Override                public int dividerLeftMargin(int position, RecyclerView parent) {                    return leftMargin;                }                @Override                public int dividerRightMargin(int position, RecyclerView parent) {                    return rightMargin;                }            });        }        public Builder margin(int horizontalMargin) {            return margin(horizontalMargin, horizontalMargin);        }        public Builder marginResId(@DimenRes int leftMarginId, @DimenRes int rightMarginId) {            return margin(mResources.getDimensionPixelSize(leftMarginId),                    mResources.getDimensionPixelSize(rightMarginId));        }        public Builder marginResId(@DimenRes int horizontalMarginId) {            return marginResId(horizontalMarginId, horizontalMarginId);        }        public Builder marginProvider(MarginProvider provider) {            mMarginProvider = provider;            return this;        }        public HorizontalDividerItemDecoration build() {            checkBuilderParams();            return new HorizontalDividerItemDecoration(this);        }    }}
在代码里可以这样去使用:设置颜色高度和左右边距
recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(this).        color(Color.RED).size(getResources().getDimensionPixelSize(R.dimen.divider))        .margin(getResources().getDimensionPixelSize(R.dimen.leftmargin),                getResources().getDimensionPixelSize(R.dimen.rightmargin)).build());
其实呢最简单的分割线可以这样写:
public class DividerItemDecoration extends RecyclerView.ItemDecoration {    private static final int[] ATTRS = new int[]{            android.R.attr.listDivider    };    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;    private Drawable mDivider;    private int mOrientation;    public DividerItemDecoration(Context context, int orientation) {        final TypedArray a = context.obtainStyledAttributes(ATTRS);        mDivider = a.getDrawable(0);        a.recycle();        setOrientation(orientation);    }    public void setOrientation(int orientation) {        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {            throw new IllegalArgumentException("invalid orientation");        }        mOrientation = orientation;    }    @Override    public void onDraw(Canvas c, RecyclerView parent) {        Log.v("recyclerview - itemdecoration", "onDraw()");        if (mOrientation == VERTICAL_LIST) {            drawVertical(c, parent);        } else {            drawHorizontal(c, parent);        }    }    public void drawVertical(Canvas c, RecyclerView parent) {        final int left = parent.getPaddingLeft();        final int right = parent.getWidth() - parent.getPaddingRight();        final int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            final View child = parent.getChildAt(i);            android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext());            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            final int top = child.getBottom() + params.bottomMargin;            final int bottom = top + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    public void drawHorizontal(Canvas c, RecyclerView parent) {        final int top = parent.getPaddingTop();        final int bottom = parent.getHeight() - parent.getPaddingBottom();        final int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            final int left = child.getRight() + params.rightMargin;            final int right = left + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    @Override    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {        if (mOrientation == VERTICAL_LIST) {            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());        } else {            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);        }    }}
该实现类可以看到通过读取系统主题中的 android.R.attr.listDivider作为Item间的分割线,并且支持横向和纵向。使用可以这样:
mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));该属性我们可以直接声明在:<!-- Application theme. -->  <pre style="background-color:#272822;color:#cfbfad;font-family:'Consolas';font-size:12.0pt;"> <span style="color:#ff007f;"><</span>style name<span style="color:#ff007f;">=</span><span style="color:#ece47e;">"AppTheme" </span>parent<span style="color:#ff007f;">=</span><span style="color:#ece47e;">"AppBaseTheme"</span><span style="color:#ff007f;">></span><span style="color:#ff007f;"><</span>item  name<span style="color:#ff007f;">=</span><span style="color:#ece47e;">"android:listDivider"</span><span style="color:#ff007f;">></span>@drawable<span style="color:#ff007f;">/</span>divider_bg<span style="color:#ff007f;"></</span>item<span style="color:#ff007f;">></span><span style="color:#ff007f;"></</span>style<span style="color:#ff007f;">></span>


 
 
 

然后最主要的就是adapter了:

// 用于创建onCreateViewHolder@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parentViewGroup, int i){    View item = LayoutInflater.from(context).inflate(            R.layout.item_recyclerview, parentViewGroup, false);    return new ViewHolder(item);}
@Override
public void onBindViewHolder(final ViewHolder holder,int position)
{
// 获取当前item中显示的数据

// 设置要显示的数据
holder.textView.setText(list.get(position));

@Overridepublic int getItemCount(){    return list.size();}//  删除指定的Itempublic void removeData(int position){    list.remove(position);    //  通知RecyclerView控件某个Item已经被删除    notifyItemRemoved(position);}public  class ViewHolder extends RecyclerView.ViewHolder{    public TextView btn_Delete;    public TextView textView;    public ViewGroup layout_content;    public ViewHolder(View itemView)    {        super(itemView);        textView = (TextView) itemView.findViewById(com.example.zengyu.recycleview.R.id.text);        layout_content = (ViewGroup) itemView.findViewById(com.example.zengyu.recycleview.R.id.layout_content);    }}

这几个方法实现一下就好了,然后要加点击事件什么的,就我们必须拉个接口回调。

private IonSlidingViewClickListener mIDeleteBtnClickListener;
public void setmIDeleteBtnClickListener(IonSlidingViewClickListener mIDeleteBtnClickListener) {    this.mIDeleteBtnClickListener = mIDeleteBtnClickListener;}

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

把这个放在adapter里面,然后事件处理时,使用接口回调好了:

holder.btn_Delete.setOnClickListener(new android.view.View.OnClickListener() {    @Override    public void onClick(View v) {        int n = holder.getLayoutPosition();//获取当前条目的position        mIDeleteBtnClickListener.onDeleteBtnCilck(v, n);    }});
最后实现类里面实现这个接口就好了:

@Overridepublic void onDeleteBtnCilck(View view, int position) {    Toast.makeText(MainActivity.this, "delete...."+position, Toast.LENGTH_SHORT).show();    adapter.removeData(position);//回调里面刷新数据}

好了,最后把所有代码贴出来自己看:

package com.example.zengyu.recycleview.widget;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.HorizontalScrollView;import android.widget.TextView;public class SlidingView extends HorizontalScrollView   {    private TextView mTextView_Delete;    private int mScrollWidth;    private IonSlidingListener mIonSlidingListener;    private Boolean isOpen = false;    private Boolean once = false;    public SlidingView(Context context) {        this(context, null);    }    public SlidingView(Context context, AttributeSet attrs) {        this(context, attrs,0);    }    public SlidingView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.setOverScrollMode(OVER_SCROLL_NEVER);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        if(!once){            mTextView_Delete = (TextView) findViewById(com.example.zengyu.recycleview.R.id.tv_delete);            once = true;        }    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        super.onLayout(changed, l, t, r, b);        if(changed){            this.scrollTo(0,0);            //获取水平滚动条可以滑动的范围,即右侧按钮的宽度            mScrollWidth = mTextView_Delete.getWidth()+getPaddingRight();            Log.i("asd", "mScrollWidth:" + mScrollWidth);        }    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        int action = ev.getAction();        switch (action) {            case MotionEvent.ACTION_DOWN:            case MotionEvent.ACTION_MOVE:                mIonSlidingListener.onDownOrMove(this);                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_CANCEL:                changeScrollx();                return true;            default:                break;        }        return super.onTouchEvent(ev);    }    @Override    protected void onScrollChanged(int l, int t, int oldl, int oldt) {        super.onScrollChanged(l, t, oldl, oldt);        mTextView_Delete.setTranslationX(l - mScrollWidth);    }    /**     * 按滚动条被拖动距离判断关闭或打开菜单     */    public void changeScrollx(){        if(getScrollX() >= (mScrollWidth/2)){            this.smoothScrollTo(mScrollWidth, 0);            isOpen = true;            mIonSlidingListener.onMenuIsOpen(this);        }else{            this.smoothScrollTo(0, 0);            isOpen = false;        }    }    /**     * 打开菜单     */    public void openMenu()    {        if (isOpen){            return;        }        this.smoothScrollTo(mScrollWidth, 0);        isOpen = true;        mIonSlidingListener.onMenuIsOpen(this);    }    /**     * 关闭菜单     */    public void closeMenu()    {        if (!isOpen){            return;        }        this.smoothScrollTo(0, 0);        isOpen = false;    }    public void setSlidingListener(IonSlidingListener listener){        mIonSlidingListener = listener;    }    public interface IonSlidingListener{        void onMenuIsOpen(View view);        void onDownOrMove(SlidingView slidingView);    }}

唉,写完了,上图

RecyclerView全攻略进阶优化                                                                        RecyclerView全攻略进阶优化

好久不写博客了,感觉写一篇怎么这么难啊,唉继续学习吧

代码下载》》》http://download.csdn.net/detail/u013278099/9256553


更多的Material Design系列效果,请去star 我的github :https://github.com/zilianliuxue/AndroidStudy