I need to scroll programatically (in order to snap items to adjust symmetrically top and bottom) after scrolling or after a tap (click) in a lazy column. I also need to start at a specific item when app launches - starts.
I am using pointerInteropFilter to be able to run some code at these actions: down, move, up. The code runs ok when I tap but it does not trigger ACTION_UP after a move is done.
[this is the desired result as soon as I release the finger from the screen... that is... a "jump" or scroll to a value that in this cases is item 10 and some offset][1]
The code is working only for tap... but the coroutine is not working when Action_up
I read that we are adviced to "prefer pointerInput] and use this only for interoperation with
- existing code that consumes [MotionEvent]s"
It also say that pointerinteropFilter try to make a seamless treatment between view and motion events... but I dont know if it is relevant.
Thanks.
Mauricio
@Composable
fun Greeting(name: String) {
val listState2 = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
LazyColumn(
state = listState2,
) {
items (50) {index ->
Text(
modifier = Modifier
.pointerInteropFilter {
when (it.action) {
MotionEvent.ACTION_DOWN -> {
Log.i(ContentValues.TAG, "down pressed")
false
}
MotionEvent.ACTION_MOVE -> {
Log.i(ContentValues.TAG, "moved done")
false
}
MotionEvent.ACTION_UP -> {
coroutineScope.launch {
listState2.scrollToItem(10, 28)
}
Log.i(ContentValues.TAG, "up detected")
}
MotionEvent.ACTION_CANCEL -> {
coroutineScope.launch {
listState2.scrollToItem(10, 28)
}
Log.i(ContentValues.TAG, "canceled chosen")
false
}
else ->
false
}
true
},
text = "item $index",
)
}
}
}```
[1]: https://i.stack.imgur.com/vSiCG.png
I've faced the same issues.
The
onClick=function doesn't work for all descendants, that are placed in the same composable ConstraintLayout, if the layout uses.pointerInteropFilterand returns true as a result of catchingACTION_UPMotionEvent.It's related to the fact that clickable logic under the hood expects
PressInteraction.Presswhich value is a simple mapping fromACTION_UP. Thus ConstraintLayout by catchingACTION_UPMoutionEvent prevents passing ofPressInteraction.Pressto descendants.If the ConstraintLayout will return false on
ACTION_UPMoutionEvent, then the next MotionEvents won't be dispatched to it next time. Because of implementation under the hood.So the root cause of the issue is misusing of the
Modifier.pointerInteropFilter. The idea behind the function is filtering events, what it actually does.In my case looks like it's required to rewrite Touch logic to
Modifier.pointerInput.Maybe this findings will help you as well