android 限制项目在一个范围内拖动 itemtouchhelper
android limit item dragging in a range itemtouchhelper
我用 RecyclerView 显示了一个项目列表,我有不同类型的项目(headers 和项目),如下所示
Header 1
Item 1
Item 2
Header 2
Item 3
Item 4
Item 5
Item 6
Header 3
Item 7
....
我想限制在 Header 部分内交换项目的位置。因此,例如,项目 4 可以与项目 3、项目 5 和项目 6 交换,但不能超出其部分边界。我正在使用 ItemTouchHelper
来实现拖动机制的交换,如这里所建议的 https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf and https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-6a6f0c422efd
我重载了 canDropOver
方法,如果您想交换例如项目 4 和 Header 2,这会有所帮助,但不会阻止我将项目拖动到 Header 1。有什么建议吗?
设置 canDropOver
后,最后一块拼图是覆盖 onChildDraw
并限制 dY
值(假设垂直列表 - 限制 dX
值(如果使用水平列表)每当 ViewHolder
被拖向相邻的 ViewHolder
它就不能掉落。
例如:
override fun onChildDraw(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float,
dY: Float,
actionState: Int,
isCurrentlyActive: Boolean
) {
val previousViewHolder = recyclerView.findViewHolderForAdapterPosition(viewHolder.bindingAdapterPosition - 1)
val nextViewHolder = recyclerView.findViewHolderForAdapterPosition(viewHolder.bindingAdapterPosition + 1)
val isDraggingUpward = dY < 0
val isDraggingDownward = dY > 0
val isDraggingIntoUndraggableArea =
(isDraggingUpward && previousViewHolder != null && !canDropOver(recyclerView, viewHolder, previousViewHolder))
|| (isDraggingDownward && nextViewHolder != null && !canDropOver(recyclerView, viewHolder, nextViewHolder))
val newDy = if (isDraggingIntoUndraggableArea) {
0f // Clamp
} else {
dY
}
super.onChildDraw(c, recyclerView, viewHolder, dX, newDy, actionState, isCurrentlyActive)
}
我还有一个存储库,你可以参考它有一个完整的应用程序示例:
https://github.com/nihk/ClampedItemTouchHelper
我用 RecyclerView 显示了一个项目列表,我有不同类型的项目(headers 和项目),如下所示
Header 1
Item 1
Item 2
Header 2
Item 3
Item 4
Item 5
Item 6
Header 3
Item 7
....
我想限制在 Header 部分内交换项目的位置。因此,例如,项目 4 可以与项目 3、项目 5 和项目 6 交换,但不能超出其部分边界。我正在使用 ItemTouchHelper
来实现拖动机制的交换,如这里所建议的 https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf and https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-6a6f0c422efd
我重载了 canDropOver
方法,如果您想交换例如项目 4 和 Header 2,这会有所帮助,但不会阻止我将项目拖动到 Header 1。有什么建议吗?
设置 canDropOver
后,最后一块拼图是覆盖 onChildDraw
并限制 dY
值(假设垂直列表 - 限制 dX
值(如果使用水平列表)每当 ViewHolder
被拖向相邻的 ViewHolder
它就不能掉落。
例如:
override fun onChildDraw(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float,
dY: Float,
actionState: Int,
isCurrentlyActive: Boolean
) {
val previousViewHolder = recyclerView.findViewHolderForAdapterPosition(viewHolder.bindingAdapterPosition - 1)
val nextViewHolder = recyclerView.findViewHolderForAdapterPosition(viewHolder.bindingAdapterPosition + 1)
val isDraggingUpward = dY < 0
val isDraggingDownward = dY > 0
val isDraggingIntoUndraggableArea =
(isDraggingUpward && previousViewHolder != null && !canDropOver(recyclerView, viewHolder, previousViewHolder))
|| (isDraggingDownward && nextViewHolder != null && !canDropOver(recyclerView, viewHolder, nextViewHolder))
val newDy = if (isDraggingIntoUndraggableArea) {
0f // Clamp
} else {
dY
}
super.onChildDraw(c, recyclerView, viewHolder, dX, newDy, actionState, isCurrentlyActive)
}
我还有一个存储库,你可以参考它有一个完整的应用程序示例: https://github.com/nihk/ClampedItemTouchHelper