Swipeable는 하단 시트, 창, 스와이프하여 닫기 등 개별 상태 간에 스와이프할 수 있는 구성요소를 빌드하는 데 도움이 되는 Compose Material API입니다. 구성요소의 크기에 종속된 앵커와 같은 고급 사용 사례를 더 잘 지원하기 위해 후속 버전이 Compose-Foundation 1.6.0-alpha01에 게시되었습니다(AnchoredDraggable). AnchoredDraggable는 고정된 상태(예: 하단 시트, 드로어, 스와이프하여 닫기)로 드래그 가능한 구성요소를 빌드하기 위한 Foundation API입니다.
Material의 Swipeable API는 Foundation의 AnchoredDraggable을 선호하여 지원 중단되었으며 향후 출시에서 삭제될 예정입니다. 이 가이드에서는 Swipeable API에서 AnchoredDraggable로 이전하는 방법을 설명합니다.
SwipeableState를 AnchoredDraggableState로 마이그레이션
상태 홀더의 변경사항을 식별하는 것부터 시작하세요. AnchoredDraggableState는 상속될 수 없으며 오프셋은 초기화되기 전에 Float.NaN로 표시됩니다.
상태 홀더 업데이트
AnchoredDraggableState는 최종 클래스이므로 상속할 수 없습니다. 기존 구성요소가 SwipeableState에서 상속되는 경우 상태 홀더가 AnchoredDraggableState에서 상속되는 대신 AnchoredDraggableState에 대한 참조를 보유하도록 업데이트합니다.
스와이프 가능
class MySwitchState: SwipeableState()
AnchoredDraggable
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
상태 홀더가 더 이상 SwipeableState에서 상속되지 않으므로 API를 직접 노출해야 할 수 있습니다. 사용할 수 있는 가장 일반적인 API는 offset, progress, currentValue, targetValue입니다.
오프셋에 액세스
Swipeable와 달리 AnchoredDraggableState의 offset은 초기화되기 전에는 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) }
)
}
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의 생성자에 전달되며 람다로도 표현됩니다.
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
velocityThreshold = { with(density) { 125.dp.toPx() } },
...
)
API 노출 영역 변경사항
아래에서 API 노출 영역의 변경사항 개요를 확인하세요.
AnchoredDraggableState
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
해당 사항 없음 |
|
|
|
|
|
|
|
|
|
|
|
Modifier.anchoredDraggable
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
아직 지원되지 않습니다. 최신 상태는 b/288084801을 참고하세요. |
|
|