Swipeable
es una API de Material de Compose que te ayuda a compilar componentes que se pueden deslizar entre estados discretos, como hojas inferiores, paneles laterales o deslizamiento para descartar. Para admitir mejor los casos de uso avanzados, como las anclas 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 que se pueden arrastrar con estados anclados, como hojas inferiores, paneles laterales o deslizamientos para descartar.
Las APIs de Swipeable
de Material dejaron de estar disponibles y se reemplazaron por AnchoredDraggable
de Foundation, y se quitarán en una versión futura. En esta guía, se describe cómo migrar de las APIs de 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 inicializarse.
Actualiza el contenedor de estado
AnchoredDraggableState
es una clase final, lo que significa que no se puede heredar. Si tu componente existente hereda de SwipeableState
, actualiza el contenedor de estado para que contenga una referencia a AnchoredDraggableState
en lugar de heredarlo:
Deslizable
class MySwitchState: SwipeableState()
Anclado arrastrable
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
Dado que 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
, offset
de AnchoredDraggableState
es Float.NaN
antes de que se inicialice. En AnchoredDraggable
, los anclajes se pueden pasar al constructor de AnchoredDraggableState
o actualizar a través de AnchoredDraggableState#updateAnchors
. Pasar los anclajes al constructor de AnchoredDraggableState
inicializa el desplazamiento de inmediato.
Si tus anclas dependen del diseño o podrían cambiar, usa AnchoredDraggableState#updateAnchors
para evitar recrear el estado cuando cambien las anclas.
Si usas updateAnchors
, el desplazamiento será Float.NaN
antes de pasar los anclas a updateAnchors
. Para evitar pasar Float.NaN
accidentalmente a los componentes, usa AnchoredDraggableState#requireOffset
para exigir que se haya inicializado el desplazamiento cuando lo leas. Esto te ayudará 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 los anuncios fijos
Define los anclajes con el método del compilador DraggableAnchors
. Luego, pásalos al constructor de AnchoredDraggableState#updateAnchors
o AnchoredDraggableState
:
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 anclas son estáticas, pásalas 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 de posición 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() } },
...
)
Cómo definir los umbrales de velocidad
Los umbrales de velocidad también se pasan al constructor de AnchoredDraggableState
y se expresan como una lambda:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
velocityThreshold = { with(density) { 125.dp.toPx() } },
...
)
Cambios en la plataforma de la API
A continuación, encontrarás una descripción general de los cambios en la plataforma de la API.
AnchoredDraggableState
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
|
N/A |
|
|
|
|
|
|
|
|
|
|
|
Modifier.anchoredDraggable
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
Se pasa al constructor |
|
Aún no se admite. Consulta b/288084801 para conocer el estado más reciente. |
|
Se pasa al constructor |