Swipeable là một API Material của Compose giúp bạn tạo các thành phần có thể vuốt giữa các trạng thái riêng biệt, chẳng hạn như trang tính dưới cùng, ngăn kéo hoặc thao tác vuốt để đóng. Để hỗ trợ tốt hơn các trường hợp sử dụng nâng cao, chẳng hạn như các neo phụ thuộc vào kích thước của một thành phần, một thành phần kế thừa đã được xuất bản trong Compose-Foundation 1.6.0-alpha01: AnchoredDraggable. AnchoredDraggable là một API Foundation để tạo các thành phần có thể kéo với trạng thái được liên kết, chẳng hạn như trang tính dưới cùng, ngăn kéo hoặc thao tác vuốt để đóng.
Các API Swipeable của Material đã ngừng hoạt động để chuyển sang dùng AnchoredDraggable của Foundation và sẽ bị xoá trong bản phát hành sau này. Hướng dẫn này mô tả cách di chuyển từ API Swipeable sang AnchoredDraggable.
Di chuyển SwipeableState sang AnchoredDraggableState
Bắt đầu bằng cách xác định những thay đổi đối với phần tử giữ trạng thái của bạn. AnchoredDraggableState không thể được kế thừa và độ lệch được biểu thị dưới dạng Float.NaN trước khi được khởi tạo.
Cập nhật phần tử giữ trạng thái
AnchoredDraggableState là một lớp cuối cùng, tức là bạn không thể kế thừa từ lớp này. Nếu thành phần hiện có của bạn kế thừa từ SwipeableState, hãy cập nhật phần tử giữ trạng thái để giữ một tham chiếu đến AnchoredDraggableState thay vì kế thừa từ phần tử giữ trạng thái đó:
Có thể vuốt
class MySwitchState: SwipeableState()
AnchoredDraggable
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
Vì phần giữ trạng thái của bạn không còn kế thừa từ SwipeableState nữa, nên có thể bạn phải tự hiển thị các API. Các API phổ biến nhất mà bạn có thể sử dụng là offset, progress, currentValue và targetValue.
Truy cập vào độ lệch
Không giống như trong Swipeable, offset của AnchoredDraggableState là Float.NaN trước khi được khởi tạo. Trong AnchoredDraggable, bạn có thể truyền các điểm neo đến hàm khởi tạo của AnchoredDraggableState hoặc cập nhật thông qua AnchoredDraggableState#updateAnchors. Việc truyền các neo đến hàm khởi tạo của AnchoredDraggableState sẽ khởi tạo độ lệch ngay lập tức.
Nếu các điểm neo của bạn phụ thuộc vào bố cục hoặc có thể thay đổi, hãy dùng AnchoredDraggableState#updateAnchors để tránh tạo lại trạng thái khi các điểm neo thay đổi.
Nếu bạn sử dụng updateAnchors, độ lệch sẽ là Float.NaN trước khi truyền các neo đến updateAnchors. Để tránh vô tình truyền Float.NaN đến các thành phần, hãy sử dụng AnchoredDraggableState#requireOffset để yêu cầu khởi chạy độ lệch khi đọc. Điều này giúp bạn phát hiện sớm những điểm không nhất quán hoặc các lỗi có thể xảy ra.
@Composable
fun AnchoredDraggableBox() {
val state = remember { AnchoredDraggableState(...) }
val density = LocalDensity.current
val anchors = remember { DraggableAnchors { ... } }
SideEffect {
state.updateAnchors(anchors)
}
Box(
Modifier.offset { IntOffset(x = state.requireOffset(), y = 0) }
}
}
Di chuyển Modifier.swipeable sang Modifier.anchoredDraggable
Modifier.anchoredDraggable() thay thế Modifier.swipeable. Một số tham số của Modifier.swipeable() đã được chuyển trực tiếp sang AnchoredDraggableState, như mô tả trong các phần sau.
Xác định điểm neo
Xác định các neo bằng phương thức trình tạo DraggableAnchors. Sau đó, hãy truyền các tham số này đến hàm khởi tạo của AnchoredDraggableState#updateAnchors hoặc AnchoredDraggableState:
Hàm dựng
enum class DragValue { Start, Center, End }
@Composable
fun AnchoredDraggableBox() {
val anchors = DraggableAnchors {
Start at -100.dp.toPx()
Center at 0f
End at 100.dp.toPx()
}
val state = remember {
AnchoredDraggableState(anchors = anchors)
}
Box(
Modifier.offset { IntOffset(x = state.requireOffset(), y = 0) }
)
}
updateAnchors
enum class DragValue { Start, Center, End }
@Composable
fun AnchoredDraggableBox() {
val state = remember { AnchoredDraggableState(...) }
val density = LocalDensity.current
val anchors = with (density) {
DraggableAnchors {
Start at -100.dp.toPx()
Center at 0f
End at 100.dp.toPx()
}
}
SideEffect {
state.updateAnchors(anchors)
}
Box(
Modifier.offset { IntOffset(x = state.requireOffset(), y = 0) }
)
}
Nếu các neo là tĩnh, hãy truyền chúng đến hàm khởi tạo. Nếu chúng phụ thuộc vào bố cục hoặc không phải là tĩnh, hãy sử dụng updateAnchors.
Xác định ngưỡng vị trí
Loại và tên của tham số ngưỡng đã thay đổi. Thay vì có một giao diện ThresholdConfig riêng biệt, AnchoredDraggableState có một tham số positionalThreshold lấy một hàm lambda trả về vị trí của ngưỡng. Ví dụ: ngưỡng vị trí là 50% có thể được biểu thị là:
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { distance -> distance * 0.5f },
...
)
Ngưỡng vị trí 56dp có thể được biểu thị là:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { with(density) { 56.dp.toPx() } },
...
)
Xác định ngưỡng vận tốc
Ngưỡng vận tốc cũng được truyền đến hàm khởi tạo của AnchoredDraggableState và cũng được biểu thị dưới dạng một lambda:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
velocityThreshold = { with(density) { 125.dp.toPx() } },
...
)
Các thay đổi đối với nền tảng API
Xem thông tin tổng quan về các thay đổi đối với giao diện API bên dưới.
AnchoredDraggableState
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
Không áp dụng |
|
|
|
|
|
|
|
|
|
|
|
Modifier.anchoredDraggable
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
Truyền đến hàm khởi tạo |
|
Chưa được hỗ trợ. Hãy xem b/288084801 để nắm được trạng thái mới nhất. |
|
Được truyền đến hàm khởi tạo |