ย้ายข้อมูลจากแบบปัดได้ไปยัง AnchorredDraggable

Swipeable เป็น Compose Material API ที่ช่วยคุณสร้างคอมโพเนนต์ที่ สามารถปัดระหว่างสถานะที่ไม่ต่อเนื่อง เช่น ชีตด้านล่าง ลิ้นชัก หรือ การปัดเพื่อปิด เราได้เผยแพร่ฟีเจอร์รุ่นต่อใน Compose-Foundation 1.6.0-alpha01 ซึ่งก็คือ AnchoredDraggable เพื่อรองรับกรณีการใช้งานขั้นสูงได้ดียิ่งขึ้น เช่น แองเคอร์ที่ขึ้นอยู่กับขนาดของคอมโพเนนต์ AnchoredDraggable เป็น Foundation API สำหรับสร้างคอมโพเนนต์ที่ลากได้โดยมีสถานะที่ยึดไว้ เช่น ชีตด้านล่าง แถบลิ้นชัก หรือการปัดเพื่อปิด

เราได้เลิกใช้งาน Material's Swipeable APIs เพื่อให้ใช้ Foundation's AnchoredDraggable แทน และจะนำออกในรุ่นต่อๆ ไป คู่มือนี้ อธิบายวิธีย้ายข้อมูลจาก Swipeable API ไปยัง AnchoredDraggable

ย้ายข้อมูล SwipeableState ไปยัง AnchoredDraggableState

เริ่มด้วยการระบุการเปลี่ยนแปลงในตัวเก็บสถานะ AnchoredDraggableState จะรับค่าจากที่อื่นไม่ได้ และออฟเซ็ตจะแสดงเป็น Float.NaN ก่อนที่จะ เริ่มต้น

อัปเดตตัวเก็บสถานะของคุณ

AnchoredDraggableState เป็นคลาสสุดท้าย ซึ่งหมายความว่าคลาสนี้จะรับค่าจากคลาสอื่นไม่ได้ หากคอมโพเนนต์ที่มีอยู่สืบทอดมาจาก SwipeableState ให้อัปเดต ตัวเก็บสถานะเพื่อเก็บการอ้างอิงไปยัง AnchoredDraggableState แทน การสืบทอดมาจาก

ปัดได้

class MySwitchState: SwipeableState()

AnchoredDraggable

class MySwitchState {
    private val anchoredDraggableState = AnchoredDraggableState(...)
}

เนื่องจากตัวเก็บสถานะไม่ได้สืบทอดมาจาก SwipeableState อีกต่อไป คุณอาจต้องเปิดเผย API ด้วยตนเอง API ที่พบบ่อยที่สุดที่คุณใช้ได้คือ offset, progress, currentValue และ targetValue

เข้าถึงออฟเซ็ต

offset ของ AnchoredDraggableState ใน Swipeable จะเป็น Float.NaN ก่อน ที่จะเริ่มต้น ใน AnchoredDraggable คุณสามารถส่งแองเคอร์ไปยัง ตัวสร้างของ AnchoredDraggableState หรืออัปเดตผ่าน AnchoredDraggableState#updateAnchors ได้ การส่งผ่าน Anchor ไปยัง AnchoredDraggableState's constructor จะเริ่มต้นออฟเซ็ตทันที

หากจุดยึดขึ้นอยู่กับเลย์เอาต์หรืออาจมีการเปลี่ยนแปลง ให้ใช้ AnchoredDraggableState#updateAnchors เพื่อหลีกเลี่ยงการสร้างสถานะใหม่เมื่อ จุดยึดมีการเปลี่ยนแปลง

หากใช้ 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

กำหนดจุดยึดโดยใช้วิธีการสร้าง 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 ที่ใช้ฟังก์ชัน Lambda ซึ่งแสดงผล ตำแหน่งของเกณฑ์แทนที่จะมีอินเทอร์เฟซ 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

ดูภาพรวมการเปลี่ยนแปลงใน API Surface ได้ที่ด้านล่าง

AnchoredDraggableState

SwipeableState

AnchoredDraggableState

open class SwipeableState(initialValue: T, animationSpec: AnimationSpec = …, confirmStateChange: (T) -> Boolean = …)

class AnchoredDraggableState( initialValue: T, animationSpec: AnimationSpec = …, confirmValueChange: (T) -> Boolean = …, positionalThreshold: Density.(Float) -> Float = …, velocityThreshold: Dp = …)

offset: State

offset: Float
requireOffset()

progress: SwipeProgress

[progress: Float [0f..1f]

currentValue: T

currentValue: T

targetValue: T

targetValue: T

[direction: Float [-1f, 0f, 1f]

ไม่มี

suspend animateTo(
targetValue: T,
anim: AnimationSpec = …)

suspend animateTo(
targetState: T,
velocity: Float =
lastVelocity)

suspend snapTo(targetValue: T)

suspend snapTo(targetValue: T)

performDrag(delta: Float)

dispatchRawDelta(delta: Float)

suspend performFling(velocity: Float)

suspend settle(velocity: Float)

isAnimationRunning: Boolean

isAnimationRunning: Boolean

lastVelocity: Float

Modifier.anchoredDraggable

Modifier.swipeable

Modifier.anchoredDraggable

state: SwipeableState

state: AnchoredDraggableState

anchors: Map

AnchoredDraggableState#updateAnchors
or

AnchoredDraggableState#constructor

orientation: Orientation

orientation: Orientation

enabled: Boolean = true

enabled: Boolean = true

reverseDirection: Boolean = false

reverseDirection: Boolean = false

interactionSource: MutableInteractionSource? = null

interactionSource: MutableInteractionSource? = null

thresholds: (from: T, to: T) -> ThresholdConfig = FixedThreshold(56.dp)

ส่งไปยังตัวสร้าง AnchoredDraggableState เป็น positionalThreshold

resistance: ResistanceConfig? = …

ยังไม่รองรับ ดูสถานะล่าสุดได้ที่ b/288084801

velocityThreshold: Dp = 125.dp

ส่งต่อให้เครื่องมือสร้าง AnchoredDraggable