Esegui la migrazione da Scorrimento a AnchoredTrascinabile

Swipeable è un'API Compose Material che consente di creare componenti che è possibile scorrere tra stati discreti, come fogli inferiori, cassetti o scorri per ignorare. Per supportare meglio i casi d'uso avanzati, come gli ancoraggi che dipendono dalle dimensioni del componente, è stato pubblicato un Compose-Foundation 1.6.0-alpha01: AnchoredDraggable. AnchoredDraggable è un'API Foundation per creare componenti trascinabili con stati ancorati, come come fogli inferiori, riquadri a scomparsa o scorri per chiudere.

Le API Swipeable di Material sono state ritirate a favore delle API di base di AnchoredDraggable e verrà rimossa in una release futura. Questa guida descrive come eseguire la migrazione dalle API Swipeable a AnchoredDraggable.

Esegui la migrazione di SwipeableState a AnchoredDraggableState

Per prima cosa, identifica le modifiche a chi detiene lo stato. AnchoredDraggableState non può essere ereditato e l'offset è rappresentato come Float.NaN prima viene inizializzato.

Aggiorna il proprietario dello stato

AnchoredDraggableState è una classe finale, ovvero non può essere ereditata da cui proviene. Se il componente esistente eredita da SwipeableState, aggiorna il proprietario dello stato deve contenere un riferimento a AnchoredDraggableState anziché a che eredita:

A scorrimento

class MySwitchState: SwipeableState()

Trascinabile ancorato

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

Poiché il proprietario dello stato non eredita più da SwipeableState, potrebbe dover esporre le API autonomamente. Le API più comuni che puoi usare sono offset, progress, currentValue e targetValue.

Accedi all'offset

A differenza di Swipeable, il valore offset di AnchoredDraggableState è Float.NaN prima viene inizializzato. In AnchoredDraggable, gli ancoraggi possono essere trasmessi a il costruttore di AnchoredDraggableState o è stato aggiornato tramite AnchoredDraggableState#updateAnchors Passaggio degli ancoraggi a Il costruttore di AnchoredDraggableState inizializza l'offset immediatamente.

Se gli ancoraggi dipendono dal layout o potrebbero cambiare, utilizza AnchoredDraggableState#updateAnchors per evitare di ricreare lo stato quando cambiano gli ancoraggi.

Se utilizzi updateAnchors, l'offset sarà Float.NaN prima di superare ancorati a updateAnchors. Per evitare di trasmettere involontariamente Float.NaN a utilizza AnchoredDraggableState#requireOffset per richiedere che è stato inizializzato durante la lettura. Questo ti aiuta a individuare incoerenze o possibili bug nella fase iniziale.

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

Esegui la migrazione di Modifier.swipeable a Modifier.anchoredDraggable

Modifier.anchoredDraggable() sostituisce Modifier.swipeable. Alcune dei parametri di Modifier.swipeable() sono stati spostati in AnchoredDraggableState come descritto nelle sezioni seguenti.

Definisci gli ancoraggi

Definisci gli ancoraggi utilizzando il metodo del builder di DraggableAnchors. Quindi, passa a quelli di AnchoredDraggableState#updateAnchors o AnchoredDraggableState costruttore:

Costruttore

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

aggiornamento anchor

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

Se gli ancoraggi sono statici, passali al costruttore. Se dipendono o non sono statici, usa updateAnchors.

Definire le soglie di posizionamento

Il tipo e il nome del parametro soglie sono stati modificati. Invece di avere una separata ThresholdConfig, AnchoredDraggableState ha una Parametro positionalThreshold che accetta una funzione lambda che restituisce il della soglia. Ad esempio, una soglia posizionale del 50% potrebbe essere espresso come:

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

Una soglia posizionale di 56dp potrebbe essere espressa come:

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

Definire le soglie di velocità

Le soglie di velocità vengono passate anche al costruttore di AnchoredDraggableState, ed espresso anche come lambda:

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

Modifiche alla piattaforma API

Di seguito è riportata una panoramica delle modifiche alla piattaforma API.

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

N/D

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)

Passato al costruttore AnchoredDraggableState come positionalThreshold

resistance: ResistanceConfig? = …

Non ancora supportato. Per lo stato più recente, visita la pagina b/288084801.

velocityThreshold: Dp = 125.dp

Passato al costruttore AnchoredDraggable