Swipeable
是一种 Compose Material API,可帮助您构建
可以在不同的状态(如底部动作条、抽屉式导航栏或
滑动关闭。为了更好地支持高级用例,例如锚点
取决于组件大小,后续版本发布于
Compose-Foundation 1.6.0-alpha01:AnchoredDraggable
。AnchoredDraggable
是用于构建具有锚定状态的可拖动组件的基础 API,
显示为底部动作条、抽屉式导航栏或滑动关闭。
Material 的 Swipeable
API 已废弃,取而代之的是 Foundation 的
AnchoredDraggable
,并将在未来的版本中移除。本指南
介绍了如何从 Swipeable
API 迁移到 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
中不同,AnchoredDraggableState
的 offset
早于 Swipeable
Float.NaN
完成初始化在 AnchoredDraggable
中,可将锚点传递给
AnchoredDraggableState
的构造函数或通过
AnchoredDraggableState#updateAnchors
。将锚点传递给
AnchoredDraggableState
的构造函数会立即初始化偏移量。
如果您的锚点依赖于布局或者可能会发生变化,请使用
AnchoredDraggableState#updateAnchors
,以避免在创建
定位点发生变化
如果您使用 updateAnchors
,则在传递Float.NaN
锚定到 updateAnchors
。为避免意外将 Float.NaN
传递给
组件,请使用 AnchoredDraggableState#requireOffset
来要求
在读取时已初始化偏移量。这有助于您
或可能出现的 bug 问题。
@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) }
)
}
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) }
)
}
如果锚点是静态的,则将其传递给构造函数。如果它们依赖于
非静态布局,请使用 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
的构造函数。
也可以表示为 lambda:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
velocityThreshold = { with(density) { 125.dp.toPx() } },
...
)
API Surface 的变化
下文提供了 API Surface 变更的概览。
AnchoredDraggableState
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
|
不适用 |
|
|
|
|
|
|
|
|
|
|
|
Modifier.anchoredDraggable
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
作为 |
|
尚不支持。如需了解最新状态,请参阅 b/288084801。 |
|
已传递给 |