RecyclerView详解

来源:互联网 发布:哪个软件容易泡妞 编辑:程序博客网 时间:2024/06/05 17:50

                                               RecyclerView详解

集成:   必须手动导入带有RecyclerView的V7包

结构:

            RecyclerView.Adapter: 创建View并将数据集合绑定到View上

           ViewHolder: 持有所有的用于绑定数据或者需要操作的View

           LayoutManager: 布局管理器,负责摆放视图等相关操作

            ItemDecoration: 负责绘制Item附近的分割线,通过RecyclerView.addItemDecoration()使用

            ItemAnimator: 为Item的操作添加动画效果,如,增删条目等,通过RecyclerView.setItemAnimator(new DefaultItemAnimator());使用

RecyclerView的内置管理器

         · LinearLayoutManager:以垂直或水平滚动列表方式显示项目。类似Listview

·         GridLayoutManager: 在网格中显示项目。                 类似GridView

·         StaggeredGridLayoutManager: 在分散对齐网格中显示项目  瀑布流

          继承RecyclerView.LayoutManager 就可以创建自定义的布局管理器。

RecyclerView.ItemDecoration是一个抽象类,可以通过重写以下三个方法,来实现Item之间的偏移量或者装饰效果:

          public void onDraw(Canvas c, RecyclerViewparent) 装饰的绘制在Item条目绘制之前调用,所以这有可能被Item的内容所遮挡

          public void onDrawOver(Canvas c, RecyclerViewparent) 装饰的绘制在Item条目绘制之后调用,因此装饰将浮于Item之上

          public void getItemOffsets(Rect outRect,int itemPosition, RecyclerView parent) 与padding或margin类似,LayoutManager在测量阶段会调用该方法,计算出每一个Item的正确尺寸并设置偏移量。

ItemAnimator触发于以下三种事件:

    某条数据被插入到数据集合中

    从数据集合中移除某条数据

    更改数据集合中的某条数据


在之前的版本中,当时据集合发生改变时通过调用notifyDataSetChanged(),来刷新列表,因为这样做会触发列表的重绘,所以并不会出现任何动画效果,因此需要调用一些以notifyItem*()作为前缀的特殊方法,比如:

 

    public final void notifyItemInserted(intposition) 向指定位置插入Item

    public final void notifyItemRemoved(intposition) 移除指定位置Item

    public final void notifyItemChanged(intposition) 更新指定位置Item

六优点
     它自带ViewHolder来实现View的复用机制,再也不用ListView那样在getView()里自己写了
     使用LayoutManager可以实现ListView,GridView以及流式布局的列表效果
     通过setItemAnimator(ItemAnimator animator)可以实现增删动画(懒的话,可以使用默认的ItemAnimator对象,效果也不错)
     控制item的间隔,可以使用addItemDecoration(ItemDecoration decor),不过里边的ItemDecoration是一个抽象类,需要自己去实现

RecyclerView的常用方法

1  GetChildCount();        //获取可见的item数量

2. findViewHolderForAdapterPosition      //获取position处item绑定的viewHolder

3  设置固定大小   recyclerView_one.setHasFixedSize(true);
                                                                                             布局管理器之GridLayoutManager

一构造方法GridLayoutManager,网格布局(流式布局应该是它的一个特殊情况):
GridLayoutManager(Context context, int spanCount)或
GridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout)
        1 Context context上下文
        2 int spanCount  显示的个数
        3 int orientation  显示的类型    默认为vertical
        LinearLayoutManager.VERTICAL  整体竖直排列一行显示参数二设置的个数
        LinearLayoutManager.HORIZONTAL 整体水平排一列显示spanCount  个数据
4 boolean reverseLayout最后一个参数表示的是是否逆向布局(意思是将数据反向显示,原先从左向右,从上至下。设为true之后全部逆转)。

小提示:在这两个LayoutManager中,默认的orientation为vertical,reverseLayout为false。对应的参数在GridLayoutManager中都有对应的方法来进行补充设置。而在StaggeredGridLayoutManager中所有的方法都针对reverseLayout做了判断,然而它并没有给出这个参数设定值的api。

二常用实现复杂列数变化的方法    根据position控制每列显示的多少

mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {            @Override            public int getSpanSize(int position) {             return  4 ? mGridLayoutManager.getSpanCount() : 1;            }});

当前position为4吗  不为4  每设置的显示类型每行【或列】显示构造方法里设置的个数【mGridLayoutManager.getSpanCount()获取GridLayoutManager设置的个数】   为4该下标position显示一条数据每行【或列】

                                                                       布局管理器之LinearLayoutManager

可见性:在RecyclerView里可见性的定义指的是Item露出一部分,,这个Item就是可见性的
完全可见性:指的是整个Item都可以在屏幕里展示出来,,没有被别的控件遮挡
一常用方法
1findFirstVisibleItemPosition();  获取第一个可见item的pisition
2findFirstCompletelyVisibleItemPosition();获取第一个完全可见item的position
3findLastVisibleItemPosition();  获取最后第一个可见item的pisition
4findFirstCompletelyVisibleItemPosition();获取最后一个完全可见item的position
5.setOrientation(OrientationHelper.VERTICAL);   //设置垂直方向
                                                                 

                                                                       瀑布流管理器

 mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,        StaggeredGridLayoutManager.VERTICAL));

 这样就和GridLayoutManager实现一样的效果了

 瀑布流效果在适配器设置其高度不一致即可

                                                                       RecyclerView.ItemDecoration画分割线

RecyclerView.ItemDecoration是一个抽象类,可以通过重写以下三个方法,来实现Item之间的偏移量或者装饰效果:

方法一:   public void onDraw(Canvas c, RecyclerViewparent) 装饰的绘制在Item条目绘制之前调用,所以这有可能被Item的内容所遮挡

方法二:    public voidonDrawOver(Canvas c, RecyclerView parent) 装饰的绘制在Item条目绘制之后调用,因此装饰将浮于Item之上、

public class ItemDecor extends RecyclerView.ItemDecoration {    Paint mPaint;    public ItemDecor() {        mPaint = new Paint();        mPaint.setColor(0x99FF0000);}//此等装饰物在   item绘制之后调用   在item之上    @Override    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {        c.drawCircle(50, 30, 30, mPaint);      }}

//使用这个方法画分割线     需要通过遍历给每个条目画

public class ItemDecorationRec extends RecyclerView.ItemDecoration{    //声明画笔    Paint mPaint;    //构造函数初始化画笔    public ItemDecorationRec() {        mPaint = new Paint();        mPaint.setColor(0x99FF0000);    }    //上边画圆    @Override    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {        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);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            final int top = child.getBottom() + params.bottomMargin +                    Math.round(ViewCompat.getTranslationY(child));            final int bottom = top + 50;            c.drawRect(left, top, right, bottom, mPaint);        }//        c.drawCircle(50, 30, 30, mPaint);    }    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        super.onDraw(c, parent, state);    }    @Override    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        outRect.set(0,0,0,70);    }}
方法三

public voidgetItemOffsets(Rect  outRect, intitemPosition, RecyclerView  parent) 与padding或margin类似,LayoutManager在测量阶段会调用该方法,计算出每一个Item的正确尺寸并设置偏移量。

参数一:我们通过设置outRect的left, top, right, bottom属性值就可以让ItemView产生相应的偏移(内嵌),
上述方法的调用顺序,先执行ItemDecoration的onDraw()、再执行ItemView的onDraw()、再执行ItemDecoration的onDrawOver()。由于和RecyclerView使用的是同一个Canvas,所以你想在Canvas上画什么都可以,就像我们平时自定义View时写onDraw()方法一样。
二 使用:自定义类itemDecoration继承RecyclerView.ItemDecoration重写上面三个方法即可
         然后调用mRecycler.addItemDecoration(new ItemDecorationRec());即可给条目添加间隔  【可重复添加addItemDecoration】

三 使用系统自带的画分割线

public class SystemDecoration extends RecyclerView.ItemDecoration {    //采用系统内置的风格的分割线    private static final int[] attrs=new int[]{android.R.attr.listDivider};      private Drawable mDivider;    private int orientation;  //定向横向还是竖向的    /**     *  系统自制分割线   参数二是orientation传入横向还是纵向的     */    public SystemDecoration(Context context,int orientation) {        TypedArray typedArray=context.obtainStyledAttributes(attrs);        mDivider=typedArray.getDrawable(0);        typedArray.recycle();        this.orientation=orientation;    }        @Override    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {        super.onDrawOver(c, parent, state);    }        @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        drawHDeraction(c,parent);        drawVDeraction(c,parent);    }    /**     * 绘制水平方向的分割线     * @param c     * @param parent     */    private void drawHDeraction(Canvas c,RecyclerView parent){        int left=parent.getPaddingLeft();        int right=parent.getWidth()-parent.getPaddingRight();        int childCount=parent.getChildCount();        for(int i=0;i<childCount;i++){            View child=parent.getChildAt(i);            RecyclerView.LayoutParams layoutParams=(RecyclerView.LayoutParams)child.getLayoutParams();            int top=child.getBottom()+layoutParams.bottomMargin;            int bottom=top+mDivider.getIntrinsicHeight();            mDivider.setBounds(left,top,right,bottom);            mDivider.draw(c);        }    }    /**     * 绘制垂直方向的分割线     * @param c     * @param parent     */    private void drawVDeraction(Canvas c,RecyclerView parent){        int top=parent.getPaddingTop();        int bottom=parent.getHeight()-parent.getPaddingBottom();        int childCount=parent.getChildCount();        for(int i=0;i<childCount;i++){            View child=parent.getChildAt(i);            RecyclerView.LayoutParams layoutParams=(RecyclerView.LayoutParams)child.getLayoutParams();            int left=child.getRight()+layoutParams.rightMargin;            int right=left+mDivider.getIntrinsicWidth();            mDivider.setBounds(left,top,right,bottom);            mDivider.draw(c);        }    }    @Override    public void getItemOffsets(Rect outRect,View view, RecyclerView parent, RecyclerView.State state) {        if(OrientationHelper.HORIZONTAL==orientation){            outRect.set(0, 0,mDivider.getIntrinsicWidth(), 0);        }else {            outRect.set(0, 0, 0,mDivider.getIntrinsicHeight());        }    }}}
调用:recyclerView_one.addItemDecoration(newAdvanceDecoration(this,OrientationHelper.VERTICAL))
GrideDecoration   网格布局用的分割线
public class grideDecoration extends RecyclerView.ItemDecoration {    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};    private Drawable mDivider;    public grideDecoration(Context context) {        final TypedArray a = context.obtainStyledAttributes(ATTRS);        mDivider = a.getDrawable(0);        a.recycle();    }    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        drawHorizontal(c, parent);        drawVertical(c, parent);    }    private int getSpanCount(RecyclerView parent) {        // 列数        int spanCount = -1;        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager) {            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();        } else if (layoutManager instanceof StaggeredGridLayoutManager) {            spanCount = ((StaggeredGridLayoutManager) layoutManager)                    .getSpanCount();        }        return spanCount;    }    public void drawHorizontal(Canvas c, RecyclerView parent) {        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.getLeft() - params.leftMargin;            final int right = child.getRight() + params.rightMargin                    + mDivider.getIntrinsicWidth();            final int top = child.getBottom() + params.bottomMargin;            final int bottom = top + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    public void drawVertical(Canvas c, RecyclerView parent) {        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 top = child.getTop() - params.topMargin;            final int bottom = child.getBottom() + params.bottomMargin;            final int left = child.getRight() + params.rightMargin;            final int right = left + mDivider.getIntrinsicWidth();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    private boolean isLastColum(RecyclerView parent, int pos, int spanCount,                                int childCount) {        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager) {            if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边            {                return true;            }        } else if (layoutManager instanceof StaggeredGridLayoutManager) {            int orientation = ((StaggeredGridLayoutManager) layoutManager)                    .getOrientation();            if (orientation == StaggeredGridLayoutManager.VERTICAL) {                if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边                {                    return true;                }            } else {                childCount = childCount - childCount % spanCount;                if (pos >= childCount)// 如果是最后一列,则不需要绘制右边                    return true;            }        }        return false;    }    private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,                              int childCount) {        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager) {            childCount = childCount - childCount % spanCount;            if (pos >= childCount)// 如果是最后一行,则不需要绘制底部                return true;        } else if (layoutManager instanceof StaggeredGridLayoutManager) {            int orientation = ((StaggeredGridLayoutManager) layoutManager)                    .getOrientation();            // StaggeredGridLayoutManager 且纵向滚动            if (orientation == StaggeredGridLayoutManager.VERTICAL) {                childCount = childCount - childCount % spanCount;                // 如果是最后一行,则不需要绘制底部                if (pos >= childCount)                    return true;            } else            // StaggeredGridLayoutManager 且横向滚动            {                // 如果是最后一行,则不需要绘制底部                if ((pos + 1) % spanCount == 0) {                    return true;                }            }        }        return false;    }    @Override    public void getItemOffsets(Rect outRect, int itemPosition,                               RecyclerView parent) {        int spanCount = getSpanCount(parent);        int childCount = parent.getAdapter().getItemCount();        if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部        {            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);        } else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边        {            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());        } else {            outRect.set(0, 0, mDivider.getIntrinsicWidth(),                    mDivider.getIntrinsicHeight());        }    }}
                                                                                                                             ItemAnimator
 1// 设置item默认动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
                                                                                                                               

                                                                                                                              RecyclerAdapte

一Recycler.Adapter中的数据的添加和删除

例如我们在使用ListView的时候,当数据发生变化的时候可以通过notifyDatasetChange()来刷新界面。对于RecyclerView控件来讲,给我们提供更加高级的使用方法notifyItemInserted(position)和notifyItemRemoved(position)
我们可以在TestRecyclerAdapter中添加数据新增和数据删除的方法如下:

  //添加数据       public void addItem(String data, intposition) {           mTitles.add(position, data);           notifyItemInserted(position);       } 

 //删除数据 

    public void removeItem(String data) { 

        int position = mTitles.indexOf(data); 

        mTitles.remove(position); 

         notifyItemRemoved(position); 

     }
在运行之前我们不要忘记RecyclerView给提供了动画设置,我这边就直接采用了默认动画,设置方法如下:

 //添加默认的动画效果 

 recyclerView_one.setItemAnimator(new DefaultItemAnimator());

二适配器的实现方法

//自定义适配器  继承  RecyclerView.Adapter   重写几个方法public class MyRecyclerAdapter extends RecyclerView.Adapter {    private static final int ITEM_VIEW_TYPE_HEADER = 12;    private static final int ITEM_VIEW_TYPE_ITEM = 1;    private List<MOdule> list;//    private Context context;    private List<Activity> activityList;//activity的集合    private BitmapUtils bitmapUtils;    private int w;//屏幕宽度    private int size;//添加空白item的集合长度    private User_login user;    ViewHolder viewHolderholder;    Holder mholder;    public boolean isHeader(int position) {        return position == 12;    }    /**     *  适配器的构造函数     */    public MyRecyclerAdapter(List<MOdule> list, Context context, int w, List<Activity> activityList, int size) {        this.list = list;        this.context = context;        this.w = w;        this.activityList = activityList;        this.size = size;    }    /**     *  onCreateViewHolder会调用这个根据position获取该位置下    条目的类型    然后onCreateViewHolder根据type分别创建holder     */    @Override    public int getItemViewType(int position) {        if (position == 12) {            return ITEM_VIEW_TYPE_HEADER;        } else {            return ITEM_VIEW_TYPE_ITEM;        }    }     /**      * 是用来配合写好的ViewHolder来返回一个ViewHolder对象。这里也涉及到了条目布局的加载。viewType则表示需要给当前position生成的是哪一种ViewHolder,这个参数也说明了RecyclerView对多类型ItemView的支持。      */    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        if (viewType == ITEM_VIEW_TYPE_HEADER) {            //ViewPager的布局            View itemview_item2 = LayoutInflater.from(context).inflate(R.layout.recycler_item2, parent, false);            mholder = new Holder(itemview_item2);            ViewGroup.LayoutParams params = mholder.itemView.getLayoutParams();            params.width = w;            params.height = (int) ((1f / 4f) * w);            return mholder;        } else {    //创建普通的方块+            final Context context = parent.getContext();            //GridView的布局            View itemview_item1 = LayoutInflater.from(context).inflate(R.layout.recycler_item1, parent, false);            viewHolderholder = new ViewHolder(itemview_item1);            return viewHolderholder;        }    }    /**     *   专门用来绑定ViewHolder里的控件和数据源中position位置的数据。     */    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {        if (position != ITEM_VIEW_TYPE_HEADER && position < list.size() - size) {            viewHolderholder = (ViewHolder) holder;            /**             *  通过viewHolderholder.itemView.   设置条目的长按点击事件             */             viewHolderholder.itemView.setOnLongClickListener(new View.OnLongClickListener() {                @Override                public boolean onLongClick(View v) {                    //添加震动                    Vibrator vibrator = (Vibrator) (context.getSystemService(Context.VIBRATOR_SERVICE));                    long[] pattern = {20, 50};                    vibrator.vibrate(pattern, -1);                    //添加缩放动画//                    ScaleAnimation animation=new ScaleAnimation(1.0f,1.2f,1.0f,1.2f);//                    animation.setDuration(200);//                    animation.setFillAfter(false);//                    v.startAnimation(animation);                    //     v.setBackgroundColor(Color.parseColor("#E8E6E8"));                    //记录位置表示有长按操作                    SharedPreferencesUtil.putInt("recycler_position", position, context);                    return false;                }            });                        /**             *  通过viewHolderholder.itemView.   设置条目的点击事件             */                        viewHolderholder.itemView.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    int recycler_position = SharedPreferencesUtil.getInt("recycler_position",                            context);                                                  }            });            tv.setText(list.get(position).getModuleName());        } else if (position == ITEM_VIEW_TYPE_HEADER) {            mholder = (Holder) holder;        }    }     /**      *    getItemCount()就不必多说了,和ListView是一样的 条目的总个数      */    @Override    public int getItemCount() {        return list.size();    }    /**     * GridView  每个方块的 ViewHolder    把inflate后的view传入     *      */    class ViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {        private View view;        public ViewHolder(View itemView) {            super(itemView);            this.view = itemView;        }        public View getView() {            return view;        }        @Override        public void onItemSelected() {            // 当选中时,背景色为灰色            itemView.setBackgroundColor(Color.LTGRAY);        }        @Override        public void onItemClear() {            //当拖拽完毕后,背景色为透明            itemView.setBackgroundColor(0);        }    }    /**     * ViewPager     * Holder     */     class Holder extends RecyclerView.ViewHolder {        public Holder(View itemView) {            super(itemView);        }     }}

三 adapter中的数据的重新处理

class MyViewHolder extends ViewHolder{   TextView tv;           //构造里执行findviewByid   public MyViewHolder(Context context, View view){          super(view);          tv = (TextView) view.findViewById(R.id.id_num);          //当然,我们也可以在这里使用view来对RecyclerView的一个item进行事件监听,也可以使用            //tv等子控件来实现item的子控件的事件监听。这也是我之所以要传context的原因之一呢~          ......   }      //创建实例的时候    填充布局      public static MyViewHolder newInstance(Activity context, ViewGroup parent){           View view = LayoutInflater.from(              context).inflate(R.layout.item_home, parent,false);         return new MyViewHolder(context, view);   }  }      //你没看错,数据绑定也被整合进来了,    //将adapter里的数据根据position获取到后传进来。当然,也可以根据具体情况来做调整。   public void onBinViewHolder(String data){            tv.setText(data);//既然这里也有子控件,那么这里也可以做item子控件的事件监听喽}
Adapter
class HomeAdapter extends RecyclerView.Adapter<MyViewHolder>{  @Override  public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){//如需要,还要对viewType做判断      return MyViewHolder.newInstance(this, parent)  }  @Override  public void onBindViewHolder(MyViewHolder holder, int position){      holder.onBindViewHolder(mDatas.get(position));  }  @Override  public int getItemCount(){      return mDatas.size();  }}
                                                                                                        

                                                                                   ItemTouchHelper实现Recycler的滑动和拖动

1、ItemTouchHelper   支持RecyclerView滑动删除和拖拽的工具类

结合recyvlerVIew的使用方法为

//1设置一个ItemTouchHelper.Callback对象

ItemTouchHelper.Callback callback = newItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT| ItemTouchHelper.LEFT, 0)

//2创建  ItemTouchHelper对象     传入callBack

ItemTouchHelper itemTouchHelper=newItemTouchHelper(callback);

//3让item的图所动滑动依附在RecyclerView上

itemTouchHelper.attachToRecyclerView(mRecycler)

SimpleCallback方法

SimpleCallback构造方法需要我们传入两个参数:

1、dragDirs - 表示拖拽的方向,有六个类型的值:LEFT、RIGHT、START、END、UP、DOWN

2、swipeDirs - 表示滑动的方向,有六个类型的值:LEFT、RIGHT、START、END、UP、DOWN

这两个参数如果为0表示不执行此操作

//1设置一个ItemTouchHelper.Callback对象 ItemTouchHelper.Callback callback = new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT, 0) {             /**             * @param recyclerView             * @param viewHolder 拖动的ViewHolder             * @param target 目标位置的ViewHolder             * @return             */            @Override            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,  RecyclerView.ViewHolder target) {                int fromPosition = viewHolder.getAdapterPosition();//得到拖动ViewHolder的position                int toPosition = target.getAdapterPosition();//得到目标ViewHolder的position                if (fromPosition < toPosition) {                    //分别把中间所有的item的位置重新交换                    for (int i = fromPosition; i < toPosition; i++) {                        Collections.swap(datas, i, i + 1);                    }                } else {                    for (int i = fromPosition; i > toPosition; i--) {                        Collections.swap(datas, i, i - 1);                    }                }                mAdapter.notifyItemMoved(fromPosition, toPosition);                //返回true表示执行拖动                return true;            }            /**             *    滑动时执行该方法     执行删除             */            @Override            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {                int position = viewHolder.getAdapterPosition();                datas.remove(position);                mAdapter.notifyItemRemoved(position);            }            /**             *    getMovementFlags ()返回支持哪些方向的事件(貌似拖动排序事件和左右滑动事件不能同时支持,拖动会覆盖左右滑动)             *     该方法第一个被调用   可加判断哪些可以拖动滑动   哪些不可以             */            @Override            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {                Log.d("flag","-------------------------getMovementFlags执行了");                if (viewHolder.getAdapterPosition() == 12 || viewHolder.getAdapterPosition() >  moduleListSize - 1) {                    return makeMovementFlags(0, 0);   //第13个轮播 和空白页不能操作                } else {                    if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {                        final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |  ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;                        final int swipeFlags = 0;                        return makeMovementFlags(dragFlags, swipeFlags);  //gridLayout不能滑动只能拖动                    } else {                        final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;                        final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;                        return makeMovementFlags(dragFlags, swipeFlags);                    }                }            }            /**             *  来改变动画效果,细心的会发现上图在滑动时候并没有透明感,于是我们可以实现onChildDraw()方法,该方法用于Item的绘制,actionState有三种状态SWIPE(滑动)、IDLE(静止)、DRAG(拖动)             */             @Override            public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,  float dX, float dY, int actionState, boolean isCurrentlyActive) {                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);                Log.d("flag", "-------------------------onChildDraw执行了");                if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {   //ACTION_STATE_SWIPE是滑动的时候 改变透明度                    //左右滑动时改变Item的透明度(没用到)                    final float alpha = 1 - Math.abs(dX) / (float) viewHolder.itemView.getWidth();                    viewHolder.itemView.setAlpha(alpha);                    viewHolder.itemView.setTranslationX(dX);                }            }                       /**             *   //当选中Item时候会调用该方法,重写此方法可以实现选中时候的一些动画逻辑             *    第二个调用             */            @Override            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {                super.onSelectedChanged(viewHolder, actionState);                Log.d("flag", "-------------------------onSelectedChanged执行了");                //长按  设置了放大的动画效果                if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {                    viewHolder.itemView.setScaleX(1.2f);                    viewHolder.itemView.setScaleY(1.2f);                }            }            /**             *   //当动画已经结束的时候调用该方法,重写此方法可以实现恢复Item的初始状态             */            @Override            public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {                super.clearView(recyclerView, viewHolder);                Log.d("flag", "------------------------clearView执行了");                //还原动画                viewHolder.itemView.setBackgroundResource(R.drawable.background_drag);                viewHolder.itemView.setScaleX(1.0f);                viewHolder.itemView.setScaleY(1.0f);                adapter.notifyDataSetChanged();//没看出什么用            }}