Swipeable — это API Compose Material, который помогает создавать компоненты, позволяющие переключаться между дискретными состояниями с помощью свайпа, например, нижние панели, выдвижные панели или кнопки закрытия свайпом. Для лучшей поддержки сложных сценариев использования, таких как привязки, зависящие от размера компонента, в Compose-Foundation 1.6.0-alpha01 был опубликован преемник: AnchoredDraggable . AnchoredDraggable — это API Foundation для создания перетаскиваемых компонентов с привязанными состояниями, такими как нижние панели, выдвижные панели или кнопки закрытия свайпом.
API-интерфейсы Swipeable в Material Design устарели и заменены на AnchoredDraggable в Foundation, поэтому они будут удалены в одном из будущих релизов. В этом руководстве описывается, как перейти с API-интерфейсов Swipeable на AnchoredDraggable .
Перенести SwipeableState в AnchoredDraggableState
Начните с определения изменений в вашем контейнере состояния. От AnchoredDraggableState нельзя получить наследие, а смещение представляется как Float.NaN до инициализации.
Обновите данные владельца вашего штата.
Класс AnchoredDraggableState является финальным (final class), то есть от него нельзя наследовать. Если ваш существующий компонент наследует от SwipeableState , обновите ваш state holder, чтобы он содержал ссылку на AnchoredDraggableState вместо наследования от него:
Пролистывание
class MySwitchState: SwipeableState()
AnchoredDraggable
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
Поскольку ваш stateholder больше не наследует от SwipeableState , вам, возможно, придётся самостоятельно предоставлять API. Наиболее распространённые API, которые вы можете использовать, — это offset , progress , currentValue и targetValue .
Получите доступ к смещению
В отличие от Swipeable , offset в AnchoredDraggableState до инициализации имеет значение Float.NaN . В AnchoredDraggable якоря можно передать в конструктор AnchoredDraggableState или обновить с помощью AnchoredDraggableState#updateAnchors . Передача якорей в конструктор AnchoredDraggableState немедленно инициализирует смещение.
If your anchors depend on layout or could change, use AnchoredDraggableState#updateAnchors to avoid recreating the state when the anchors change.
Если вы используете updateAnchors , смещение будет иметь значение Float.NaN перед передачей якорей в updateAnchors . Чтобы избежать случайной передачи Float.NaN компонентам, используйте AnchoredDraggableState#requireOffset , чтобы потребовать, чтобы смещение было инициализировано при его чтении. Это поможет вам выявлять несоответствия или возможные ошибки на ранней стадии.
@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) }
}
}
Migrate Modifier.swipeable to Modifier.anchoredDraggable
Modifier.anchoredDraggable() заменяет Modifier.swipeable . Некоторые параметры Modifier.swipeable() были перенесены непосредственно в AnchoredDraggableState , как описано в следующих разделах.
Определить якоря
Определите точки привязки, используя метод конструктора DraggableAnchors . Затем передайте их в AnchoredDraggableState#updateAnchors или в конструктор AnchoredDraggableState :
Конструктор
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) }
)
}
обновить якоря
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) }
)
}
Если ссылки на элементы статические, передайте их в конструктор. Если они зависят от макета или не являются статическими, используйте updateAnchors .
Определите позиционные пороговые значения
Изменились тип и имя параметра thresholds. Вместо отдельного интерфейса ThresholdConfig , AnchoredDraggableState имеет параметр positionalThreshold , который принимает лямбда-функцию, возвращающую позицию порога. Например, позиционный порог в 50% может быть выражен следующим образом:
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { distance -> distance * 0.5f },
...
)
Позиционный порог в 56dp можно выразить следующим образом:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { with(density) { 56.dp.toPx() } },
...
)
Определите пороговые значения скорости
Пороговые значения скорости также передаются в конструктор AnchoredDraggableState и выражаются в виде лямбда-функции:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
velocityThreshold = { with(density) { 125.dp.toPx() } },
...
)
Изменения в интерфейсе API
Ниже представлен обзор изменений в интерфейсе API.
AnchoredDraggableState
| |
|---|---|
| |
| |
| |
| |
| |
| Н/Д |
| |
| |
| |
| |
| |
|
Modifier.anchoredDraggable
| |
|---|---|
| |
| |
| |
| |
| |
| |
| Передается в конструктор |
| Поддержка пока отсутствует. Актуальную информацию см. в репозитории b/288084801 . |
| Передаётся в конструктор |