Swipeable
è un'API Compose Material che ti aiuta a creare componenti che possono essere spostati tra stati discreti, ad esempio riquadri inferiori, riquadri a scomparsa o scorrimento per chiudere. Per supportare meglio i casi d'uso avanzati, come gli ancoraggi che dipendono dalle dimensioni di un componente, è stato pubblicato un successore in Compose-Foundation 1.6.0-alpha01: AnchoredDraggable
. AnchoredDraggable
è un'API Foundation per la creazione di componenti trascinabili con stati ancorati, come schede inferiori, riquadri o scorrimento per chiudere.
Le API Swipeable
di Material sono state ritirate a favore di quelle di FoundationAnchoredDraggable
e verranno rimosse in una release futura. Questa guida descrive come eseguire la migrazione dalle API Swipeable
a AnchoredDraggable
.
Esegui la migrazione di SwipeableState
a AnchoredDraggableState
Inizia identificando le modifiche al proprietario dello stato. AnchoredDraggableState
non può essere ereditato e l'offset è rappresentato come Float.NaN
prima di
essere inizializzato.
Aggiorna il proprietario dello stato
AnchoredDraggableState
è una classe finale, ovvero non può essere ereditata. Se il componente esistente eredita da SwipeableState
, aggiorna il proprietario dello stato in modo che contenga un riferimento a AnchoredDraggableState
anziché ereditarlo:
Scorrevole
class MySwitchState: SwipeableState()
Trascinabile ancorato
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
Poiché il gestore dello stato non eredita più da SwipeableState
, potresti dover esporre le API autonomamente. Le API più comuni che puoi utilizzare sono
offset
, progress
, currentValue
e targetValue
.
Accedi all'offset
A differenza di Swipeable
, il valore offset
di AnchoredDraggableState
è Float.NaN
prima dell'inizializzazione. In AnchoredDraggable
, le ancore possono essere passate al costruttore di AnchoredDraggableState
o aggiornate tramite AnchoredDraggableState#updateAnchors
. Se passi le ancore al constructor di AnchoredDraggableState
, l'offset viene inizializzato immediatamente.
Se le ancore dipendono dal layout o potrebbero cambiare, utilizza
AnchoredDraggableState#updateAnchors
per evitare di ricreare lo stato quando le
ancore cambiano.
Se utilizzi updateAnchors
, l'offset sarà Float.NaN
prima di passare gli ancoraggi a updateAnchors
. Per evitare di passare accidentalmente Float.NaN
ai componenti, utilizza AnchoredDraggableState#requireOffset
per richiedere che l'offset sia stato inizializzato durante la lettura. In questo modo, puoi rilevare tempestivamente
incoerenze o possibili bug.
@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
. Alcuni parametri di Modifier.swipeable()
sono stati spostati direttamente in AnchoredDraggableState
, come descritto nelle sezioni seguenti.
Definisci gli ancoraggi
Definisci gli ancoraggi utilizzando il metodo del builder di DraggableAnchors
. Poi, passali al constructor di AnchoredDraggableState#updateAnchors
o AnchoredDraggableState
:
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) }
)
}
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) }
)
}
Se le ancore sono statiche, passale al costruttore. Se dipendono dal layout o non sono statici, utilizza updateAnchors
.
Definire le soglie di posizione
Il tipo e il nome del parametro soglie sono cambiati. Invece di avere un'interfaccia ThresholdConfig
separata, AnchoredDraggableState
ha un parametro positionalThreshold
che accetta una funzione lambda che restituisce la posizione della soglia. Ad esempio, una soglia di posizionamento del 50% potrebbe essere expressed as:
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { distance -> distance * 0.5f },
...
)
Una soglia di posizione 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
e espresse anche come lambda:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
velocityThreshold = { with(density) { 125.dp.toPx() } },
...
)
Modifiche alla piattaforma API
Di seguito trovi una panoramica delle modifiche all'interfaccia API.
AnchoredDraggableState
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
|
N/D |
|
|
|
|
|
|
|
|
|
|
|
Modifier.anchoredDraggable
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
Passato al costruttore |
|
Non ancora supportato. Per lo stato più recente, consulta b/288084801. |
|
Passato al costruttore |