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

Swipeable, alt sayfalar, çekmeceler veya kaydırarak kapatma gibi ayrı durumlar arasında kaydırılabilen bileşenler oluşturmanıza yardımcı olan bir Compose Material API'sidir. Bir bileşenin boyutuna bağlı olan bağlantılar gibi gelişmiş kullanım alanlarını daha iyi desteklemek için Compose-Foundation 1.6.0-alpha01'de bir halef yayınlandı: AnchoredDraggable. AnchoredDraggable alt sayfalar, çekmeceler veya kaydırarak kapatma gibi sabit durumlarla sürüklenebilir bileşenler oluşturmak için kullanılan bir Foundation API'dir.

Material'ın Swipeable API'lerinin desteği sonlandırıldı ve Foundation'ın AnchoredDraggable API'leri kullanıma sunuldu. Bu API'ler gelecekteki bir sürümde kaldırılacak. Bu kılavuzda, Swipeable API'lerinden AnchoredDraggable'ye nasıl geçiş yapılacağı açıklanmaktadır.

SwipeableState alanını AnchoredDraggableState alanına taşıma

Öncelikle durum bilgisi depolayıcınızdaki değişiklikleri belirleyin. AnchoredDraggableState devralınamaz ve ofset, başlatılmadan önce Float.NaN olarak gösterilir.

Durum bilgisi depolayıcınızı güncelleyin

AnchoredDraggableState, nihai bir sınıftır. Bu nedenle, devralınamaz. Mevcut bileşeniniz SwipeableState öğesinden devralıyorsa durum bilgisi depolayıcınızı AnchoredDraggableState öğesinden devralmak yerine AnchoredDraggableState öğesine referans tutacak şekilde güncelleyin:

Kaydırarak izleme

class MySwitchState: SwipeableState()

AnchoredDraggable

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

Durum bilgisi depolayıcınız artık SwipeableState öğesinden devralmadığı için API'leri kendiniz kullanıma sunmanız gerekebilir. Kullanabileceğiniz en yaygın API'ler offset, progress, currentValue ve targetValue'dir.

Ofsete erişme

Swipeable'dan farklı olarak, AnchoredDraggableState'nin offset özelliği başlatılmadan önce Float.NaN olur. AnchoredDraggable içinde, bağlantılar AnchoredDraggableState oluşturucusuna iletilebilir veya AnchoredDraggableState#updateAnchors aracılığıyla güncellenebilir. Sabitleri AnchoredDraggableState'nın oluşturucusuna iletmek, dengelemeyi hemen başlatır.

Bağlantılarınız düzene bağlıysa veya değişebilecekse bağlantılar değiştiğinde durumu yeniden oluşturmamak için AnchoredDraggableState#updateAnchors kullanın.

updateAnchors kullanıyorsanız updateAnchors'ya bağlantılar aktarılmadan önce ofset Float.NaN olur. Float.NaN değerinin bileşenlere yanlışlıkla aktarılmasını önlemek için AnchoredDraggableState#requireOffset kullanarak okunurken ofsetin başlatılmasını zorunlu kılın. Bu sayede tutarsızlıkları veya olası hataları erken aşamada yakalayabilirsiniz.

@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 alanını Modifier.anchoredDraggable alanına taşıma

Modifier.anchoredDraggable(), Modifier.swipeable yerine geçer. Aşağıdaki bölümlerde açıklandığı gibi, Modifier.swipeable() parametrelerinden bazıları doğrudan AnchoredDraggableState'e taşındı.

Bağlantı noktalarını tanımlama

DraggableAnchors oluşturucu yöntemini kullanarak bağlantıları tanımlayın. Ardından bunları AnchoredDraggableState#updateAnchors veya AnchoredDraggableState'nin oluşturucusuna iletin:

Marka

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

Sabit bağlantılar varsa bunları oluşturucuya iletin. Düzenle ilgiliyse veya statik değilse updateAnchors kullanın.

Konumsal eşikleri tanımlama

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

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

56dp 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, AnchoredDraggableState'nın oluşturucusuna da iletilir ve lambda olarak da ifade edilir:

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

API yüzeyinde yapılan değişiklikler

API yüzeyindeki değişikliklere genel bakışı aşağıda 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şturucusuna positionalThreshold olarak iletildi

resistance: ResistanceConfig? = …

Henüz desteklenmiyor. En son durum için b/288084801 adresine bakın.

velocityThreshold: Dp = 125.dp

AnchoredDraggable oluşturucusuna iletildi