Swipeable から AnchoredDraggable に移行する

Swipeable は、次のようなコンポーネントの作成に役立つ Compose Material API です。 スワイプすることで、ボトムシート、引き出し、 スワイプして閉じることができます。高度なユースケースをサポートするには、 コンポーネントの規模によっては後継が Compose-Foundation 1.6.0-alpha01: AnchoredDraggableAnchoredDraggable は、次のように、固定された状態を持つドラッグ可能なコンポーネントを構築するための Foundation API です。 閉じることもできます。

Foundation の採用により、マテリアルの Swipeable API のサポートは終了しました。 AnchoredDraggable。今後のリリースで削除される予定です。このガイド Swipeable API から AnchoredDraggable に移行する方法について説明します。

SwipeableStateAnchoredDraggableState に移行する

まず、状態ホルダーの変更を特定します。AnchoredDraggableState 継承できず、オフセットは前の Float.NaN として表される 初期化されます。

状態ホルダーを更新する

AnchoredDraggableState は final クラスです。つまり、継承することはできません 選択します。既存のコンポーネントが SwipeableState から継承する場合は、 代わりに AnchoredDraggableState への参照を保持するために、状態ホルダーを使用します。 確認します。

スワイプ可能

class MySwitchState: SwipeableState()

AnchoredDraggable

class MySwitchState {
    private val anchoredDraggableState = AnchoredDraggableState(...)
}

状態ホルダーは SwipeableState から継承しなくなったため、 自分で API を公開しなければならない場合もあります。最も一般的な API は次のとおりです。 offsetprogresscurrentValuetargetValue

オフセットにアクセスする

Swipeable とは異なり、AnchoredDraggableStateoffset は前の Float.NaN 初期化されます。AnchoredDraggable では、アンカーを AnchoredDraggableState のコンストラクタ、または AnchoredDraggableState#updateAnchors。アンカーを AnchoredDraggableState のコンストラクタは、オフセットをすぐに初期化します。

アンカーがレイアウトに依存する場合や変更される可能性がある場合は、 AnchoredDraggableState#updateAnchors: リソースの作成時に状態が再作成されないように アンカーが変化します。

updateAnchors を使用する場合、オフセットは Float.NaNupdateAnchors へのアンカー。誤って Float.NaN を 作成するには、AnchoredDraggableState#requireOffset を使用して、 offset は読み取り時に初期化されています。これにより、 不整合やバグの可能性を早期に発見できます

@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.swipeableModifier.anchoredDraggable に移行する

Modifier.swipeable に代わる Modifier.anchoredDraggable() です。一部 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

SwipeableState

AnchoredDraggableState

open class SwipeableState(initialValue: T, animationSpec: AnimationSpec = …, confirmStateChange: (T) -> Boolean = …)

class AnchoredDraggableState( initialValue: T, animationSpec: AnimationSpec = …, confirmValueChange: (T) -> Boolean = …, positionalThreshold: Density.(Float) -> Float = …, velocityThreshold: Dp = …)

offset: State

offset: Float
requireOffset()

progress: SwipeProgress

progress: Float [0f..1f] を選択)

currentValue: T

currentValue: T

targetValue: T

targetValue: T

direction: Float [-1f, 0f, 1f] を選択)

なし

suspend animateTo(
targetValue: T,
anim: AnimationSpec = …)

suspend animateTo(
targetState: T,
velocity: Float =
lastVelocity)

suspend snapTo(targetValue: T)

suspend snapTo(targetValue: T)

performDrag(delta: Float)

dispatchRawDelta(delta: Float)

suspend performFling(velocity: Float)

suspend settle(velocity: Float)

isAnimationRunning: Boolean

isAnimationRunning: Boolean

lastVelocity: Float

Modifier.anchoredDraggable

Modifier.swipeable

Modifier.anchoredDraggable

state: SwipeableState

state: AnchoredDraggableState

anchors: Map

AnchoredDraggableState#updateAnchors
or

AnchoredDraggableState#constructor

orientation: Orientation

orientation: Orientation

enabled: Boolean = true

enabled: Boolean = true

reverseDirection: Boolean = false

reverseDirection: Boolean = false

interactionSource: MutableInteractionSource? = null

interactionSource: MutableInteractionSource? = null

thresholds: (from: T, to: T) -> ThresholdConfig = FixedThreshold(56.dp)

AnchoredDraggableState コンストラクタに positionalThreshold として渡されます

resistance: ResistanceConfig? = …

現時点ではサポートされていません。最新のステータスについては、b/288084801 をご覧ください。

velocityThreshold: Dp = 125.dp

AnchoredDraggable コンストラクタに渡されます。