RecyclerView全攻略进阶优化

        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 manager
mLayoutManager = 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
@Override
public 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));

@Override
public int getItemCount()
{
    return list.size();
}
//  删除指定的Item
public 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);
    }
});
最后实现类里面实现这个接口就好了:

@Override
public 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);
    }


}

唉,写完了,上图

                                                                        

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

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


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

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:C马雯娟 返回首页