https://kotlinlang.org logo
#compose
Title
# compose
n

Nicolai

10/01/2023, 7:38 PM
Hey Guys 👋 , I’ve been trying to create a HorizontalPager that makes sure that each item has the same height. As it is done inside a LazyColumn I have tried to do so with subcomposeLayout. I’m still very new to Compose so feel free to drop any knowledge and improvements you can think of 🙏 It doesn’t really work :( Would appreciate any help 🙏 Code in thread
Copy code
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun PwHorizontalPager(
    content: List<@Composable () -> Unit>
) {
    Box(
        modifier = Modifier
            .fillMaxWidth()
    )
    {
        val pagerState = rememberPagerState(
            pageCount = { content.size }
        )
        val placeables: ArrayList<Placeable> = arrayListOf()
        var maximumHeight by remember {
            mutableStateOf(300.dp)
        }

        SubcomposeLayout(modifier = Modifier.fillMaxSize()) { constraints ->
            content.forEachIndexed { index, composable ->
                placeables.addAll(subcompose(index, composable).map { it.measure(constraints) })
            }

            placeables.forEach { Timber.v("height: " + it.height) }

            maximumHeight = maxOf(0.dp, placeables.maxByOrNull { it.height }?.height?.toFloat()?.toDp() ?: 0.dp)

            layout(constraints.maxWidth, constraints.maxHeight) {
}
        }

        HorizontalPager(
            modifier = Modifier
                .fillMaxWidth(),
            state = pagerState,
            userScrollEnabled = true,
            verticalAlignment = Alignment.Top,
            contentPadding = PaddingValues(16.dp),
            beyondBoundsPageCount = content.size,
            pageSpacing = 32.dp
        ) {
            content[it]()
        }
    }
}
c

Colton Idle

10/03/2023, 6:20 AM
You can't really do this with HorizontalPager since its a Lazy* layout. I did this in a personal project in two different ways: 1. Look at past implementations of HorizontalPager in accompanist. The initial impl of HP used to be non-lazy. just copy paste that. 2. Just use a Scrollable Row and set the snapping feature to it and you have yourself a cheap HorizontalPager where everything is laid out and measured before hand.
n

Nicolai

10/03/2023, 6:44 AM
Thanks @Colton Idle I actually ended up with a solution that works with HorizontalPager. Not a pretty one but works. Your other ideas are where I'm going next for further improvements. Thanks for taking your time to answer! 🙏
c

Colton Idle

10/03/2023, 6:25 PM
What was the solution with HP?
n

Nicolai

10/04/2023, 7:39 AM
There were still some hiccups unfortunately making it not work so great after all. Sorry to disappoint 😓
Hmm going back to this… Do you have any example of how to get a snapping behavior on a normal row? I see plenty for a LazyRow but that’s not what I need here for the items to be measured out beforehand.
n

Nicolai

10/13/2023, 6:18 AM
I’ll take a look asap Thanks again Colton!
Thanks Colton I got it working! 🙏
c

Colton Idle

10/18/2023, 4:18 PM
Nice!