Я пытался реализовать «меню смахивания» для своих элементов в RecyclerView, используя «ItemTouchHelper.Callback».Сначала я пытаюсь остановить элемент в определенной позиции, а не сдвинуть его обратно в положение (X) 0.
Для этого решения я просто следовал руководству поСредний и он должен делать, как описано выше: https://codeburst.io/android-swipe-menu-with-recyclerview-8f28a235ff28
Код ниже не на 100% такой же, как в учебнике, так как я также хотел реализовать функцию перетаскивания элементов (которая работает).
Тем не менее, я пытался следовать учебному пособию шаг за шагом, но безуспешно.Я не могу найти других полезных руководств и т. Д. Для этой конкретной функции
Вот мой код для реализации ItemTouchHelper.Callback:
enum class ButtonsState {
GONE,
VISIBLE
}
class SwipeItemHelper : ItemTouchHelper.Callback {
private var mAdapter: ItemTouchHelperAdapter
private var swipeBack: Boolean = true
private var buttonShowedState: ButtonsState = ButtonsState.GONE
private val buttonsWidth: Float = 300f
constructor(adapter: ItemTouchHelperAdapter) {
mAdapter = adapter
}
override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
if (actionState == ACTION_STATE_SWIPE) {
setTouchListener(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
}
private fun setTouchListener(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
recyclerView.setOnTouchListener { v, event ->
swipeBack = event.action == MotionEvent.ACTION_CANCEL || event.action == MotionEvent.ACTION_UP
if (swipeBack) {
if (dX < -buttonsWidth)
buttonShowedState = ButtonsState.VISIBLE
if (buttonShowedState !== ButtonsState.GONE) {
setTouchDownListener(c, recyclerView, viewHolder, -buttonsWidth, dY, actionState, isCurrentlyActive)
setItemsClickable(recyclerView, false)
}
}
false
}
}
// SwipeController.java
private fun setTouchDownListener(c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float, dY: Float,
actionState: Int, isCurrentlyActive: Boolean) {
recyclerView.setOnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
setTouchUpListener(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
}
false
}
}
private fun setTouchUpListener(c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float, dY: Float,
actionState: Int, isCurrentlyActive: Boolean) {
recyclerView.setOnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_UP) {
SwipItemHelper@super.onChildDraw(c, recyclerView, viewHolder, 0f, dY, actionState, isCurrentlyActive)
recyclerView.setOnTouchListener { v, event -> false }
setItemsClickable(recyclerView, true)
swipeBack = false
buttonShowedState = ButtonsState.GONE
}
false
}
}
private fun setItemsClickable(recyclerView: RecyclerView,
isClickable: Boolean) {
for (i in 0 until recyclerView.childCount) {
recyclerView.getChildAt(i).isClickable = isClickable
}
}
override fun convertToAbsoluteDirection(flags: Int, layoutDirection: Int): Int {
if (swipeBack) {
swipeBack = false
return 0
}
return super.convertToAbsoluteDirection(flags, layoutDirection)
}
override fun getMovementFlags(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?): Int {
val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
val swipeFlags = ItemTouchHelper.START
return makeMovementFlags(dragFlags, swipeFlags)
}
override fun onMove(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?, target: RecyclerView.ViewHolder?): Boolean {
if (viewHolder == null || target == null)
return false
mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition())
return true
}
override fun isLongPressDragEnabled(): Boolean {
return true
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder?, direction: Int) {
}
}