از Swipeable به AnchoredDraggable مهاجرت کنید

Swipeable یک API Compose Material است که به شما کمک می‌کند اجزایی بسازید که می‌توانند بین حالت‌های مجزا حرکت کنند، مانند صفحات پایین، کشوها، یا کشیدن برای رد کردن. برای پشتیبانی بهتر از موارد استفاده پیشرفته، مانند لنگرهایی که به اندازه یک جزء بستگی دارد، یک جانشین در Compose-Foundation 1.6.0-alpha01: AnchoredDraggable منتشر شد. AnchoredDraggable یک پایه API برای ساخت مؤلفه‌های قابل کشیدن با حالت‌های لنگر است، مانند برگه‌های پایین، کشوها یا تند کشیدن برای رد کردن.

APIهای Swipeable Material به نفع AnchoredDraggable بنیاد منسوخ شده اند و در نسخه بعدی حذف خواهند شد. این راهنما نحوه مهاجرت از APIهای Swipeable به 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 .

به افست دسترسی پیدا کنید

برخلاف Swipeable ، offset AnchoredDraggableState قبل از مقداردهی اولیه Float.NaN است. در AnchoredDraggable ، لنگرها را می توان به سازنده AnchoredDraggableState منتقل کرد یا از طریق AnchoredDraggableState#updateAnchors به ​​روز کرد. ارسال لنگرها به سازنده AnchoredDraggableState ، فوراً افست را مقداردهی اولیه می کند.

اگر لنگرهای شما به چیدمان بستگی دارند یا می‌توانند تغییر کنند، از AnchoredDraggableState#updateAnchors استفاده کنید تا از ایجاد مجدد وضعیت در هنگام تغییر لنگرها جلوگیری کنید.

اگر از updateAnchors استفاده می کنید، قبل از اینکه لنگرها را به updateAnchors منتقل کنید، آفست Float.NaN خواهد بود. برای جلوگیری از انتقال تصادفی Float.NaN به کامپوننت‌ها، از AnchoredDraggableState#requireOffset استفاده کنید تا هنگام خواندن آن، Offset مقداردهی اولیه شود. این به شما کمک می کند تا ناهماهنگی ها یا اشکالات احتمالی را در اوایل تشخیص دهید.

@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 منتقل شده اند، همانطور که در بخش های زیر توضیح داده شده است.

لنگرها را تعریف کنید

لنگرها را با استفاده از روش سازنده 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) }
    )
}

به روز رسانی Anchors

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 به جای داشتن یک رابط جداگانه ThresholdConfig ، یک پارامتر positionalThreshold دارد که یک تابع لامبدا را می گیرد که موقعیت آستانه را برمی گرداند. به عنوان مثال، آستانه موقعیتی 50% می تواند به صورت زیر بیان شود:

val anchoredDraggableState = AnchoredDraggableState(
    positionalThreshold = { distance -> distance * 0.5f },
    ...
)

آستانه موقعیتی 56dp را می توان به صورت زیر بیان کرد:

val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
    positionalThreshold = { with(density) { 56.dp.toPx() } },
    ...
)

آستانه های سرعت را تعریف کنید

آستانه های سرعت نیز به سازنده AnchoredDraggableState منتقل می شوند و همچنین به صورت لامبدا بیان می شوند:

val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
    velocityThreshold = { with(density) { 125.dp.toPx() } },
    ...
)

تغییرات در سطح API

یک نمای کلی از تغییرات سطح API در زیر پیدا کنید.

AnchoredDraggableState

SwipeableState

AnchoredDraggableState

open class SwipeableState (initialValue: T, animationSpec: AnimationSpec = …, confirmStateChange: (T) -> Boolean = …) open class SwipeableState (initialValue: T, animationSpec: AnimationSpec = …, confirmStateChange: (T) -> Boolean = …) 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 = …) class AnchoredDraggableState ( initialValue: T, animationSpec: AnimationSpec = …, confirmValueChange: (T) -> Boolean = …, positionalThreshold: Density.(Float) -> Float = …, velocityThreshold: Dp = …) 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 ]

N/A

suspend animateTo(
targetValue: T,
anim: AnimationSpec = …)
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 منتقل شد