当前位置:   article > 正文

RecyclerView拖拽移动,长按小图标拖拽,侧滑删除_android recyclerview图标拖拽排序

android recyclerview图标拖拽排序

RecyclerView拖拽移动,长按小图标拖拽,侧滑删除

Github源码


长按小图标拖拽.gif

侧滑删除.gif


  • Android RecyclerView出来也很多年了,是非常成熟的控件,Github上工具一堆,做的非常全,侧滑、拖拽、动画都封装好的,但是工作需求,这种小功能就不用别人的,自己学习一下,写一个简单的代码即可实现。

  • RecyclerView的拖拽跟侧滑删除,其实就是使用 ItemTouchHelper 来实现,而我们只要写一下CallBack 继承 ItemTouchHelper.Callback(),重写里面的方法就行。

  • 要注意的一点是,完成CallBack直接长按就能实现拖拽,但是点小图标拖拽,其实就是加个开关,item要使用ontouch回调来处理,而不要使用长按longClick回调,因为在三星手机上,onLongClick回调是在CallBack之后的,就会无法拖拽,而国产系统都是longClick先回调,坑了我一把。

  • 一定会重写的三个方法,功能如下。

/**
 * 设置拖拽、滑动方向
 */
override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
    if (!edit) {
        return 0
    }

    //拖拽方向
    val dragFlags =
        ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT

    //侧滑删除
    val swipeFlags =  ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT

    return makeMovementFlags(dragFlags, swipeFlags)
}

/**
 * 拖拽移动
 */
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
    //不同类型的item不能移动
    if (viewHolder.itemViewType != target.itemViewType) {
        return false
    }

    //拖动的position
    var fromPosition = viewHolder.adapterPosition
    //释放的position
    var targetPosition = target.adapterPosition

    onCallBack.onMove(fromPosition, targetPosition)
    return true
}

/**
 * 侧滑
 */
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
    onCallBack.remove(viewHolder,direction,viewHolder.layoutPosition)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 按自己需求重写其他的方法,功能如下。
/**
 * 长按时调用
 */
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
    super.onSelectedChanged(viewHolder, actionState)
    viewHolder?.let {
        //长按
        onCallBack.onSelectedChanged(viewHolder, actionState)
    }
}

/**
 * 松手时会最后调用
 */
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
    super.clearView(recyclerView, viewHolder)

    onCallBack.clearView(recyclerView, viewHolder)
}

/**
 * 是否支持长按,默认true
 */
override fun isLongPressDragEnabled(): Boolean {
    return super.isLongPressDragEnabled()
}

/**
 * 是否支持侧滑,默认true
 */
override fun isItemViewSwipeEnabled(): Boolean {
    return super.isItemViewSwipeEnabled()
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 当我们移动item,数据换位置,就要自己写逻辑了。
/**
 * 移动item
 *
 * @param fromPosition   长按的item,position
 * @param targetPosition 要到达的position
 */
fun itemMove(adapter: RecyclerView.Adapter<RecyclerView.ViewHolder>, data: List<*>, fromPosition: Int, targetPosition: Int) {
    if (adapter == null || data.isEmpty()) {
        return
    }

    if (fromPosition < targetPosition) {
        for (i in fromPosition until targetPosition) {
            Collections.swap(data, i, i + 1)
        }
    } else {
        for (i in targetPosition until fromPosition) {
            Collections.swap(data, i, i + 1)
        }
    }
    adapter.notifyItemMoved(fromPosition, targetPosition)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 这整个callback就完成了。
class RecyclerTouchHelpCallBack(var onCallBack: OnHelperCallBack) : ItemTouchHelper.Callback() {
    //拖拽开关
    var edit = false


    /**
     * 设置拖拽、滑动方向
     */
    override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
        if (!edit) {
            return 0
        }

        //拖拽方向
        val dragFlags =
            ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT

        //侧滑删除
        val swipeFlags =  ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT

        return makeMovementFlags(dragFlags, swipeFlags)
    }

    /**
     * 拖拽移动
     */
    override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
        //不同类型的item不能移动
        if (viewHolder.itemViewType != target.itemViewType) {
            return false
        }

        //拖动的position
        var fromPosition = viewHolder.adapterPosition
        //释放的position
        var targetPosition = target.adapterPosition

        onCallBack.onMove(fromPosition, targetPosition)
        return true
    }

    /**
     * 侧滑
     */
    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
        onCallBack.remove(viewHolder,direction,viewHolder.layoutPosition)
    }

    /**
     * 长按时调用
     */
    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
        super.onSelectedChanged(viewHolder, actionState)
        viewHolder?.let {
            //长按
            onCallBack.onSelectedChanged(viewHolder, actionState)
        }
    }

    /**
     * 松手时会最后调用
     */
    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
        super.clearView(recyclerView, viewHolder)

        onCallBack.clearView(recyclerView, viewHolder)
    }

    /**
     * 是否支持长按,默认true
     */
    override fun isLongPressDragEnabled(): Boolean {
        return super.isLongPressDragEnabled()
    }

    /**
     * 是否支持侧滑,默认true
     */
    override fun isItemViewSwipeEnabled(): Boolean {
        return super.isItemViewSwipeEnabled()
    }


    /**
     * 移动item
     *
     * @param fromPosition   长按的item,position
     * @param targetPosition 要到达的position
     */
    fun itemMove(adapter: RecyclerView.Adapter<RecyclerView.ViewHolder>, data: List<*>, fromPosition: Int, targetPosition: Int) {
        if (adapter == null || data.isEmpty()) {
            return
        }

        if (fromPosition < targetPosition) {
            for (i in fromPosition until targetPosition) {
                Collections.swap(data, i, i + 1)
            }
        } else {
            for (i in targetPosition until fromPosition) {
                Collections.swap(data, i, i + 1)
            }
        }
        adapter.notifyItemMoved(fromPosition, targetPosition)
    }

    interface OnHelperCallBack {
        fun onMove(fromPosition: Int, targetPosition: Int)

        fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder, actionState: Int)

        fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder)

        fun remove(viewHolder: RecyclerView.ViewHolder, direction: Int, position: Int)
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 使用简单。
callback = RecyclerTouchHelpCallBack(object : RecyclerTouchHelpCallBack.OnHelperCallBack {
    override fun onMove(fromPosition: Int, targetPosition: Int) {
        //移动item
        callback.itemMove(adapter, adapter.mData, fromPosition, targetPosition)
    }

    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder, actionState: Int) {
        //选中的改变样式
        viewHolder.itemView.alpha = 1f
        viewHolder.itemView.scaleX = 1.2f
        viewHolder.itemView.scaleY = 1.2f
    }

    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
        //松手后不让操作,不然会点击全部范围拖拽
        callback.edit = false
        //完成移动,选中的改变样式
        adapter.mData
        viewHolder.itemView.alpha = 1f
        viewHolder.itemView.scaleX = 1f
        viewHolder.itemView.scaleY = 1f
    }

    override fun remove(viewHolder: RecyclerView.ViewHolder, direction: Int, position: Int) {
        // callback.edit = false,所以不会触发侧滑删除
       adapter.removeData(position)
    }
})

ItemTouchHelper(callback).attachToRecyclerView(rv_item)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/286767
推荐阅读
相关标签
  

闽ICP备14008679号