We just launched Compose Examples featuring over 150+ components! Check it out →

HorizontalUncontainedCarousel

Common

Component in Material 3 Compose

A horizontal carousel that displays its items with the given size except for one item at the end that is cut off.

Note that the item size will be bound by the size of the carousel. Otherwise, this carousel lays out as many items as it can in the given size, and changes the size of the last cut off item such that there is a range of motion when items scroll off the edge.

For more information, see design guidelines.

Last updated:

Installation

dependencies {
   implementation("androidx.compose.material3:material3:1.4.0-alpha02")
}

Overloads

@ExperimentalMaterial3Api
@Composable
fun HorizontalUncontainedCarousel(
    state: CarouselState,
    itemWidth: Dp,
    modifier: Modifier = Modifier,
    itemSpacing: Dp = 0.dp,
    flingBehavior: TargetedFlingBehavior = CarouselDefaults.noSnapFlingBehavior(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    content: @Composable CarouselItemScope.(itemIndex: Int) -> Unit
)

Parameters

namedescription
stateThe state object to be used to control the carousel's state
itemWidthThe width of items in the carousel
modifierA modifier instance to be applied to this carousel container
itemSpacingThe amount of space used to separate items in the carousel
flingBehaviorThe [TargetedFlingBehavior] to be used for post scroll gestures
contentPaddinga 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.
contentThe carousel's content Composable

Code Example

HorizontalUncontainedCarouselSample

@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun HorizontalUncontainedCarouselSample() {

    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),
        )
    HorizontalUncontainedCarousel(
        state = rememberCarouselState { items.count() },
        modifier = Modifier.width(412.dp).height(221.dp),
        itemWidth = 186.dp,
        itemSpacing = 8.dp,
        contentPadding = PaddingValues(horizontal = 16.dp)
    ) { i ->
        val item = items[i]
        Image(
            modifier = Modifier.height(205.dp).maskClip(MaterialTheme.shapes.extraLarge),
            painter = painterResource(id = item.imageResId),
            contentDescription = stringResource(item.contentDescriptionResId),
            contentScale = ContentScale.Crop
        )
    }
}
by @alexstyl