Swipeable es una API de Compose Material que te ayuda a compilar componentes que se pueden deslizar entre estados discretos, como hojas inferiores, paneles laterales o la acción de deslizar para descartar. Para admitir mejor los casos de uso avanzados, como los anclajes que
dependen del tamaño de un componente, se publicó un sucesor en
Compose-Foundation 1.6.0-alpha01: AnchoredDraggable. AnchoredDraggable
es una API de Foundation para compilar componentes arrastrables con estados anclados, como hojas inferiores, paneles laterales o la acción de deslizar para descartar.
Las APIs Swipeable de Material dejaron de estar disponibles en favor de AnchoredDraggable de Foundation y se quitarán en una versión futura. En esta guía, se describe cómo migrar de las APIs Swipeable a AnchoredDraggable.
Migra SwipeableState a AnchoredDraggableState
Para comenzar, identifica los cambios en tu contenedor de estado. AnchoredDraggableState
no se puede heredar, y el desplazamiento se representa como Float.NaN antes de que se
inicialice.
Actualiza tu contenedor de estado
AnchoredDraggableState es una clase final, lo que significa que no se puede heredar. Si tu componente existente hereda de SwipeableState, actualiza
tu contenedor de estado para que contenga una referencia a la AnchoredDraggableState en lugar de
heredar de él:
Swipeable
class MySwitchState: SwipeableState()
AnchoredDraggable
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
Como tu contenedor de estado ya no hereda de SwipeableState, es posible que tengas que exponer las APIs por tu cuenta. Las APIs más comunes que puedes usar son
offset, progress, currentValue y targetValue.
Accede al desplazamiento
A diferencia de Swipeable, el offset de AnchoredDraggableState es Float.NaN antes
de que se inicialice. En AnchoredDraggable, los anclajes se pueden pasar al constructor de
AnchoredDraggableState o actualizarse a través de
AnchoredDraggableState#updateAnchors. Si pasas los anclajes al constructor de AnchoredDraggableState, se inicializa el desplazamiento de inmediato.
Si tus anclajes dependen del diseño o podrían cambiar, usa AnchoredDraggableState#updateAnchors para evitar volver a crear el estado cuando cambien los anclajes.
Si usas updateAnchors, el desplazamiento será Float.NaN antes de pasar los anclajes a updateAnchors. Para evitar pasar Float.NaN a
los componentes por accidente, usa AnchoredDraggableState#requireOffset para requerir que el
desplazamiento se haya inicializado cuando se lea. Esto te ayuda a detectar inconsistencias o posibles errores desde el principio.
@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) }
}
}
Migra Modifier.swipeable a Modifier.anchoredDraggable
Modifier.anchoredDraggable() reemplaza a Modifier.swipeable. Algunos de los parámetros de Modifier.swipeable() se movieron directamente a AnchoredDraggableState, como se describe en las siguientes secciones.
Define anclajes
Define los anclajes con el método de compilador DraggableAnchors. Luego, pásalos a AnchoredDraggableState#updateAnchors o AnchoredDraggableState's constructor:
Constructor
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) }
)
}
Si los anclajes son estáticos, pásalos al constructor. Si dependen del diseño o no son estáticos, usa updateAnchors.
Define umbrales posicionales
El tipo y el nombre del parámetro de umbrales cambiaron. En lugar de tener una
interfaz ThresholdConfig separada, AnchoredDraggableState tiene un parámetro
positionalThreshold que toma una función lambda que muestra la
posición del umbral. Por ejemplo, un umbral posicional del 50% se podría expresar de la siguiente manera:
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { distance -> distance * 0.5f },
...
)
Un umbral posicional de 56dp se podría expresar de la siguiente manera:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { with(density) { 56.dp.toPx() } },
...
)
Define umbrales de velocidad
Los umbrales de velocidad también se pasan al constructor de AnchoredDraggableState y también se expresan como una lambda:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
velocityThreshold = { with(density) { 125.dp.toPx() } },
...
)
Cambios en la superficie de la API
A continuación, encontrarás una descripción general de los cambios en la superficie de la API.
AnchoredDraggableState
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
N/A |
|
|
|
|
|
|
|
|
|
|
|
Modifier.anchoredDraggable
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
Se pasó al constructor de |
|
Aún no se admite. Consulta b/288084801 para conocer el estado más reciente. |
|
Se pasó al constructor de |