androidx.compose.material3.carousel

Interfaces

CarouselItemDrawInfo

Interface to hold information about a Carousel item and its size.

Cmn
CarouselItemScope

Receiver scope for Carousel item content.

Cmn

Classes

CarouselState

The state that can be used to control all types of carousels.

Cmn

Objects

CarouselDefaults

Contains the default values used by Carousel.

Cmn

Top-level functions summary

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

Material Design Carousel

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

Material Design Carousel

Cmn
Unit
@ExperimentalMaterial3Api
@Composable
HorizontalUncontainedCarousel(
    state: CarouselState,
    itemWidth: Dp,
    modifier: Modifier,
    itemSpacing: Dp,
    flingBehavior: TargetedFlingBehavior,
    userScrollEnabled: Boolean,
    contentPadding: PaddingValues,
    content: @Composable CarouselItemScope.(itemIndex: Int) -> Unit
)

Material Design Carousel

Cmn
CarouselState

Creates a CarouselState that is remembered across compositions.

Cmn

Top-level functions

HorizontalCenteredHeroCarousel

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

Material Design Carousel

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

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

maxItemWidth: Dp = Dp.Unspecified

The max width a large item is allowed to be in dp. The default value of Dp.Unspecified allows one large item to grow to fill the entire viewport minus space for two surrounding small items. Values other than unspecified will add additional large items as space allows.

itemSpacing: Dp = 0.dp

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 = PaddingValues(0.dp)

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

HorizontalMultiBrowseCarousel

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

Material Design Carousel

A horizontal carousel meant to display many items at once for quick browsing of smaller content like album art or photo thumbnails.

Note that this carousel may adjust the size of items in order to ensure a mix of large, medium, and small items fit perfectly into the available space and are arranged in a visually pleasing way. Carousel then 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, medium, and small sizes.

For more information, see design guidelines

Example of a multi-browse carousel:

import androidx.annotation.DrawableRes import androidx.annotation.StringRes import androidx.compose.foundation.Image import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.material.icons.filled.Image import androidx.compose.material3.MaterialTheme import androidx.compose.material3.carousel.HorizontalMultiBrowseCarousel import androidx.compose.material3.carousel.rememberCarouselState import androidx.compose.runtime.remember 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.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),  ) HorizontalMultiBrowseCarousel(  state = rememberCarouselState { items.count() },  modifier = Modifier.fillMaxWidth().height(221.dp),  preferredItemWidth = 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,  ) }
import androidx.activity.compose.BackHandler import androidx.annotation.DrawableRes import androidx.annotation.StringRes import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.filled.Image import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.carousel.HorizontalMultiBrowseCarousel import androidx.compose.material3.carousel.rememberCarouselState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Shape import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource 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),  ) var showAllItems by remember { mutableStateOf(false) } BackHandler(enabled = showAllItems) { showAllItems = false } if (showAllItems) {  // Shows the grid page directly. For better user experience and navigation patterns,  // consider navigating to a dedicated screen  LazyVerticalGrid(  columns = GridCells.Fixed(2),  contentPadding = PaddingValues(16.dp),  verticalArrangement = Arrangement.spacedBy(8.dp),  horizontalArrangement = Arrangement.spacedBy(8.dp),  modifier = Modifier.fillMaxSize().padding(top = 8.dp),  ) {  items(items.size) { i ->  val item = items[i]  Image(  painter = painterResource(id = item.imageResId),  contentDescription = stringResource(item.contentDescriptionResId),  modifier = Modifier.height(205.dp).clip(MaterialTheme.shapes.extraLarge),  contentScale = ContentScale.Crop,  )  }  } } else {  Column(  modifier =  Modifier.fillMaxSize()  .verticalScroll(rememberScrollState())  .padding(vertical = 16.dp)  ) {  HorizontalMultiBrowseCarousel(  state = rememberCarouselState { items.count() },  modifier = Modifier.width(412.dp).height(221.dp),  preferredItemWidth = 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,  )  }  TextButton(  onClick = { showAllItems = true },  modifier =  Modifier.align(Alignment.End).padding(vertical = 4.dp, horizontal = 16.dp),  ) {  Text("Show all")  }  // An example of the content for the scrollable page  (0..4).forEach { index ->  Spacer(modifier = Modifier.height(16.dp))  Box(  modifier =  Modifier.fillMaxWidth()  .height(140.dp)  .padding(horizontal = 16.dp)  .background(  MaterialTheme.colorScheme.surfaceVariant,  RoundedCornerShape(16.dp),  )  ) {}  }  } }
Parameters
state: CarouselState

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

preferredItemWidth: Dp

The width that large, fully visible items would like to be in the horizontal axis. This width is a target and will likely be adjusted by carousel in order to fit a whole number of items within the container. Carousel adjusts small items first (between the minSmallItemWidth and maxSmallItemWidth) then medium items when present, and finally large items if necessary.

modifier: Modifier = Modifier

A modifier instance to be applied to this carousel container

itemSpacing: Dp = 0.dp

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. Depending on the preferredItemWidth and the width of the carousel, the small item width will be chosen from a range of minSmallItemWidth and maxSmallItemWidth

maxSmallItemWidth: Dp = CarouselDefaults.MaxSmallItemSize

The maximum allowable width of small items in dp. Depending on the preferredItemWidth and the width of the carousel, the small item width will be chosen from a range of minSmallItemWidth and maxSmallItemWidth

contentPadding: PaddingValues = PaddingValues(0.dp)

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

HorizontalUncontainedCarousel

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

Material Design Carousel

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

Example of an uncontained carousel:

import androidx.annotation.DrawableRes import androidx.annotation.StringRes import androidx.compose.foundation.Image import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.width import androidx.compose.material.icons.filled.Image import androidx.compose.material3.MaterialTheme import androidx.compose.material3.carousel.HorizontalUncontainedCarousel import androidx.compose.material3.carousel.rememberCarouselState import androidx.compose.runtime.remember 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.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),  ) 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,  ) }
Parameters
state: CarouselState

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

itemWidth: Dp

The width of items in the carousel

modifier: Modifier = Modifier

A modifier instance to be applied to this carousel container

itemSpacing: Dp = 0.dp

The amount of space used to separate items in the carousel

flingBehavior: TargetedFlingBehavior = CarouselDefaults.noSnapFlingBehavior()

The TargetedFlingBehavior to be used for post scroll gestures

userScrollEnabled: Boolean = true

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

contentPadding: PaddingValues = PaddingValues(0.dp)

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

rememberCarouselState

@ExperimentalMaterial3Api
@Composable
fun rememberCarouselState(initialItem: Int = 0, itemCount: () -> Int): CarouselState

Creates a CarouselState that is remembered across compositions.

Parameters
initialItem: Int = 0

The initial item that should be scrolled to.

itemCount: () -> Int

The number of items this Carousel will have.