O Swipeable é uma API do Material do Compose 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 ancorados, como
folhas de baixo, gavetas ou deslizar para dispensar.
As APIs Swipeable do Material foram descontinuadas em favor do
AnchoredDraggable do Foundation e serão removidas em uma versão futura. Este guia descreve como migrar das APIs Swipeable para AnchoredDraggable.
Migrar SwipeableState para AnchoredDraggableState
Comece identificando as mudanças no seu gerenciador 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 não pode ser herdada. Se o componente atual herdar de SwipeableState, atualize
o detentor de estado para manter uma referência ao AnchoredDraggableState em vez de
herdar dele:
Deslizável
class MySwitchState: SwipeableState()
AnchoredDraggable
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
Como seu detentor de estado não herda mais de SwipeableState, talvez seja necessário expor as APIs por conta própria. 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. Em AnchoredDraggable, as âncoras podem ser transmitidas para o construtor de
AnchoredDraggableState ou atualizadas por
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 mudam.
Se você usar updateAnchors, o deslocamento será Float.NaN antes de transmitir as âncoras para updateAnchors. Para evitar transmitir Float.NaN acidentalmente aos componentes, use AnchoredDraggableState#requireOffset para exigir que o deslocamento tenha sido inicializado ao ser lido. Isso ajuda a detectar inconsistências ou possíveis bugs no início do processo.
@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) }
}
}
Migrar Modifier.swipeable para Modifier.anchoredDraggable
Modifier.anchoredDraggable() substitui Modifier.swipeable. Alguns 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 builder DraggableAnchors. Em seguida, transmita
para o construtor de AnchoredDraggableState#updateAnchors ou AnchoredDraggableState:
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 posição
O tipo e o nome do parâmetro de limites foram alterados. Em vez de ter uma
interface ThresholdConfig separada, 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 superfície da API
Confira abaixo uma visão geral das mudanças na superfície da API.
AnchoredDraggableState
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
N/A |
|
|
|
|
|
|
|
|
|
|
|
Modifier.anchoredDraggable
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
Transmitido para o construtor |
|
Não compatível no momento. Consulte b/288084801 para conferir o status mais recente. |
|
Transmitido para o construtor |