Swipeable é uma API do Compose Material que ajuda a criar componentes que
podem ser deslizados entre estados discretos, como páginas inferiores, gavetas ou
deslizar para dispensar. Para oferecer melhor suporte a casos de uso avançados, como âncoras que
dependem do tamanho de um componente, um sucessor foi publicado no
Compose-Foundation 1.6.0-alpha01: AnchoredDraggable. AnchoredDraggable
é uma API do Foundation para criar componentes arrastáveis com estados fixados, como
folhas de fundo, gavetas ou deslize para fechar.
As APIs Swipeable do Material foram descontinuadas em favor da AnchoredDraggable
do Foundation e serão removidas em uma versão futura. Este guia
descreve como migrar das APIs Swipeable para AnchoredDraggable.
Migre SwipeableState para AnchoredDraggableState
Comece identificando as mudanças no seu detentor de estado. AnchoredDraggableState
não pode ser herdado, e o deslocamento é representado como Float.NaN antes de ser
inicializado.
Atualizar o detentor de estado
AnchoredDraggableState é uma classe final, o que significa que ela não pode ser herdada. Se o componente existente for herdado de SwipeableState, atualize
o detentor de estado para manter uma referência ao AnchoredDraggableState em vez de
herdar dele:
Deslizante
class MySwitchState: SwipeableState()
AnchoredDraggable
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
Como o detentor de estado não herda mais de SwipeableState, talvez
seja necessário expor as APIs. As APIs mais comuns que você pode usar são
offset, progress, currentValue e targetValue.
Acessar o deslocamento
Ao contrário de Swipeable, o offset de AnchoredDraggableState é Float.NaN antes
de ser inicializado. No AnchoredDraggable, as âncoras podem ser transmitidas para
o construtor da AnchoredDraggableState ou atualizadas pelo
AnchoredDraggableState#updateAnchors. A transmissão das âncoras para
o construtor de AnchoredDraggableState inicializa o deslocamento imediatamente.
Se as âncoras dependem do layout ou podem mudar, use
AnchoredDraggableState#updateAnchors para evitar recriar o estado quando as
âncoras mudarem.
Se você usar updateAnchors, o deslocamento será Float.NaN antes de transmitir as
âncoras para updateAnchors. Para evitar a transmissão acidental de Float.NaN para
componentes, use AnchoredDraggableState#requireOffset para exigir que o
offset tenha sido inicializado ao ser lido. Isso ajuda a detectar
inconsistências ou possíveis bugs logo no início.
@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) }
}
}
Migre Modifier.swipeable para Modifier.anchoredDraggable
Modifier.anchoredDraggable() substitui Modifier.swipeable. Alguns
dos parâmetros de Modifier.swipeable() foram movidos diretamente para AnchoredDraggableState, conforme descrito nas seções a seguir.
Definir âncoras
Defina as âncoras usando o método de builder DraggableAnchors. Em seguida, transmita
elas para o AnchoredDraggableState#updateAnchors ou o AnchoredDraggableState
do construtor:
Construtor
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 as âncoras forem estáticas, transmita-as ao construtor. Se eles dependem do
layout ou não são estáticos, use updateAnchors.
Definir limites de posicionamento
O tipo e o nome do parâmetro limites mudaram. Em vez de ter uma
interface ThresholdConfig separada, o AnchoredDraggableState tem um
parâmetro positionalThreshold que usa uma função lambda que retorna a
posição do limite. Por exemplo, um limite posicional de 50% pode ser
expresso como:
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { distance -> distance * 0.5f },
...
)
Um limite posicional de 56dp pode ser expresso como:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { with(density) { 56.dp.toPx() } },
...
)
Definir limites de velocidade
Os limites de velocidade também são transmitidos para o construtor de AnchoredDraggableState
e expressos como uma lambda:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
velocityThreshold = { with(density) { 125.dp.toPx() } },
...
)
Mudanças na plataforma da API
Confira uma visão geral das mudanças na API abaixo.
AnchoredDraggableState
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
N/A |
|
|
|
|
|
|
|
|
|
|
|
Modifier.anchoredDraggable
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
Transmitido para o construtor |
|
Sem suporte no momento. Consulte o status mais recente em b/288084801. |
|
Transmitido para o construtor |