Kaydırılabilirden SabitlenmişDraggable'a Geçiş

Swipeable, alt sayfalar, çekmeceler veya hızlıca kaydırarak kapatmak için farklı durumlar arasında kaydırılabilen bileşenler oluşturmanıza yardımcı olan bir Compose Material API'sidir. Bileşenin boyutuna bağlı olan sabitler gibi ileri düzey kullanım alanlarını daha iyi desteklemek için Composer-Foundation 1.6.0-alpha01: AnchoredDraggable sürümünde bir halef yayınlandı. AnchoredDraggable, alt sayfalar, çekmeceler veya hızlıca kaydırarak kapatma gibi sabit durumlarda sürüklenebilir bileşenler oluşturmaya yönelik bir Temel API'dir.

Materyalin Swipeable API'leri kullanımdan kaldırılmıştır ve yerine Foundation'ın AnchoredDraggable API'si getirilmektedir ve gelecekteki bir sürümde kaldırılacaktır. Bu kılavuzda, Swipeable API'lerinden AnchoredDraggable'a nasıl geçiş yapılacağı açıklanmaktadır.

SwipeableState cihazını AnchoredDraggableState hedefine taşıyın

Eyalet sahibinizdeki değişiklikleri tanımlayarak başlayın. AnchoredDraggableState şuradan devralınamaz ve ofset, başlatılmadan önce Float.NaN olarak temsil edilir.

Eyalet sahibinizi güncelleme

AnchoredDraggableState bir nihai sınıftır. Diğer bir deyişle, bu sınıftan devralınamaz. Mevcut bileşeniniz SwipeableState öğesini devralıyorsa durum sahibinizi, öğeden devralmak yerine AnchoredDraggableState öğesine bir referans içerecek şekilde güncelleyin:

Kaydırılabilir

class MySwitchState: SwipeableState()

Sabit Sürüklenebilir

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

Durum sahibiniz artık SwipeableState öğelerini devralmadığından API'leri kendiniz kullanıma sunmanız gerekebilir. En yaygın olarak offset, progress, currentValue ve targetValue API'lerini kullanabilirsiniz.

Ofset erişimi

Swipeable uygulamasının aksine AnchoredDraggableState offset özelliği başlatılmadan önce Float.NaN değerindedir. AnchoredDraggable ürününde çapalar AnchoredDraggableState oluşturucuya iletilebilir veya AnchoredDraggableState#updateAnchors aracılığıyla güncellenebilir. Çapaların AnchoredDraggableState oluşturucusuna geçirilmesi, ofseti hemen başlatır.

Anchor'larınız düzene bağlıysa veya değişebilecekse çapalar değiştiğinde durumu yeniden oluşturmaktan kaçınmak için AnchoredDraggableState#updateAnchors kullanın.

updateAnchors kullanırsanız çapalar updateAnchors öğesine geçirilmeden önce göreli konum Float.NaN olur. Float.NaN değerini yanlışlıkla bileşenlere geçirmeyi önlemek için AnchoredDraggableState#requireOffset kullanarak ofsetin okuma sırasında başlatılmasını zorunlu kılın. Bu, tutarsızlıkları veya olası hataları önceden fark etmenize yardımcı olur.

@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 cihazını Modifier.anchoredDraggable hedefine taşıyın

Modifier.anchoredDraggable(), Modifier.swipeable yerine geçer. Bazı Modifier.swipeable() parametreleri, aşağıdaki bölümlerde açıklandığı gibi doğrudan AnchoredDraggableState konumuna taşındı.

Anchor'ları tanımlama

Anchor'ları DraggableAnchors oluşturucu yöntemini kullanarak tanımlayın. Ardından, bunları AnchoredDraggableState#updateAnchors veya AnchoredDraggableState oluşturucuya iletin:

Oluşturucu

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

Anchor'lar statikse bunları oluşturucuya iletin. Bunlar düzene bağlıysa veya statik değilse updateAnchors kullanın.

Konumlandırma eşiklerini tanımlama

Eşikler parametresinin türü ve adı değişti. AnchoredDraggableState, ayrı bir ThresholdConfig arayüzüne sahip olmak yerine, eşiğin konumunu döndüren lambda işlevini alan bir positionalThreshold parametresine sahiptir. Örneğin, %50'lik bir konum eşiği şu şekilde ifade edilebilir:

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

56dp'lık bir konum eşiği şu şekilde ifade edilebilir:

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

Hız eşiklerini tanımlama

Hız eşikleri de AnchoredDraggableState oluşturucuya iletilir ve ayrıca lambda olarak ifade edilir:

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

API yüzeyindeki değişiklikler

Aşağıda, API yüzeyinde yapılan değişikliklerle ilgili genel bir bakış bulabilirsiniz.

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]

Yok

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 oluşturucuya positionalThreshold olarak iletildi

resistance: ResistanceConfig? = …

Henüz desteklenmiyor. En son durum için b/288084801 adresini ziyaret edin.

velocityThreshold: Dp = 125.dp

AnchoredDraggable oluşturucuya iletildi