Đối tượng sửa đổi verticalScroll và horizontalScroll cung cấp cách đơn giản nhất để người dùng cuộn một phần tử khi nội dung của phần tử đó lớn hơn giới hạn kích thước tối đa. Với phương thức sửa đổi verticalScroll và horizontalScroll, bạn không cần dịch hoặc bù trừ phần nội dung.
@Composable private fun ScrollBoxes() { Column( modifier = Modifier .background(Color.LightGray) .size(100.dp) .verticalScroll(rememberScrollState()) ) { repeat(10) { Text("Item $it", modifier = Modifier.padding(2.dp)) } } }
ScrollState cho phép bạn thay đổi vị trí thanh cuộn hoặc xem trạng thái hiện tại của vị trí thanh cuộn. Để tạo lớp này với các tham số mặc định, hãy sử dụng rememberScrollState().
@Composable private fun ScrollBoxesSmooth() { // Smoothly scroll 100px on first composition val state = rememberScrollState() LaunchedEffect(Unit) { state.animateScrollTo(100) } Column( modifier = Modifier .background(Color.LightGray) .size(100.dp) .padding(horizontal = 8.dp) .verticalScroll(state) ) { repeat(10) { Text("Item $it", modifier = Modifier.padding(2.dp)) } } }
Đối tượng sửa đổi cho vùng có thể cuộn
Đối tượng sửa đổi scrollableArea là một thành phần cơ bản để tạo vùng chứa có thể cuộn tuỳ chỉnh. Thành phần này cung cấp một lớp trừu tượng cấp cao hơn đối với đối tượng sửa đổi scrollable, xử lý các yêu cầu phổ biến như diễn giải delta cử chỉ, cắt nội dung và hiệu ứng cuộn quá mức.
Mặc dù scrollableArea được dùng cho các phương thức triển khai tuỳ chỉnh, nhưng nhìn chung, bạn nên ưu tiên các giải pháp có sẵn như verticalScroll, horizontalScroll hoặc các thành phần kết hợp như LazyColumn cho danh sách cuộn chuẩn. Các thành phần cấp cao hơn này đơn giản hơn cho các trường hợp sử dụng phổ biến và được xây dựng bằng cách sử dụng scrollableArea.
Sự khác biệt giữa đối tượng sửa đổi scrollableArea và scrollable
Sự khác biệt chính giữa scrollableArea và scrollable nằm ở cách các thành phần này diễn giải cử chỉ cuộn của người dùng:
scrollable(delta thô): Delta phản ánh trực tiếp chuyển động vật lý của hoạt động đầu vào của người dùng (ví dụ: kéo con trỏ) trên màn hình.scrollableArea(delta hướng nội dung):deltađược đảo ngược về mặt ngữ nghĩa để thể hiện thay đổi đã chọn ở vị trí cuộn, giúp nội dung có vẻ như di chuyển theo cử chỉ của người dùng, thường ngược với chuyển động của con trỏ.
Hãy nghĩ theo cách này: scrollable cho bạn biết cách con trỏ di chuyển, trong khi scrollableArea chuyển đổi chuyển động của con trỏ đó thành cách nội dung sẽ di chuyển trong một khung hiển thị có thể cuộn thông thường. Sự đảo ngược này là lý do khiến scrollableArea có cảm giác tự nhiên hơn khi triển khai vùng chứa có thể cuộn tiêu chuẩn.
Bảng sau đây tóm tắt các dấu hiệu delta cho các trường hợp phổ biến:
Cử chỉ của người dùng |
delta được |
mức chênh lệch do |
|---|---|---|
Con trỏ di chuyển LÊN |
Negative |
Tích cực |
Con trỏ di chuyển XUỐNG |
Tích cực |
Negative |
Con trỏ di chuyển sang TRÁI |
Negative |
Dương (Âm đối với RTL) |
Con trỏ di chuyển sang PHẢI |
Tích cực |
Âm (Dương đối với RTL) |
(*) Lưu ý về scrollableArea dấu delta: Dấu delta từ scrollableArea không chỉ là một phép đảo ngược đơn giản. Công cụ này xem xét một cách thông minh:
- Hướng: Dọc hoặc ngang.
LayoutDirection: LTR hoặc RTL (đặc biệt quan trọng đối với thao tác cuộn ngang).- Cờ
reverseScrolling: Cho biết hướng cuộn có bị đảo ngược hay không.
Ngoài việc đảo ngược delta cuộn, scrollableArea cũng cắt bớt nội dung theo ranh giới của bố cục và xử lý việc kết xuất hiệu ứng cuộn quá mức. Theo mặc định, hàm này sử dụng hiệu ứng do LocalOverscrollFactory cung cấp.
Bạn có thể tuỳ chỉnh hoặc tắt tính năng này bằng cách sử dụng phương thức nạp chồng scrollableArea chấp nhận tham số OverscrollEffect.
Trường hợp sử dụng đối tượng sửa đổi scrollableArea
Bạn nên sử dụng đối tượng sửa đổi scrollableArea khi cần tạo một thành phần cuộn tuỳ chỉnh mà các đối tượng sửa đổi horizontalScroll hoặc verticalScroll hoặc bố cục Lazy không đáp ứng được. Điều này thường liên quan đến các trường hợp có:
- Logic bố cục tuỳ chỉnh: Khi cách sắp xếp các mục thay đổi linh động dựa trên vị trí cuộn.
- Hiệu ứng hình ảnh độc đáo: Áp dụng các phép biến đổi, điều chỉnh tỷ lệ hoặc các hiệu ứng khác cho các thành phần con khi chúng cuộn.
- Kiểm soát trực tiếp: Cần kiểm soát chi tiết cơ chế cuộn ngoài những gì
verticalScrollhoặc bố cục Lazy hiển thị.
Tạo danh sách tuỳ chỉnh giống như bánh xe bằng scrollableArea
Mẫu sau đây minh hoạ cách sử dụng scrollableArea để tạo danh sách dọc tuỳ chỉnh, trong đó các mục thu nhỏ khi di chuyển ra xa trung tâm, tạo hiệu ứng hình ảnh "giống như bánh xe". Kiểu biến đổi phụ thuộc vào thao tác cuộn này là một trường hợp sử dụng hoàn hảo cho scrollableArea.
scrollableArea.
@Composable private fun ScrollableAreaSample() { // ... Layout( modifier = Modifier .size(150.dp) .scrollableArea(scrollState, Orientation.Vertical) .background(Color.LightGray), // ... ) { measurables, constraints -> // ... // Update the maximum scroll value to not scroll beyond limits and stop when scroll // reaches the end. scrollState.maxValue = (totalHeight - viewportHeight).coerceAtLeast(0) // Position the children within the layout. layout(constraints.maxWidth, viewportHeight) { // The current vertical scroll position, in pixels. val scrollY = scrollState.value val viewportCenterY = scrollY + viewportHeight / 2 var placeableLayoutPositionY = 0 placeables.forEach { placeable -> // This sample applies a scaling effect to items based on their distance // from the center, creating a wheel-like effect. // ... // Place the item horizontally centered with a layer transformation for // scaling to achieve wheel-like effect. placeable.placeRelativeWithLayer( x = constraints.maxWidth / 2 - placeable.width / 2, // Offset y by the scroll position to make placeable visible in the viewport. y = placeableLayoutPositionY - scrollY, ) { scaleX = scaleFactor scaleY = scaleFactor } // Move to the next item's vertical position. placeableLayoutPositionY += placeable.height } } } } // ...
Đối tượng sửa đổi cho các mục cuộn được (scrollable)
Đối tượng sửa đổi scrollable khác với đối tượng sửa đổi thao tác cuộn ở chỗ scrollable phát hiện các cử chỉ cuộn và ghi lại các delta, nhưng không tự động bù trừ phần nội dung. Thay vào đó, việc này được uỷ quyền cho người dùng thông qua
ScrollableState
, cần thiết để đối tượng sửa đổi này hoạt động chính xác.
Khi xây dựng ScrollableState, bạn phải cung cấp một hàm consumeScrollDelta, hàm này sẽ được gọi trong mỗi bước cuộn (thông qua cử chỉ nhập, cuộn hoặc hất nhẹ) với delta được tính bằng pixel. Hàm này phải trả về khoảng cách đã cuộn để đảm bảo truyền sự kiện đúng cách trong trường hợp có các phần tử lồng nhau có đối tượng sửa đổi scrollable.
Đoạn mã sau đây phát hiện các cử chỉ và cho thấy một giá trị dạng số cho một phần bù trừ, nhưng không bù trừ phần tử nào:
@Composable private fun ScrollableSample() { // actual composable state var offset by remember { mutableFloatStateOf(0f) } Box( Modifier .size(150.dp) .scrollable( orientation = Orientation.Vertical, // Scrollable state: describes how to consume // scrolling delta and update offset state = rememberScrollableState { delta -> offset += delta delta } ) .background(Color.LightGray), contentAlignment = Alignment.Center ) { Text(offset.toString()) } }
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Tìm hiểu về cử chỉ
- Di chuyển
CoordinatorLayoutsang Compose - Sử dụng Thành phần hiển thị trong Compose