实现拖拽效果二: 使用RecyclerView + ItemTouchHelper 实现拖拽、删除,滑动删除效果

实现拖拽效果二: 使用RecyclerView + ItemTouchHelper 实现拖拽、删除,滑动删除效果

因为demo适配了公司的业务,具体图层不好放出来,难受。但是这毕竟只是记录学习,自己知道实现了就好!

之前是使用GridView实现的拖拽效果,但是其实他存在一个问题,当时涉及我本身的业务,所以使用那个很难实现,所以发现了这个。

GridView如果要实现横向滚动实现分页功能,并且支持拖拽互换就存在很大的问题,当然不同的trager也是可以实现的,但是很不方便,然后使用ItemTouchHelper实现就会很方便。横向滚动实现分页使用RecyclerView+ItemTouchHelper本身相较于GridView实现就简单很多,并且是google官方支持,丝毫不慌。

那么再整理思路,要完成那些方面,需要注意以下几点:

  1. 要解耦!不要一大堆文件全部卸载一两个java文件中,看着脑壳痛,让后期接手的人拿头维护。
  2. 业务需求的实现:分页和间隔。间隔必不可少,其次使用过recyclerView的都知道recyclerView是可以随意滚动的,要实现分页,像GridView+ViewPage实现效果,那就不能使得它能够随意滚动,而是一次滚动响应的列数(因为我这里是水平滚动,竖向类同)。
  3. 交互效果,也需要震动啊,改变底色啊等等
  4. 持久化,点击仿重等

这个实现方法比GridView实现着实简单很多,主要是代码的解耦啊,了解以下recyclerView和ItemTouchHelper的了解啊和具体的业务需求。

解耦

首先实现解耦,我的文件目录如下:

在这里插入图片描述

从上往下分别是

  • 实现分页效果的helper
  • 适配器
  • 回调 这个就是集成itemTouchHelper.Callback,用来实现拖拽效果。
  • itemTouchHelper和适配器之间的接口,实现解耦,具体的工作全部交给适配器去做
  • 间隔

itemTouchHelper实现

itemTouchHelper是google为我们封装的为recyclerView实现的可以拖拽交换item,侧滑删除item的封装类。

我们这里要完成这个效果,主要是集成itemTouchHelper.Callback接口就行。

必须完成的有三个函数:

  • getMovementFlags :设置拖拽方向和滑动方向。
  • onMove:实现拖拽移动的时候的监听。
  • onSwiped:实现滑动删除

其次之外涉及以下几个我们需要实现的父类的函数:

  • isLongPressDragEnabled(): 是否支持长按删除 (其实不弄也许)
  • isItemViewSwipeEnable():是否支持滑动删除(其实不弄也行,但是放在自己眼皮子底下放心点)
  • onSelectdChanged():选中的时候,会调用这个方法,在这里实现长按选中的震动、改变底色效果等
  • clearView():事件结束了,Up手指了,这里也是调用实现onSelectedChanged设置底色改变的取消等操作
  • onChildDraw():这里实现自己的自定义的交互规则,或者动画效果这里也行,我这里完成了拖拽删除的自定义交互效果。

完整的源码如下,具体的注释都有:

public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback {
    private MyItemTouchHelperListener mListener;	//适配器和itemTouchHelper之间的接口,完成解耦
    private boolean up;

    public MyItemTouchHelperCallback(MyItemTouchHelperListener mListener){
        this.mListener = mListener;
    }

    /**
     * 设置拖拽方向、滑动方向
     * @param recyclerView
     * @param viewHolder
     * @return
     */
    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        int dragFlags = 0;
        int swipeFlags = ItemTouchHelper.UP;
        if (recyclerView.getLayoutManager() instanceof GridLayoutManager || recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager){
            dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT;
        }
        else {
            dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        }
        return makeMovementFlags(dragFlags,swipeFlags);
    }

    /**
     * 拖拽移动
     * @param recyclerView
     * @param viewHolder
     * @param target
     * @return
     */
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        int fromPosition = viewHolder.getAdapterPosition();
        int toPosition = target.getAdapterPosition();
        mListener.onItemMove(fromPosition,toPosition);
        return true;
    }

    /**
     * 滑动删除
     * @param viewHolder
     * @param direction
     */
    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
//        mListener.onItemDelete(viewHolder.getAdapterPosition());
    }

    /**
     * 是否支持长按拖拽
     * @return
     */
    @Override
    public boolean isLongPressDragEnabled(){
        return true;
    }

    /**
     * 是否支持滑动
     * @return
     */
    @Override
    public boolean isItemViewSwipeEnabled(){
        return false;
    }

    /**
     * 选中的时候,会调用这个方法
     * @param viewHolder
     * @param actionState
     */
    @Override
    public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
        //不等于休闲的时候,也就是被选中了
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE){
            up = false;
            mListener.onSelectedItem(viewHolder);
        }
        super.onSelectedChanged(viewHolder, actionState);
    }

    /**
     * 事件结束
     * @param recyclerView
     * @param viewHolder
     */
    @Override
    public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        mListener.onSelectedFinish(viewHolder);
        super.clearView(recyclerView, viewHolder);
    }
	/**
	* 完成自定义的交互规则
	* 完成对item拖拽到一定位置的删除
	*
	*/
    @Override
    public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        if (mListener == null)
            return;
//        Log.d(TAG, "onChildDraw:dY " + dY);
        //因为dY是以本身为坐标的,所以只要他向上就为负的,向下就为正的,所以要
        //记录相关变化,使得控件完全画出界面就删除
        int result = viewHolder.itemView.getBottom();
        float res = result+dY;
        int index = viewHolder.getAdapterPosition();
//        Log.d(TAG, "onChildDraw:Result " + res);
//        Log.d(TAG, "onChildDraw:Position " + viewHolder.getAdapterPosition());
        if (res < 0){
            if (up){	//这里的up必须有,否则删除了当前item一会,因为还在滑动,会返回index为-1
                mListener.onItemDelete(index);
                up = false;
            }
//            Log.d(TAG, "onChildDraw: "+index);
        }
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, is
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值