您当前的位置: 首页 > 
  • 0浏览

    0关注

    674博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

ItemTouchHelper实现拖拽和侧滑删除使用篇(一)

沙漠一只雕得儿得儿 发布时间:2020-05-02 15:20:00 ,浏览量:0

有时候我们可能需要实现侧滑删除的功能,又或者长按Item进行拖动与其他Item进行位置的交换,但RecyclerView没有提供现成的API供我们操作,但是SDK提供了ItemTouchHelper这样一个工具类帮助我们快速实现以上功能。首先我们来看下使用recyclerView的上下拖拽和侧滑删除效果,完整项目:

官方提供了ItemTouchHelper类使用步骤如下:

定义ItemTouchHelper.Callback实现类,以下是几个重要的方法

我们在使用ItemTouchHelper时,必须自定义一个ItemTouchHelper.Callback,我们来了解一下其中比较重要的几个方法。

方法名作用getMovementFlags

在此方法里面我们需要构建两个flag,一个是dragFlags,表示拖动效果支持的方向,另一个是swipeFlags,表示侧滑效果支持的方向。在我们的Demo中,拖动执行上下两个方向,侧滑执行左右两个方向,这些操作我们都可以在此方法里面定义。

onMove当拖动效果已经产生了,会回调此方法。在此方法里面,我们通常会更新数据源,就比如说,一个ItemView从0拖到了1位置,那么对应的数据源也需要更改位置。onSwiped当侧滑效果以上产生了,会回调此方法。在此方法里面,我们也会更新数据源。与onMove方法不同到的是,我们在这个方法里面从数据源里面移除相应的数据,然后调用notifyXXX方法就行了。
onSelectedChanged
在每次View Holder的状态变成拖拽 (ACTION_STATE_DRAG) 或者 滑动 (ACTION_STATE_SWIPE)的时候被调用。
clearView
在一个view被拖拽然后被放开的时候被调用,
import android.graphics.Canvas;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;

public class MessageItemTouchCallback extends ItemTouchHelper.Callback {

    private static final String TAG = "ItemTouchCallback";
    private ItemTouchHelperAdapterCallback adapterCallback;

    public MessageItemTouchCallback(ItemTouchHelperAdapterCallback adapterCallback) {
        this.adapterCallback = adapterCallback;
    }

    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        //callback回调监听哪些动作?---判断方向
        //表示拖动效果支持的方向
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        //表示侧滑效果支持的方向
        int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    @Override
    public boolean onMove(RecyclerView arg0, RecyclerView.ViewHolder srcHolder, RecyclerView.ViewHolder targetHolder) {
        // 监听滑动(水平方向、垂直方向)
        //让数据集合中的两个数据进行位置交换
        //同时还要刷新RecyclerView
        adapterCallback.onItemMove(srcHolder.getAdapterPosition(), targetHolder.getAdapterPosition());
        return true;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder holder, int arg1) {
        // 滑动动作的时候回调
        //1.删除数据集合里面的position位置的数据
        //2.刷新adapter
        adapterCallback.onItemSwiped(holder.getAdapterPosition());
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView,
                            RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState,
                            boolean isCurrentlyActive) {
        Log.d(TAG, "onChildDraw");
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState,
                isCurrentlyActive);
    }

    //滑动消失的距离,当滑动小于这个值的时候会删除这个item,否则不会视为删除
    //返回值作为用户视为拖动的距离
    @Override
    public float getSwipeThreshold(RecyclerView.ViewHolder viewHolder) {
        return 0.1f;
    }
    //返回值滑动消失的距离,滑动小于这个值不消失,大于消失

    @Override
    public float getSwipeEscapeVelocity(float defaultValue) {
        return 5f;
    }

    //设置手指离开后ViewHolder的动画时间
    @Override
    public long getAnimationDuration(RecyclerView recyclerView, int animationType, float animateDx, float animateDy) {
        return 100;
    }

    //网格型RecyclerView
    @Override
    public float getMoveThreshold(RecyclerView.ViewHolder viewHolder) {
        return 0.9f;
    }

    //返回值决定是否有滑动操作
    @Override
    public boolean isItemViewSwipeEnabled() {
        return true;
    }
}
声明ItemTouchHelper,并绑定到待管理的RecyclerView上
ItemTouchHelper.Callback callback = new MessageItemTouchCallback(adapter);
        itemTouchHelper = new ItemTouchHelper(callback);
        itemTouchHelper.attachToRecyclerView(recyclerView);
在Adapter中定义滑动删除和拖动排序的数据逻辑
@Override
    public boolean onItemMove(int fromPosition, int toPosition) {

        //让数据集合中的两个数据进行位置交换
        Collections.swap(list, fromPosition, toPosition);
        //同时还要刷新RecyclerView
//		notifyDataSetChanged();这种会刷新整个adapter不推荐使用
        notifyItemMoved(fromPosition, toPosition);

        return false;
    }

    @Override
    public void onItemSwiped(int adapterPosition) {
        //1.删除数据集合里面的position位置的数据
        list.remove(adapterPosition);
        //2.刷新adapter
        notifyItemRemoved(adapterPosition);
    }

这样一个拖动重排的功能就实现了。完整代码见:https://github.com/buder-cp/CustomView/tree/master/buder_DN_view/buderdn11

关注
打赏
1657159701
查看更多评论
立即登录/注册

微信扫码登录

0.0368s