Akash Amin
Akash Amin

Reputation: 2761

Scroll issues with LazyRow inside traditional android ViewPager

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)
            }
        }
    }
}

Upvotes: 14

Views: 2304

Answers (2)

hqzxzwb
hqzxzwb

Reputation: 4741

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.

Upvotes: 2

ΓDΛ
ΓDΛ

Reputation: 11060

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

Upvotes: 0

Related Questions