Băng chuyền hiển thị một danh sách các mục có thể cuộn, tự động điều chỉnh dựa trên kích thước cửa sổ. Sử dụng băng chuyền để giới thiệu một bộ sưu tập nội dung có liên quan. Các mục trong băng chuyền nhấn mạnh hình ảnh, nhưng cũng có thể chứa văn bản ngắn thích ứng với kích thước của mục.
Có 4 bố cục băng chuyền phù hợp với nhiều trường hợp sử dụng:
- Nhiều kích thước: Bao gồm các mặt hàng có nhiều kích thước. Nên dùng để duyệt qua nhiều mục cùng lúc, chẳng hạn như ảnh.
- Uncontained (Không có vùng chứa): Chứa các mục có một kích thước và trôi qua cạnh của màn hình. Bạn có thể tuỳ chỉnh để hiện thêm văn bản hoặc giao diện người dùng khác ở phía trên hoặc phía dưới mỗi mục.
- Hero: Làm nổi bật một hình ảnh lớn để tập trung vào và cung cấp thông tin sơ lược về nội dung tiếp theo bằng một mục nhỏ. Nên dùng để làm nổi bật nội dung mà bạn muốn nhấn mạnh, chẳng hạn như hình thu nhỏ của phim hoặc chương trình.
- Toàn màn hình: Hiển thị từng mục lớn tràn viền tại một thời điểm và cuộn theo chiều dọc. Phù hợp với nội dung có chiều cao lớn hơn chiều rộng.

Trang này hướng dẫn bạn cách triển khai bố cục băng chuyền không có vùng chứa và duyệt qua nhiều nội dung. Hãy xem Nguyên tắc về băng chuyền Material 3 để biết thêm thông tin về các loại bố cục.
Nền tảng API
Để triển khai băng chuyền có nhiều chế độ duyệt và không có vùng chứa, hãy sử dụng các thành phần kết hợp HorizontalMultiBrowseCarousel
và HorizontalUncontainedCarousel
. Các thành phần kết hợp này có những tham số chính sau:
state
: Một thực thểCarouselState
quản lý chỉ mục mục hiện tại và vị trí cuộn. Tạo trạng thái này bằng cách sử dụngrememberCarouselState { itemCount }
, trong đóitemCount
là tổng số mục trong băng chuyền.itemSpacing
: Xác định khoảng trống giữa các mục liền kề trong băng chuyền.contentPadding
: Áp dụng khoảng đệm xung quanh vùng nội dung của băng chuyền. Sử dụng thuộc tính này để thêm khoảng cách trước mục đầu tiên hoặc sau mục cuối cùng, hoặc để cung cấp lề cho các mục trong vùng có thể di chuyển.content
: Một hàm có khả năng kết hợp nhận được một chỉ mục số nguyên. Sử dụng lambda này để xác định giao diện người dùng cho từng mục trong băng chuyền dựa trên chỉ mục của mục đó.
Các thành phần kết hợp này khác nhau ở cách chúng chỉ định kích thước của mục:
itemWidth
(đối vớiHorizontalUncontainedCarousel
): Chỉ định chiều rộng chính xác cho từng mục trong băng chuyền không có vùng chứa.preferredItemWidth
(choHorizontalMultiBrowseCarousel
): Đề xuất chiều rộng lý tưởng cho các mục trong băng chuyền duyệt qua nhiều nội dung, cho phép thành phần hiển thị nhiều mục nếu có đủ không gian.
Ví dụ: Băng chuyền duyệt qua nhiều nội dung
Đoạn mã này triển khai một băng chuyền duyệt qua nhiều nội dung:
@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 ) } }
Các điểm chính về mã
- Xác định một lớp dữ liệu
CarouselItem
, giúp cấu trúc dữ liệu cho từng phần tử trong băng chuyền. - Tạo và ghi nhớ một
List
gồm các đối tượngCarouselItem
được điền sẵn bằng các tài nguyên và nội dung mô tả hình ảnh. - Sử dụng thành phần kết hợp
HorizontalMultiBrowseCarousel
, được thiết kế để hiển thị nhiều mục trong một băng chuyền.- Trạng thái của băng chuyền được khởi chạy bằng
rememberCarouselState
, được cung cấp tổng số mục. - Các mục có
preferredItemWidth
(ở đây là186.dp
), cho biết chiều rộng tối ưu cho từng mục. Băng chuyền sử dụng thông tin này để xác định số lượng mục có thể vừa với màn hình cùng một lúc. - Tham số
itemSpacing
sẽ thêm một khoảng trống nhỏ giữa các mục. - Lambda theo sau của
HorizontalMultiBrowseCarousel
sẽ lặp lại thông quaCarouselItems
. Trong mỗi lần lặp, hàm này sẽ truy xuất mục tại chỉ mụci
và hiển thị một thành phần kết hợpImage
cho mục đó. Modifier.maskClip(MaterialTheme.shapes.extraLarge)
áp dụng một mặt nạ hình dạng xác định trước cho từng hình ảnh, giúp hình ảnh có các góc bo tròn.contentDescription
cung cấp nội dung mô tả hỗ trợ tiếp cận cho hình ảnh.
- Trạng thái của băng chuyền được khởi chạy bằng
Kết quả
Hình ảnh sau đây cho thấy kết quả từ đoạn mã trước:

Ví dụ: Băng chuyền không có vùng chứa
Đoạn mã sau đây triển khai một băng chuyền không có vùng chứa:
@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 ) } }
Các điểm chính về mã
- Thành phần kết hợp
HorizontalUncontainedCarousel
tạo bố cục băng chuyền.- Tham số
itemWidth
đặt chiều rộng cố định cho từng mục trong băng chuyền.
- Tham số
Kết quả
Hình ảnh sau đây cho thấy kết quả từ đoạn mã trước:
