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

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

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

نقل بيانات SwipeableState إلى AnchoredDraggableState

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

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

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

قابلة للتمرير السريع

class MySwitchState: SwipeableState()

قابل للسحب

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

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

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

على عكس Swipeable، قيمة offset في AnchoredDraggableState هي Float.NaN قبل إعدادها. في AnchoredDraggable، يمكن تمرير علامات الارتساء إلى الدالة الإنشائية لـ AnchoredDraggableState أو تعديلها من خلال AnchoredDraggableState#updateAnchors. ويؤدي تمرير علامات الارتساء إلى الدالة الإنشائية لـ AnchoredDraggableState إلى إعداد الإزاحة على الفور.

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

إذا كنت تستخدم updateAnchors، ستكون الإزاحة 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) }
    )
}

علامات تحديث تلقائية

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 تأخذ دالة lambda التي تعرض موضع الحدّ. على سبيل المثال، يمكن التعبير عن حد الموضع بنسبة 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() } },
    ...
)

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

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

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).