캐러셀은 창 크기에 따라 동적으로 조정되는 스크롤 가능한 항목 목록을 표시합니다. 캐러셀을 사용하여 관련 콘텐츠 모음을 표시합니다. 캐러셀 항목은 시각적 요소를 강조하지만 항목 크기에 맞게 조정되는 간단한 텍스트를 포함할 수도 있습니다.
다양한 사용 사례에 적합한 네 가지 캐러셀 레이아웃이 있습니다.
- 다중 탐색: 크기가 다른 항목을 포함합니다. 사진과 같이 한 번에 여러 항목을 탐색하는 데 권장됩니다.
- Uncontained: 크기가 하나인 항목을 포함하며 화면 가장자리를 지나 흐릅니다. 각 항목 위 또는 아래에 더 많은 텍스트나 다른 UI를 표시하도록 맞춤설정할 수 있습니다.
- 히어로: 하나의 큰 이미지를 강조하여 집중하고 작은 항목으로 다음 항목을 미리 보여줍니다. 영화 또는 TV 프로그램 썸네일과 같이 강조하려는 콘텐츠를 집중 조명하는 데 권장됩니다.
- 전체 화면: 한 번에 하나의 큰 항목을 화면 전체에 표시하고 세로로 스크롤합니다. 너비보다 높이가 더 긴 콘텐츠에 권장됩니다.
이 페이지에서는 멀티 탐색 및 포함되지 않은 캐러셀 레이아웃을 구현하는 방법을 보여줍니다. 레이아웃 유형에 관한 자세한 내용은 캐러셀 Material 3 가이드라인을 참고하세요.
API 노출 영역
멀티 탐색 및 비포함 캐러셀을 구현하려면 HorizontalMultiBrowseCarousel 및 HorizontalUncontainedCarousel 컴포저블을 사용하세요. 이러한 컴포저블은 다음 주요 매개변수를 공유합니다.
state: 현재 항목 색인과 스크롤 위치를 관리하는CarouselState인스턴스입니다.rememberCarouselState { itemCount }를 사용하여 이 상태를 만듭니다. 여기서itemCount은 캐러셀의 총 항목 수입니다.itemSpacing: 캐러셀에서 인접한 항목 사이의 빈 공간 크기를 정의합니다.contentPadding: 캐러셀의 콘텐츠 영역 주위에 패딩을 적용합니다. 이를 사용하여 첫 번째 항목 앞이나 마지막 항목 뒤에 공백을 추가하거나 스크롤 가능한 영역 내의 항목에 여백을 제공합니다.content: 정수 색인을 수신하는 컴포저블 함수입니다. 이 람다를 사용하여 색인을 기반으로 캐러셀의 각 항목에 대한 UI를 정의합니다.
이러한 컴포저블은 항목 크기를 지정하는 방식이 다릅니다.
itemWidth(HorizontalUncontainedCarousel의 경우): 컨테이너가 없는 캐러셀의 각 항목에 대한 정확한 너비를 지정합니다.preferredItemWidth(HorizontalMultiBrowseCarousel의 경우): 멀티 탐색 캐러셀의 항목에 이상적인 너비를 제안하여 공간이 허용하는 경우 구성요소가 여러 항목을 표시할 수 있도록 합니다.
예: 멀티 브라우즈 캐러셀
이 스니펫은 멀티 탐색 캐러셀을 구현합니다.
@Composable fun CarouselExample_MultiBrowse() { data class CarouselItem( val id: Int, @DrawableRes val imageResId: Int, val contentDescription: String ) val items = remember { listOf( CarouselItem(0, R.drawable.cupcake, "cupcake"), CarouselItem(1, R.drawable.donut, "donut"), CarouselItem(2, R.drawable.eclair, "eclair"), CarouselItem(3, R.drawable.froyo, "froyo"), CarouselItem(4, R.drawable.gingerbread, "gingerbread"), ) } HorizontalMultiBrowseCarousel( state = rememberCarouselState { items.count() }, modifier = Modifier .fillMaxWidth() .wrapContentHeight() .padding(top = 16.dp, bottom = 16.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 = item.contentDescription, contentScale = ContentScale.Crop ) } }
코드에 관한 핵심 사항
- 캐러셀의 각 요소에 대한 데이터를 구조화하는
CarouselItem데이터 클래스를 정의합니다. - 이미지 리소스와 설명으로 채워진
CarouselItem객체의List를 만들고 기억합니다. - 캐러셀에 여러 항목을 표시하도록 설계된
HorizontalMultiBrowseCarousel컴포저블을 사용합니다.- 캐러셀의 상태는
rememberCarouselState를 사용하여 초기화되며, 이 상태에는 총 항목 수가 제공됩니다. - 항목에는 각 항목의 최적 너비를 제안하는
preferredItemWidth(여기서는186.dp)가 있습니다. 캐러셀은 이를 사용하여 한 번에 화면에 표시할 수 있는 항목 수를 결정합니다. itemSpacing매개변수는 항목 사이에 작은 간격을 추가합니다.HorizontalMultiBrowseCarousel의 후행 람다는CarouselItems를 반복합니다. 각 반복에서 색인i의 항목을 가져와Image컴포저블을 렌더링합니다.Modifier.maskClip(MaterialTheme.shapes.extraLarge)는 각 이미지에 사전 정의된 도형 마스크를 적용하여 모서리를 둥글게 만듭니다.contentDescription는 이미지에 대한 접근성 설명을 제공합니다.
- 캐러셀의 상태는
결과
다음 이미지는 이전 스니펫의 결과를 보여줍니다.
예: 포함되지 않은 캐러셀
다음 스니펫은 포함되지 않은 캐러셀을 구현합니다.
@Composable fun CarouselExample() { data class CarouselItem( val id: Int, @DrawableRes val imageResId: Int, val contentDescription: String ) val carouselItems = remember { listOf( CarouselItem(0, R.drawable.cupcake, "cupcake"), CarouselItem(1, R.drawable.donut, "donut"), CarouselItem(2, R.drawable.eclair, "eclair"), CarouselItem(3, R.drawable.froyo, "froyo"), CarouselItem(4, R.drawable.gingerbread, "gingerbread"), ) } HorizontalUncontainedCarousel( state = rememberCarouselState { carouselItems.count() }, modifier = Modifier .fillMaxWidth() .wrapContentHeight() .padding(top = 16.dp, bottom = 16.dp), itemWidth = 186.dp, itemSpacing = 8.dp, contentPadding = PaddingValues(horizontal = 16.dp) ) { i -> val item = carouselItems[i] Image( modifier = Modifier .height(205.dp) .maskClip(MaterialTheme.shapes.extraLarge), painter = painterResource(id = item.imageResId), contentDescription = item.contentDescription, contentScale = ContentScale.Crop ) } }
코드에 관한 핵심 사항
HorizontalUncontainedCarousel컴포저블은 캐러셀 레이아웃을 만듭니다.itemWidth매개변수는 캐러셀의 각 항목에 고정 너비를 설정합니다.
결과
다음 이미지는 이전 스니펫의 결과를 보여줍니다.
