Setup: I have a RecyclerView
with a vertical LinearLayoutManager
. Each ViewHolder
has 2 TextViews
(green and red in the picture), which can be very long. RED
can be scrolled horizontally thanks to a HorizontalScrollView
. GREEN
can be scrolled vertically thanks to a ScrollView
.
Now I have implemented ItemTouchHelper
, to swipe LEFT, UP or DOWN. The problem is that my ScrollViews
don't work anymore. Instead, even when I swipe GREEN
UP or DOWN, it is my ViewHolder
that moves. How do I prevent my ItemTouchHelper
from getting the touch event?
I've tried:
-android:descendantFocusability="blocksDescendants"
-NestedScrollView
instead of ScrollView
-implementing setOnTouchListener
inside my adapter to return true
(the listener is triggered, but the event is not consumed)
-thought about using RecyclerView.findChildViewUnder
inside onChildDraw
to scroll manually and block the super
method but I can't find a way to get the coordinates
Nothing works so far. How do I do this? Here is my ItemTouchHelper
:
private fun enableSwipe() {
val simpleItemTouchCallback =
object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.ACTION_STATE_IDLE, ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val position = viewHolder.adapterPosition
if (direction == ItemTouchHelper.LEFT) {
val content = mAdapter.getContentForPosition(position)
//do stuff...
}
}
override fun onChildDraw(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float,
dY: Float,
actionState: Int,
isCurrentlyActive: Boolean
) {
val mdX = if (abs(dY) > abs(dX)) {
0f
}else{
dX
}
val mdY = if (abs(dY) > abs(dX)) {
when{
dY > 0 -> if (dY > 500f) 500f else dY
else -> if (dY < -500f) -500f else dY
}
}else{
0f
}
//override viewHolder in case we swipe up or down on the other content
val mViewHolder: RecyclerView.ViewHolder = if (abs(dY) > abs(dX)) {
if (dY < 0) {
//swiping up
getViewHolder(1) ?: viewHolder
} else {
getViewHolder(0) ?: viewHolder
}
}else {
viewHolder
}
super.onChildDraw(c, recyclerView, mViewHolder, mdX, mdY, actionState, isCurrentlyActive)
}
}
val itemTouchHelper = ItemTouchHelper(simpleItemTouchCallback)
itemTouchHelper.attachToRecyclerView(recyclerViewClash)
}