MaterialDesign-RecyleView探究及使用【四】-RecyleView交互动画

实现RecyleView中使用ItemTouchHelper实现拖拽和侧滑删除效果,实现步骤分析如下:
效果图:

MaterialDesign-RecyleView探究及使用【四】-RecyleView交互动画_第1张图片图注:效果图

一、创建ItemTouchHelper对象

ItemTouchHelper.Callback callback = new ItemTouchHelperCallBack(adapter);
//条目触摸辅助类
itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyleview);

ItemTouchHelper属于android.support.v7.widget.helper中的类,我们来创建ItemTouchHelper实例,发现需要一个Callback,该Callback是ItemTouchHelper.Callback属于ItemTouchHelper内部类;

接着我们就需要新建一个类比如ItemTouchHelperCallback继承自ItemTouchHelper.Callback,itemTouchHelper.attachToRecyclerView(recyleview)方法将ItemTouchHelper与recyleview进行绑定,然后通过监听recyleview条目的上下左右触摸滑动童工callback回调监听方法,所以callback就是个中间接口;

继承自ItemTouchHelper.Callback需要重写其相关方法,ItemTouchHelper.Callback必需要重写的几个方法。

1、public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)

该方法主要定义返回可以滑动的方向,比如说允许从右到左侧滑,允许上下拖动等。通过源码注释可以看到可以使用makeMovementFlags(int,int)或makeFlag(int, int)来构造返回值。

2、public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)

查看源码注释中的内容:Called when ItemTouchHelper wants to move the dragged item from its old position to the new position.
当条目触发移动拖拽时会回调改方法。

3、public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction)

查看源码注释内容:Called when a ViewHolder is swiped by the user.
当条目左右滑动的时候触发

getMovementFlags方法中定义好触摸滑动的方向代码如下:

@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
   int dragFlag = ItemTouchHelper.DOWN | ItemTouchHelper.UP;
   int swipeFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
   int flag = makeMovementFlags(dragFlag,swipeFlag);
   return flag;
}

这样就可以触发长按拖拽效果和触摸左右滑动效果,但是不会真正的换位置和删除条目,还需要自己实现数据源的刷新业务。触发这个效果也是有两个默认方法起到作用

4、public boolean isLongPressDragEnabled():

该方法返回true时,表示支持长按拖动,即长按ItemView后才可以拖动,我们遇到的场景一般也是这样的。默认是返回true。

5、public boolean boolean isItemViewSwipeEnabled():

该方法返回true时,表示如果用户触摸并左右滑动了View,那么可以执行滑动删除操作,即可以调用到onSwiped()方法。默认是返回true。

二、拖拽效果触发

如果要主动触发上下拖拽换位置的效果,例如,条目中触摸头像实现上下拖拽互换位置的效果,需要用到一个方法:itemTouchHelper.startDrag(viewHolder);来主动触发条目的拖拽效果

1、在Adapter中添加头像的触摸拖拽事件

adapter中添加头像的触摸事件:

holder.ivHead.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event{
        if(event.getAction() == MotionEvent.ACTION_DOWN){
            if(dragListener != null){
                dragListener.startDrag(holder);
            }
        }
        return false;
    }
});

adapter由于需要activity中的itemTouchHelper通信,两个类建立联系最好的方式就是通过接口,需要定义一个接口StartDragListener 让activity实现该方法,并在new adapterStartDragListener)对象传入,activity实现接口方法,并触发itemTouchHelper.startDrag(viewHolder);方法。

RVTouchActivity中实现接口方法:

@Override
public void startDrag(RecyclerView.ViewHolder viewHolder) {
    itemTouchHelper.startDrag(viewHolder);
}

StartDragListener 接口定义:

public interface StartDragListener {
    void startDrag(RecyclerView.ViewHolder viewHolder);
}
2、实现拖拽移动位置和侧滑删除功能

要真正实现拖拽后移动位置效果,需要用到adapter.notifyItemMoved(startPosition,tagetPosition);而需要触发移动拖拽的方法是onMove方法,所以需要在onMove方法中触发adapter.notifyItemMoved(startPosition,tagetPosition),这里又是两个类之间通信,最好的方法还是定义接口,通过接口触发,如下是onMove和onSwiped方法的实现,我们都通过moveListener接口来触发

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {

    if(viewHolder.getItemViewType() != target.getItemViewType()){
        return false;
    }
    if(moveListener != null){
        moveListener.onItemMove(viewHolder.getAdapterPosition(),target.getAdapterPosition());
    }
    return true;
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    if(moveListener != null){
        moveListener.onItemReMove(viewHolder.getAdapterPosition());
    }
}

ItemTouchMoveListener 接口定义:

public interface ItemTouchMoveListener {
    void onItemMove(int startPosition,int tagetPosition);//拖拽方法

    void onItemReMove(int adapterPosition);//移除方法
}

adapter中实现该接口,并实现接口方法:
由于adapter实现了ItemTouchMoveListener 接口,可以通过如下方法将接口传给ItemTouchHelperCallBack
ItemTouchHelper.Callback callback = new ItemTouchHelperCallBack(adapter);

@Override
public void onItemMove(int startPosition, int tagetPosition) {
    Collections.swap(data,startPosition,tagetPosition);//数据源排序
    this.notifyItemMoved(startPosition,tagetPosition);//刷新视图
}

@Override
public void onItemReMove(int adapterPosition) {
    data.remove(adapterPosition);//数据源移除条目数据
    this.notifyItemRemoved(adapterPosition);//刷新视图
}

三、侧滑动画以及选中背景效果

ItemTouchHelper.Callback中还有一些方法,可以实现相应的效果

1、public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState):

从静止状态变为拖拽或者滑动的时候会回调该方法,参数actionState表示当前的状态。

2、public void clearView(RecyclerView recyclerView, ViewHolder viewHolder):

当用户操作完毕某个item并且其动画也结束后会调用该方法,一般我们在该方法内恢复ItemView的初始状态,防止由于复用而产生的显示错乱问题。

3、public void onChildDraw(…):

我们可以在这个方法内实现我们自定义的交互规则或者自定义的动画效果。

具体实现如下:

@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
    if(actionState!=ItemTouchHelper.ACTION_STATE_IDLE){
            viewHolder.itemView.setBackgroundColor(
viewHolder.itemView.getContext()
.getResources()
.getColor(R.color.colorAccent));
    }
    super.onSelectedChanged(viewHolder, actionState);
}

@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    viewHolder.itemView.setBackgroundColor(Color.WHITE);
    viewHolder.itemView.setAlpha(1);
    viewHolder.itemView.setScaleX(1);
    viewHolder.itemView.setScaleY(1);
    super.clearView(recyclerView, viewHolder);
}

@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
    if(actionState==ItemTouchHelper.ACTION_STATE_SWIPE){
        float alpha = 1-Math.abs(dX)/viewHolder.itemView.getWidth();
        viewHolder.itemView.setAlpha(alpha);//1~0
        viewHolder.itemView.setScaleX(alpha);//1~0
        viewHolder.itemView.setScaleY(alpha);//1~0
    }
    super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}

源码地址:https://github.com/heiyl/recyleview

MaterialDesign-RecyleView探究及使用【四】-RecyleView交互动画_第2张图片图注:关注公众号

你可能感兴趣的:(Android进阶学习)