Swipeable
— это API Compose Material, который помогает создавать компоненты, которые можно перемещать между отдельными состояниями, например нижние листы, ящики или пролистывание для закрытия. Для лучшей поддержки расширенных вариантов использования, таких как привязки, зависящие от размера компонента, в Compose-Foundation 1.6.0-alpha01 был опубликован преемник: AnchoredDraggable
. AnchoredDraggable
— это API-интерфейс Foundation для создания перетаскиваемых компонентов с привязанными состояниями, таких как нижние листы, ящики или пролистывание для закрытия.
API-интерфейсы Swipeable
Material устарели в пользу AnchoredDraggable
Foundation и будут удалены в будущем выпуске. В этом руководстве описывается, как перейти с API Swipeable
на AnchoredDraggable
.
Миграция SwipeableState
в AnchoredDraggableState
Начните с выявления изменений в держателе вашего состояния. AnchoredDraggableState
не может быть унаследован, а смещение представлено как Float.NaN
до его инициализации.
Обновите свой государственный держатель
AnchoredDraggableState
— это финальный класс, то есть от него нельзя унаследоваться. Если ваш существующий компонент наследует от SwipeableState
, обновите свой держатель состояния, чтобы он содержал ссылку на AnchoredDraggableState
вместо наследования от него:
Перелистываемый
class MySwitchState: SwipeableState()
ПрикрепленныйПеретаскиваемый
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
Поскольку ваш держатель состояния больше не наследуется от SwipeableState
, вам, возможно, придется предоставить API самостоятельно. Наиболее распространенные API, которые вы можете использовать, — это offset
, progress
, currentValue
и targetValue
.
Доступ к смещению
В отличие от Swipeable
, offset
AnchoredDraggableState
равно Float.NaN
до его инициализации. В AnchoredDraggable
привязки можно передать конструктору AnchoredDraggableState
или обновить с помощью AnchoredDraggableState#updateAnchors
. Передача привязок конструктору AnchoredDraggableState
немедленно инициализирует смещение.
Если ваши привязки зависят от макета или могут измениться, используйте AnchoredDraggableState#updateAnchors
чтобы избежать повторного создания состояния при изменении привязок.
Если вы используете updateAnchors
, перед передачей привязок в updateAnchors
смещение будет Float.NaN
. Чтобы избежать случайной передачи 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) }
}
}
Перенести Modifier.swipeable
в 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
.
Определить позиционные пороги
Тип и имя параметра порогов изменились. Вместо отдельного интерфейса 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 . |
| Передано конструктору |