HorizontalMultiBrowseCarousel
Composable Component
A horizontal carousel meant to display many items at once for quick browsing of smaller content like album art or photo thumbnails.
Common
@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,
)
Parameters
state | The state object to be used to control the carousel's state |
preferredItemWidth | 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 | A modifier instance to be applied to this carousel container |
itemSpacing | The amount of space used to separate items in the carousel |
flingBehavior | The TargetedFlingBehavior to be used for post scroll gestures |
userScrollEnabled | whether the scrolling via the user gestures or accessibility actions is allowed. |
minSmallItemWidth | 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 | 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 | 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 | The carousel's content Composable |
Common
Deprecated Kept for binary compatibility
@ExperimentalMaterial3Api
@Composable
fun HorizontalMultiBrowseCarousel(
state: CarouselState,
preferredItemWidth: Dp,
modifier: Modifier = Modifier,
itemSpacing: Dp = 0.dp,
flingBehavior: TargetedFlingBehavior =
CarouselDefaults.singleAdvanceFlingBehavior(state = state),
minSmallItemWidth: Dp = CarouselDefaults.MinSmallItemSize,
maxSmallItemWidth: Dp = CarouselDefaults.MaxSmallItemSize,
contentPadding: PaddingValues = PaddingValues(0.dp),
content: @Composable CarouselItemScope.(itemIndex: Int) -> Unit,
) =
HorizontalMultiBrowseCarousel(
state = state,
preferredItemWidth = preferredItemWidth,
modifier = modifier,
itemSpacing = itemSpacing,
flingBehavior = flingBehavior,
userScrollEnabled = true,
minSmallItemWidth = minSmallItemWidth,
maxSmallItemWidth = maxSmallItemWidth,
contentPadding = contentPadding,
content = content,
)
Code Examples
HorizontalMultiBrowseCarouselSample
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun HorizontalMultiBrowseCarouselSample() {
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,
)
}
}
CarouselWithShowAllButtonSample
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun CarouselWithShowAllButtonSample() {
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),
)
) {}
}
}
}
}