Swipeable คือ Compose Material API ที่ช่วยคุณสร้างคอมโพเนนต์ที่สามารถปัดระหว่างสถานะที่ไม่ต่อเนื่อง เช่น Bottom Sheet ลิ้นชัก หรือปัดเพื่อปิด เราได้เผยแพร่ฟังก์ชันที่มาแทนใน Compose-Foundation 1.6.0-alpha01 ซึ่งก็คือ AnchoredDraggable เพื่อรองรับกรณีการใช้งานขั้นสูงได้ดียิ่งขึ้น เช่น แองเคอร์ที่
ขึ้นอยู่กับขนาดของคอมโพเนนต์ AnchoredDraggable
เป็น Foundation API สำหรับสร้างคอมโพเนนต์ที่ลากได้โดยมีสถานะที่ยึดไว้ เช่น
ชีตด้านล่าง ลิ้นชัก หรือการปัดเพื่อปิด
เราเลิกใช้งาน API ของ Swipeable ของ Material แล้วเพื่อเปลี่ยนไปใช้ AnchoredDraggable ของ Foundation
และจะนำออกในรุ่นต่อๆ ไป คู่มือนี้
อธิบายวิธีย้ายข้อมูลจาก Swipeable API ไปยัง AnchoredDraggable
ย้ายข้อมูล SwipeableState ไปยัง AnchoredDraggableState
เริ่มจากการระบุการเปลี่ยนแปลงในตัวเก็บสถานะ AnchoredDraggableState
จะรับค่ามาจากที่อื่นไม่ได้ และออฟเซ็ตจะแสดงเป็น Float.NaN ก่อนที่จะ
เริ่มต้น
อัปเดตตัวเก็บสถานะของคุณ
AnchoredDraggableState เป็นคลาสสุดท้าย ซึ่งหมายความว่าคลาสนี้จะรับค่าจากคลาสอื่นไม่ได้ หากคอมโพเนนต์ที่มีอยู่สืบทอดมาจาก SwipeableState ให้อัปเดตตัวเก็บสถานะเพื่อเก็บการอ้างอิงถึง AnchoredDraggableState แทนที่จะสืบทอดมาจาก AnchoredDraggableState
ปัดได้
class MySwitchState: SwipeableState()
AnchoredDraggable
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
เนื่องจากตัวเก็บสถานะของคุณไม่ได้สืบทอดจาก SwipeableState อีกต่อไป คุณอาจต้องเปิดเผย API ด้วยตนเอง API ที่ใช้กันมากที่สุดที่คุณใช้ได้คือ offset, progress, currentValue และ targetValue
เข้าถึงออฟเซ็ต
AnchoredDraggableState ของ AnchoredDraggableState จะเป็น Float.NaN ก่อน
ที่จะเริ่มต้นใช้งาน ซึ่งแตกต่างจากใน Swipeableoffset ใน AnchoredDraggable คุณสามารถส่งแองเคอร์ไปยัง
เครื่องมือสร้างของ AnchoredDraggableState หรืออัปเดตผ่าน
AnchoredDraggableState#updateAnchors ได้ การส่งผ่าน Anchor ไปยัง
AnchoredDraggableStateตัวสร้างจะเริ่มต้นออฟเซ็ตทันที
หาก Anchor ขึ้นอยู่กับเลย์เอาต์หรืออาจเปลี่ยนแปลง ให้ใช้
AnchoredDraggableState#updateAnchors เพื่อหลีกเลี่ยงการสร้างสถานะใหม่เมื่อ
Anchor เปลี่ยนแปลง
หากคุณใช้ updateAnchors ออฟเซ็ตจะเป็น Float.NaN ก่อนส่งผ่าน Anchor ไปยัง updateAnchors หากต้องการหลีกเลี่ยงการส่ง Float.NaN ไปยัง คอมโพเนนต์โดยไม่ตั้งใจ ให้ใช้ AnchoredDraggableState#requireOffset เพื่อกำหนดว่าต้องมีการเริ่มต้นออฟเซ็ตเมื่ออ่าน ซึ่งจะช่วยให้คุณพบความไม่สอดคล้องกันหรือข้อบกพร่องที่อาจเกิดขึ้นได้ตั้งแต่เนิ่นๆ
@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) }
}
}
ย้ายข้อมูล Modifier.swipeable ไปยัง Modifier.anchoredDraggable
Modifier.anchoredDraggable() แทนที่ Modifier.swipeable พารามิเตอร์บางรายการของ Modifier.swipeable() ได้ย้ายไปที่ AnchoredDraggableState โดยตรงตามที่อธิบายไว้ในส่วนต่อไปนี้
กำหนด Anchor
กำหนด Anchor โดยใช้เมธอดตัวสร้าง DraggableAnchors จากนั้นส่ง
ไปยังเครื่องมือสร้างของ AnchoredDraggableState#updateAnchors หรือ AnchoredDraggableState
เครื่องมือสร้าง
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) }
)
}
หากจุดยึดเป็นแบบคงที่ ให้ส่งไปยังตัวสร้าง หากขึ้นอยู่กับเลย์เอาต์หรือไม่ได้เป็นแบบคงที่ ให้ใช้ updateAnchors
กำหนดเกณฑ์ตำแหน่ง
ประเภทและชื่อของพารามิเตอร์เกณฑ์มีการเปลี่ยนแปลง AnchoredDraggableState มีพารามิเตอร์ positionalThreshold ที่ใช้ฟังก์ชันแลมบ์ดาซึ่งแสดงผล
ตำแหน่งของเกณฑ์แทนที่จะมีอินเทอร์เฟซ ThresholdConfig แยกต่างหาก
เช่น เกณฑ์ตำแหน่ง 50% อาจแสดงได้ดังนี้
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { distance -> distance * 0.5f },
...
)
เกณฑ์ตำแหน่งของ 56dp สามารถแสดงได้ดังนี้
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { with(density) { 56.dp.toPx() } },
...
)
กำหนดเกณฑ์ความเร็ว
นอกจากนี้ ยังมีการส่งผ่านเกณฑ์ความเร็วไปยังตัวสร้างของ AnchoredDraggableState และแสดงเป็น Lambda ด้วย
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
velocityThreshold = { with(density) { 125.dp.toPx() } },
...
)
การเปลี่ยนแปลงใน API Surface
ดูภาพรวมของการเปลี่ยนแปลงใน API Surface ด้านล่าง
AnchoredDraggableState
|
|
|---|---|
|
|
|
|
|
[ |
|
|
|
|
[ |
ไม่มี |
|
|
|
|
|
|
|
|
|
|
|
Modifier.anchoredDraggable
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
ส่งไปยังตัวสร้าง |
|
ยังไม่รองรับ ดูสถานะล่าสุดได้ที่ b/288084801 |
|
ส่งไปยังตัวสร้าง |