Swipeable
là một Compose Material API 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ư bảng dưới cùng, ngăn hoặc vuốt để đóng. Để hỗ trợ tốt hơn cho 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 phát hành trong Compose-Foundation 1.6.0-alpha01: AnchoredDraggable
. AnchoredDraggable
là một API nền tảng để tạo các thành phần có thể kéo với trạng thái cố định, chẳng hạn như bảng dưới cùng, ngăn hoặc vuốt để đóng.
Ngừng sử dụng các API Swipeable
của Material và thay vào đó là AnchoredDraggable
của nền tảng. Các API này sẽ bị xoá trong một bản phát hành sau này. Hướng dẫn này mô tả cách di chuyển từ các API Swipeable
sang AnchoredDraggable
.
Di chuyển SwipeableState
sang AnchoredDraggableState
Bắt đầu bằng cách xác định các thay đổi đối với phần tử giữ trạng thái. AnchoredDraggableState
không thể được kế thừa từ 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à lớp cuối cùng, nghĩa là không thể kế thừa 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ữ lại thông tin tham chiếu đến AnchoredDraggableState
thay vì kế thừa từ thành phần đó:
Có thể vuốt
class MySwitchState: SwipeableState()
Có thể kéo cố định
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
Vì phần tử giữ trạng thái không 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 khoản bù trừ
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 liên kết đế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 động độ lệch ngay lập tức.
Nếu các neo của bạn phụ thuộc vào bố cục hoặc có thể thay đổi, hãy sử dụng AnchoredDraggableState#updateAnchors
để tránh tạo lại trạng thái khi các 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 động phần bù trừ khi đọc. Việc này giúp bạn phát hiện các điểm không nhất quán hoặc lỗi có thể xảy ra ngay từ đầu.
@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()
đã chuyển trực tiếp sang AnchoredDraggableState
, như mô tả trong các phần sau.
Xác định neo
Xác định neo bằng phương thức tạo DraggableAnchors
. Sau đó, hãy truyền các hàm đó đế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) }
)
}
cập nhật neo
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 ở dạng tĩnh, hãy truyền các neo đó đến hàm khởi tạo. Nếu các giá trị này phụ thuộc vào bố cục hoặc không ở dạng tĩnh, hãy sử dụng updateAnchors
.
Xác định ngưỡng vị trí
Loại và tên của thông số ngưỡng đã thay đổi. Thay vì có giao diện ThresholdConfig
riêng biệt, AnchoredDraggableState
có tham số positionalThreshold
nhận 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ị như sau:
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { distance -> distance * 0.5f },
...
)
Ngưỡng vị trí của 56dp
có thể được biểu thị như sau:
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 lambda:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
velocityThreshold = { with(density) { 125.dp.toPx() } },
...
)
Thay đổi đối với nền tảng API
Xem thông tin tổng quan về những thay đổi đối với nền tảng 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 để biết trạng thái mới nhất. |
|
Đã truyền đến hàm khởi tạo |