Karlo Vuljanko
07/20/2023, 10:18 AMIntrinsicSize.Max()
in lazy components. (Understandably)
is there an easy way to work around this or do i have to do some magic with SubcomposeLayout / Create quasi non lazy pager with Row composable?Stylianos Gakis
07/20/2023, 10:27 AMAnchoredDraggable it seems.Karlo Vuljanko
07/20/2023, 10:40 AMKarlo Vuljanko
07/20/2023, 10:41 AMStylianos Gakis
07/20/2023, 10:43 AMKarlo Vuljanko
07/20/2023, 11:44 AMAlbert Chang
07/20/2023, 11:44 AMoffscreenLimit to cover all the pages and you should be able to achieve what you want.Karlo Vuljanko
07/20/2023, 11:49 AMStylianos Gakis
07/20/2023, 11:49 AMColton Idle
07/21/2023, 10:34 PMColton Idle
07/21/2023, 10:34 PMStylianos Gakis
07/21/2023, 11:03 PMAndrey Kulikov
07/22/2023, 1:02 PMbeyondBoundsPageCount param on HorizontalPager from compose:foundation. but keep in mind that loading a lot of pages at once will affect your performance. sometimes a more reasonable approach is to react on size changes nicely, like with having animateContentSize modifier on Pager, or something like thisLukasz Kalnik
08/01/2025, 10:31 AMSubcomposeLayout and the regular, lazy HorizontalPager here, in case someone finds this thread:
fun OnboardingPager(onboardingCards: List<OnboardingCardState>) {
val pagerState = rememberPagerState(pageCount = { onboardingCards.size })
var maxCardHeight by remember { mutableStateOf(0.dp) }
val pagerContentPadding = 16.dp
// Measure the maximum height of all cards
SubcomposeLayout { constraints ->
val measuredHeights = onboardingCards.map { card ->
val placeables = subcompose(card) {
OnboardingCard(
onboardingCard = card,
modifier = Modifier.padding(horizontal = pagerContentPadding)
)
}.map { it.measure(constraints) }
placeables.maxOf { it.height.toDp() }
}
maxCardHeight = measuredHeights.maxOrNull() ?: 0.dp
layout(0, 0) {}
}
HorizontalPager(
state = pagerState,
pageSpacing = 16.dp,
verticalAlignment = Alignment.Top,
contentPadding = PaddingValues(horizontal = pagerContentPadding),
)
{ page ->
OnboardingCard(
onboardingCard = onboardingCards[page],
modifier = Modifier.height(maxCardHeight)
)
}
// ...Lukasz Kalnik
08/01/2025, 10:35 AMSubcomposeLayout just measures all the `OnboardingCard`s here, which are displayed in HorizontalPager.
It is important to pass the same constraints to the `OnboardingCard`s inside the SubcomposeLayout, that's why I pass the pagerContentPadding both to the card in the SubcomposeLayout and to the HorizontalPager itself.
Otherwise the card will assume it has more horizontal space and will cut off the content of the highest pages in the HorizontalPager.Lukasz Kalnik
08/01/2025, 10:36 AMSubcomposeLayout is executed during layout phase, after measuring and before placing items.
It doesn't draw anything on the screen. It's sole purpose is if you need to measure some Composables (e.g. here the OnboardingCard) to pass the result to some other Composable (here it is passed to the OnboardingCard inside the HorizontalPager in the Modifier.height(maxCardHeight)).Andrey Kulikov
08/01/2025, 10:50 AMLukasz Kalnik
08/01/2025, 10:50 AMLukasz Kalnik
08/01/2025, 10:51 AMitemsCount to beyondViewportPageCount didn't fix the problemLukasz Kalnik
08/01/2025, 10:51 AMLukasz Kalnik
08/01/2025, 10:51 AMHorizontalPager height doesn't changeLukasz Kalnik
08/01/2025, 10:52 AMLukasz Kalnik
08/01/2025, 10:53 AMModifier.height(Intrinsics.Max) to the pages, because they all will be composed eagerly then?Lukasz Kalnik
08/01/2025, 10:56 AMHorizontalPager(
// ...
beyondViewportPageCount = itemsCount
// ...
) { page ->
Page(Modifier.height(IntrinsicsSize.Max))
}Andrey Kulikov
08/01/2025, 10:57 AMLukasz Kalnik
08/01/2025, 10:58 AM