HorizontalCenteredHeroCarousel

Functions summary

Unit
@Composable
HorizontalCenteredHeroCarousel(
    state: CarouselState,
    modifier: Modifier,
    preferredItemWidth: Dp,
    itemSpacing: Dp,
    flingBehavior: TargetedFlingBehavior,
    userScrollEnabled: Boolean,
    minSmallItemWidth: Dp,
    maxSmallItemWidth: Dp,
    contentPadding: PaddingValues,
    content: @Composable CarouselItemScope.(itemIndex: Int) -> Unit
)

Material Design center-aligned hero carousel

Cmn

Functions

HorizontalCenteredHeroCarousel

@Composable
fun HorizontalCenteredHeroCarousel(
    state: CarouselState,
    modifier: Modifier = Modifier,
    preferredItemWidth: Dp = Dp.Unspecified,
    itemSpacing: Dp = CarouselDefaults.ItemSpacing,
    flingBehavior: TargetedFlingBehavior = CarouselDefaults.singleAdvanceFlingBehavior(state = state),
    userScrollEnabled: Boolean = true,
    minSmallItemWidth: Dp = CarouselDefaults.MinSmallItemSize,
    maxSmallItemWidth: Dp = CarouselDefaults.MaxSmallItemSize,
    contentPadding: PaddingValues = CarouselDefaults.ContentPadding,
    content: @Composable CarouselItemScope.(itemIndex: Int) -> Unit
): Unit

Material Design center-aligned hero carousel

A horizontal carousel that centers at least one large item between two small items.

Note that this carousel lays out items using the large item size and clips (or masks) items depending on their scroll offset to create items which smoothly expand and collapse between the large and small sizes.

The selected item is centered whenever items sit on both sides of it. At the bounds of the list the arrangement shifts, so the first item aligns to the start of the viewport and the last item aligns to its end:

// Five items, one large item between two small items:
item 1 selected: [ 1 ][2][3]
item 3 selected: [2][ 3 ][4]
item 5 selected: [3][4][ 5 ]

Lists holding fewer items than the arrangement needs (three at a minimum) stay start-aligned.

Example of a center-aligned hero carousel:

import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.filled.Image
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.carousel.HorizontalCenteredHeroCarousel
import androidx.compose.material3.carousel.rememberCarouselState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp

data class CarouselItem(
    val id: Int,
    @DrawableRes val imageResId: Int,
    @StringRes val contentDescriptionResId: Int,
)

val items =
    listOf(
        CarouselItem(0, R.drawable.carousel_image_1, R.string.carousel_image_1_description),
        CarouselItem(1, R.drawable.carousel_image_2, R.string.carousel_image_2_description),
        CarouselItem(2, R.drawable.carousel_image_3, R.string.carousel_image_3_description),
        CarouselItem(3, R.drawable.carousel_image_4, R.string.carousel_image_4_description),
        CarouselItem(4, R.drawable.carousel_image_5, R.string.carousel_image_5_description),
    )
val state = rememberCarouselState { items.count() }
val animationScope = rememberCoroutineScope()
HorizontalCenteredHeroCarousel(
    state = state,
    modifier = Modifier.fillMaxWidth().height(221.dp).padding(horizontal = 24.dp),
    itemSpacing = 8.dp,
    contentPadding = PaddingValues(horizontal = 16.dp),
) { i ->
    val item = items[i]
    Image(
        modifier =
            Modifier.fillMaxWidth()
                .height(205.dp)
                .maskClip(MaterialTheme.shapes.extraLarge)
                .clickable(true, "Tap to focus", Role.Image) {
                    animationScope.launch { state.animateScrollToItem(i) }
                },
        painter = painterResource(id = item.imageResId),
        contentDescription = stringResource(item.contentDescriptionResId),
        contentScale = ContentScale.Crop,
    )
}
Parameters
state: CarouselState

The state object to be used to control the carousel's state

modifier: Modifier = Modifier

A modifier instance to be applied to this carousel container

preferredItemWidth: Dp = Dp.Unspecified

The width large items aim for in dp. Carousel picks the arrangement whose large item width lands closest to this value, resizing small items between minSmallItemWidth and maxSmallItemWidth to fill the rest of the viewport, so the final width can differ. The default Dp.Unspecified targets the whole viewport, fitting one large item beside two small items; smaller values fit more large items. Large items always end up wider than the small items beside them, which are never narrower than minSmallItemWidth, so widths at or below that bound cannot be honored. To target an aspect ratio, use the carousel's cross axis size * a multiplier (e.g. 220.dp * 2 for a 2:1 ratio).

itemSpacing: Dp = CarouselDefaults.ItemSpacing

The amount of space used to separate items in the carousel

flingBehavior: TargetedFlingBehavior = CarouselDefaults.singleAdvanceFlingBehavior(state = state)

The TargetedFlingBehavior to be used for post scroll gestures

userScrollEnabled: Boolean = true

whether the scrolling via the user gestures or accessibility actions is allowed.

minSmallItemWidth: Dp = CarouselDefaults.MinSmallItemSize

The minimum allowable width of small items in dp

maxSmallItemWidth: Dp = CarouselDefaults.MaxSmallItemSize

The maximum allowable width of small items in dp

contentPadding: PaddingValues = CarouselDefaults.ContentPadding

a padding around the whole content. This will add padding for the content after it has been clipped. You can use it to add a padding before the first item or after the last one. Use itemSpacing to add spacing between the items.

content: @Composable CarouselItemScope.(itemIndex: Int) -> Unit

The carousel's content Composable