Swipeable is a Compose Material API that helps you build components that can be swiped between discrete states, such as bottom sheets, drawers, or swipe-to-dismiss. To better support advanced use cases, such as anchors that depend on the size of a component, a successor was published in Compose-Foundation 1.6.0-alpha01: AnchoredDraggable . AnchoredDraggable is a Foundation API for building draggable components with anchored states, such as bottom sheets, drawers, or swipe-to-dismiss.
API-интерфейсы Swipeable Material устарели в пользу AnchoredDraggable Foundation и будут удалены в будущем выпуске. В этом руководстве описывается, как перейти с API Swipeable на AnchoredDraggable .
Перенос SwipeableState в AnchoredDraggableState
Начните с выявления изменений в вашем держателе штата. AnchoredDraggableState не может быть унаследован, а смещение представлено как Float.NaN до его инициализации.
Обновите своего владельца штата
AnchoredDraggableState — это финальный класс, то есть от него нельзя унаследоваться. If your existing component inherits from SwipeableState , update your state holder to hold a reference to the AnchoredDraggableState instead of inheriting from it:
Перелистываемый
class MySwitchState: SwipeableState()
ПрикрепленныйПеретаскиваемый
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
Поскольку ваш держатель состояния больше не наследуется от SwipeableState , вам, возможно, придется предоставить API самостоятельно. Наиболее распространенные API, которые вы можете использовать, — это offset , progress , currentValue и targetValue .
Доступ к смещению
В отличие от Swipeable , offset AnchoredDraggableState равно Float.NaN до его инициализации. In AnchoredDraggable , the anchors can be passed to AnchoredDraggableState 's constructor or updated through 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 , перед передачей привязок в 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 .
Определить позиционные пороги
Тип и имя параметра порогов изменились. Instead of having a separate ThresholdConfig interface, AnchoredDraggableState has a positionalThreshold parameter that takes a lambda function that returns the position of the threshold. Например, позиционный порог в 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 . |
| Передано конструктору |