نقل البيانات من قابل للتمرير السريع إلى قابل للسحب الأساسي

Swipeable هي واجهة برمجة تطبيقات Compose Material API تساعدك في إنشاء مكوّنات يمكن التمرير سريعًا بينها بين حالات منفصلة، مثل الأوراق السفلية أو الأدراج أو التمرير سريعًا لإغلاق العنصر. لدعم حالات الاستخدام المتقدّمة بشكلٍ أفضل، مثل عناصر الربط التي تعتمد على حجم المكوّن، تم نشر عنصر لاحق في Compose-Foundation 1.6.0-alpha01: ‏ AnchoredDraggable. AnchoredDraggable هي واجهة برمجة تطبيقات لإنشاء مكونات قابلة للسحب ذات حالات ثابتة، مثل الأوراق السفلية أو الأدراج أو التمرير السريع للإغلاق.

لقد تم إيقاف واجهات برمجة التطبيقات Swipeable التابعة للمواد لصالح AnchoredDraggable الخاصة بالمؤسسة، وستتم إزالتها في إصدار مستقبلي. يشرح هذا الدليل كيفية نقل البيانات من واجهات برمجة تطبيقات Swipeable إلى AnchoredDraggable.

نقل SwipeableState إلى AnchoredDraggableState

ابدأ بتحديد التغييرات التي طرأت على مالك الحالة. لا يمكن اكتساب الخاصية AnchoredDraggableState، ويتم تمثيل الإزاحة كـ Float.NaN قبل إعدادها.

تعديل معلومات صاحب الحالة

AnchoredDraggableState هي فئة نهائية، ما يعني أنّه لا يمكن اكتساب ميزاتها. إذا كان المكوّن الحالي ينشئ عنصرًا فرعيًا من SwipeableState، عدِّل عنصر الحالة ليحتوِى على إشارة إلى AnchoredDraggableState بدلاً من إنشاء عنصر فرعي منه:

تمرير سريع لمشاهدة الفيديو التالي

class MySwitchState: SwipeableState()

AnchoredDraggable

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

بما أنّ مالك الحالة لم يعُد يكتسب معلومات من SwipeableState، قد تحتاج إلى الإفصاح عن واجهات برمجة التطبيقات بنفسك. واجهات برمجة التطبيقات الأكثر شيوعًا التي يمكنك استخدامها هي offset وprogress وcurrentValue وtargetValue.

الوصول إلى الإزاحة

على عكس Swipeable، يكون offset في AnchoredDraggableState هو Float.NaN قبل بدء تشغيله. في AnchoredDraggable، يمكن تمرير نقاط الربط إلى طريقة وضع تصميم AnchoredDraggableState أو تعديلها من خلال AnchoredDraggableState#updateAnchors. يؤدي تمرير نقاط الربط إلى باني AnchoredDraggableState إلى بدء القيمة المُعدَّلة على الفور.

إذا كانت نقاط الربط تعتمد على التنسيق أو يمكن أن تتغيّر، استخدِم AnchoredDraggableState#updateAnchors لتجنُّب إعادة إنشاء الحالة عند تغيُّر نقاط الربط.

في حال استخدام updateAnchors، سيكون ال offset هو Float.NaN قبل تمرير المرسّيات إلى 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 مباشرةً، كما هو موضّح في الأقسام التالية.

تحديد علامات الارتساء

حدِّد نقاط الربط باستخدام طريقة إنشاء 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.

تحديد حدود موضعية

تم تغيير نوع معلَمة الحدود واسمها. بدلاً من استخدام واجهة ThresholdConfig منفصلة، تحتوي دالة AnchoredDraggableState على مَعلمة 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() } },
    ...
)

التغييرات في واجهة برمجة التطبيقات

يمكنك الاطّلاع أدناه على نظرة عامة حول التغييرات التي طرأت على واجهة برمجة التطبيقات.

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