13

When using the jetpack compose interoperability API, using LazyRow inside a prebuilt ViewPager causes scroll issues.

When trying to scroll items inside the LazyRow the ViewPager moves. Is there any way we can prevent this?

ComposeView

<androidx.compose.ui.platform.ComposeView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/compose_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Setting the view in the fragment

binding.composeView.setContent {
    HorizontalScrollableView(listOfCards)
}

And the view written in compose

@Composable
fun HorizontalScrollableView(listOfCards: List<Cards>) {
    Column(
        modifier = Modifier
            .background(color = colorResource(R.color.grey10))
    ) {
        Text(
            text = "Items",
            color = colors.primary,
            style = typography.subheadBold,
            fontSize = 15.sp,
            modifier = Modifier.padding(start = 16.dp, top = 10.dp, end = 16.dp)
        )
        LazyRow(contentPadding = PaddingValues(end = 16.dp)) {
            items(
                items = listOfCards,
                key = { listOfCards.id }
            ) {
                RenderCard(it)
            }
        }
    }
}

Akash Amin
  • 2,741
  • 19
  • 38
  • 1
    Do you have any news about this issue? @akash-amin – jzeferino Nov 15 '21 at 09:25
  • 2
    I believe the simplest solution would be migrating from ViewPager to compose `Pager` and using `AndroidView`s (or `AndroidViewBinding`s) for traditional views. – H.D. Nov 16 '21 at 08:50
  • Are you using ViewPager2 or just ViewPager? If it's ViewPager2 then I'd suggest to disable manual drag/scroll if it's feasible for you. – Jeel Vankhede Dec 01 '21 at 14:15
  • Here's the [compose pager doc](https://google.github.io/accompanist/pager/) in the accompanist library. – Noah Dec 01 '21 at 15:04

2 Answers2

1

It is a normal behavior you experience.The similar problem is described here.

Link

Alternatively, lazy row gestures can be controlled.

Modifier.pointerInput(Unit) {
    detectTapGestures(
        onPress = { /* Called when the gesture starts */ },
        onDoubleTap = { /* Called on Double Tap */ },
        onLongPress = { /* Called on Long Press */ },
        onTap = { /* Called on Tap */ }
    )
}

In onPress you can cancel the scroll state you want

Apart from composing, we were solving it this way.

Link

I hope this helps. Good job

Arda Kazancı
  • 8,341
  • 4
  • 28
  • 50
1

This is mainly because ComposeView is not implementing canScrollHorizontally correctly. ViewPager uses this method to decide whether it intercepts touch events.

A workaround:

Create a class extending FrameLayout, override canScrollHorizontally to always return true, and wrap ComposeView with this container. In this way, the scrolling in ComposeView works normally. The shortcoming of this workaround is that the ViewPager won't scroll if you are moving your finger on ComposeView, even when ComposeView has scrolled to the end.

hqzxzwb
  • 4,661
  • 2
  • 14
  • 15