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 . |
| Передано конструктору |