wbk727
wbk727

Reputation: 8408

Nested LazyRow not scrolling vertically when scrolling LazyColumn

For some reason, my LazyRow inside a Cloumn won't budge whenever I veritically scroll through the LazyColumn. The LazyColumn works perfectly though.

@Composable
fun Screen() {
    ReusableScaffold(
        scaffoldTitle = "Demo",
        scaffoldContent = {
            MyScreenContent(contentPadding = it)
        }
    )
}

@Composable
fun MyReusableScaffold(scaffoldTitle: String, scaffoldFab: @Composable () -> Unit,
                       scaffoldContent: @Composable (contentPadding: PaddingValues) -> Unit) {
    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()

    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        topBar = {
            LargeTopAppBar(
                title = {Text(text = scaffoldTitle)},
                scrollBehavior = scrollBehavior
            )
        },
        content = { contentPadding -> scaffoldContent(contentPadding = contentPadding) }
    )
}

@Composable
fun MyScreenContent(
    modifier: Modifier = Modifier,
    contentPadding: PaddingValues = PaddingValues()
) {
    // Example data sets
    val rowItems = arrayOf(
        RowItems.ItemRowCheetah,
        RowItems.ItemRowPuma,
        RowItems.ItemRowJaguar,
        RowItems.ItemRowPanther,
        RowItems.ItemRowTiger
    )

    val columnItems = arrayOf(
        ColumnItems.ItemPetitFour,
        ColumnItems.ItemCupcake,
        ColumnItems.ItemDonut,
        ColumnItems.ItemEclair,
        ColumnItems.ItemFroyo
    )

    Box(modifier = modifier
        .fillMaxSize()
        .padding(contentPadding)) {
        Column(content = {
                ReusableLazyRow(
                    lazyRowItems = rowItems,
                    lazyRowItemLayout = {
                        Card(
                            modifier = Modifier
                                .height(250.dp)
                                .padding(16.dp),
                            shape = RoundedCornerShape(size = 16.dp),
                        ) {
                            Column {
                                Text(text = it.rowItemTitle)
                                Text(text = it.rowItemDesc)
                            }
                        }
                    }
                )

                ReusableLazyColumn(
                    lazyColumnItems = columnItems,
                    lazyColumnItemLayout = {
                        Row { Text(text = it.columnItemTitle) }
                    }
                )
            }
        )
    }
}

@Composable
fun <T> ReusableLazyRow(lazyRowItems: Array<T>,
                        lazyRowItemLayout: @Composable Any.(item: T) -> Unit,
                        onClickLazyRowItem: (T) -> Unit
) {
    val listState = rememberLazyListState()

    LazyRow(
        modifier = Modifier
            .fillMaxWidth()
            .height(300.dp),
        state = listState,
        contentPadding = PaddingValues(top = 0.dp, bottom = 0.dp)
    ) {
        items(lazyRowItems) { itemR ->
            Column(modifier = Modifier
                .clickable {
                    onClickLazyRowItem(itemR)
                }) {
                lazyRowItemLayout(itemR)
            }
        }
    }
}

@Composable
fun <T> ReusableLazyColumn(
    lazyColumnItems: Array<T>,
    lazyColumnItemLayout: @Composable Any.(item: T) -> Unit,
    onClickLazyColumnItem: (T) -> Unit
) {
    val listState = rememberLazyListState()

    LazyColumn(
        state = listState,
        contentPadding = PaddingValues(top = 0.dp, bottom = 20.dp)
    ) {
        items(lazyColumnItems) { itemC -> 
            Row(modifier = Modifier
                .fillMaxWidth()
                .clickable {
                    onClickLazyColumnItem(itemC)
                }) {
                lazyColumnItemLayout(itemC)
            }
        }
    }
}

enter image description here

enter image description here

Upvotes: 0

Views: 446

Answers (1)

Eliza Camber
Eliza Camber

Reputation: 1652

The reason is that the Column will always show all the items inside it. In order to use two (lazy) columns with the same scrolling direction, you have two options. Either you will add a header to your ReusableLazyColumn or you get rid of the ReusableLazyColumn altogether and use a LazyColum instead of a Column with the same children as the code below (item {...} for the ReusableLazyRow header and items(columnItems) {...} for the rest)

@Composable
fun <T> ReusableLazyColumn(
    header: @Composable () -> Unit,
    lazyColumnItems: Array<T>,
    lazyColumnItemLayout: @Composable Any.(item: T) -> Unit,
    onClickLazyColumnItem: (T) -> Unit
) {
    val listState = rememberLazyListState()

    LazyColumn(
        state = listState,
        contentPadding = PaddingValues(top = 0.dp, bottom = 20.dp)
    ) {
        item { header.invoke() }
        items(lazyColumnItems) {
            Row(modifier = Modifier
                .fillMaxWidth()
                .clickable {
                    onClickLazyColumnItem(it)
                }) {
                lazyColumnItemLayout(it)
            }
        }
    }
}

--------

Box(
        modifier = modifier
            .fillMaxSize()
            .padding(contentPadding)
    ) {
        ReusableLazyColumn(
            header = {
                ReusableLazyRow(
                    lazyRowItems = rowItems,
                    lazyRowItemLayout = {
                        Card(
                            modifier = Modifier
                                .height(250.dp)
                                .padding(16.dp),
                            shape = RoundedCornerShape(size = 16.dp),
                        ) {
                            Column {
                                Text(text = it)
                            }
                        }
                    },
                    onClickLazyRowItem = {}
                )
            },
            lazyColumnItems = columnItems,
            lazyColumnItemLayout = { Row(Modifier.height(120.dp)) { Text(text = it) } },
            onClickLazyColumnItem = {}
        )
}

Upvotes: 1

Related Questions