予測型「戻る」アニメーションのサポートを追加する

システムの「戻る」API を使用する場合は、アプリ内アニメーションの受け取りをオプトインし、カスタム遷移をサポートすることができます。

動画 1: 予測型「戻る」アニメーション

オプトインすると、アプリは「ホームに戻る」、アクティビティ間、タスク間のアニメーションを表示します。

この動画では、Android 設定アプリを使用して、アクティビティ間と「ホームに戻る」の予測型「戻る」アニメーションの簡単な例を紹介します。

  1. アニメーションでは、ユーザーは後方にスワイプして前の設定画面に戻ります(アクティビティ間アニメーションの例)。
  2. 前の画面で、ユーザーが 2 回目のスワイプを始めると、ホーム画面のプレビューが壁紙とともに表示されます(「ホームに戻る」アニメーションの例)。
  3. ユーザーが右にスワイプし続けると、ウィンドウがホーム画面のアイコンまで縮小するアニメーションが表示されます。
  4. これで、ユーザーは完全にホーム画面に戻ります。

詳しくは、予測型「戻る」ジェスチャーのサポートを追加するをご覧ください。

カスタムのアプリ内遷移とアニメーションを追加する

予測型「戻る」ジェスチャーを使用して、カスタムのアプリ内プロパティ アニメーションと遷移、カスタムのアクティビティ間アニメーション、カスタムのフラグメント間アニメーションを作成できます。

Jetpack Compose でカスタム遷移を追加する

Jetpack Compose で PredictiveBackHandler を使用して予測型「戻る」ジェスチャーを処理し、カスタム アプリ内トランジションを作成できます。この機能は androidx.activity:activity-compose:1.8.0-alpha01 以降でご利用いただけます。

PredictiveBackHandler は、ユーザーがエッジからスワイプして戻るとイベントを発行する Flow<BackEventCompat> を公開するコールバック ラムダを提供します。これらのイベントは、ユーザーのタッチ位置、スワイプの端、最も重要な progress に関する情報を提供します。この情報は、戻るジェスチャーの処理の一環として、コンポーネントをアニメーションで消すために使用できます。

次のスニペットは、PredictiveBackHandler を使用して Surface を縮小し、ジェスチャーの進行状況に合わせて移動させるアニメーションの例を示しています。

@Composable
fun DetailScreen(onBack: () -> Unit) {
    var scale by remember { mutableFloatStateOf(1f) }
    var xOffset by remember { mutableFloatStateOf(0f) }
    val scope = rememberCoroutineScope()

    PredictiveBackHandler { progressFlow ->
        try {
            progressFlow.collectLatest { backEvent ->
                scale = 1f - backEvent.progress
                xOffset = backEvent.progress * 100f
            }
            // User completed gesture
            onBack()
        } catch (e: CancellationException) {
            // User cancelled gesture
            // Animate scale and xOffset back to 1f and 0f respectively
            scope.launch {
                animate(scale, 1f) { value, _ -> scale = value }
            }
            scope.launch {
                animate(xOffset, 0f) { value, _ -> xOffset = value }
            }
        }
    }
    Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        Surface(
            modifier = Modifier
                .size(200.dp)
                .scale(scale)
                .offset(x = xOffset.dp, y = 0.dp),
            color = Color.Blue
        ) {}
    }
}