LoginSignup
3
4
Android強化月間 - Androidアプリ開発の知見を共有しよう -

Jetpack Navigation で Material 3 に沿った画面遷移アニメーションを設定する

Posted at

はじめに

Android アプリにおける画面遷移は主に

がありますが、この記事では Jetpack Navigation による画面遷移のアニメーションについて述べます。Jetpack Naviation は Compose 登場前から開発しているアプリでは、現在でも使われているケースが多いと思います。

Jetpack Navigation による画面遷移は設定しなければアニメーションなし

Jetpack Navigation では XML で画面遷移を定義しますが、それだけでは画面遷移がカットインになっていしまい不自然です。

nav_graph.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph"
    app:startDestination="@+id/screen1">
    <fragment
        android:id="@+id/screen1"
        android:name="com.tfandkusu.ate.feature.jnta.Screen1Fragment">
        <action
            android:id="@+id/actionScreen2"
            app:destination="@+id/screen2" />
    </fragment>
    <fragment
        android:id="@+id/screen2"
        android:name="com.tfandkusu.ate.feature.jnta.Screen2Fragment" />
</navigation>
Screen1Fragment.kt
// Screen1Fragment から Screen2Fragment に遷移する
findNavController().navigate(
    Screen1FragmentDirections.actionScreen2(),
)

cutin.gif

ナビゲーション グラフ XML にアニメーションを設定する

ナビゲーション グラフ XML の action タグにアニメーションを設定することができます。

nav_graph.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph"
    app:startDestination="@+id/screen1">
    <fragment
        android:id="@+id/screen1"
        android:name="com.tfandkusu.ate.feature.jnta.Screen1Fragment">
        <!-- アニメーション追加 -->
        <action
            android:id="@+id/actionScreen2"
            app:destination="@+id/screen2"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right" />
    </fragment>
    <fragment
        android:id="@+id/screen2"
        android:name="com.tfandkusu.ate.feature.jnta.Screen2Fragment" />
</navigation>
slide_in_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="400"
        android:fromXDelta="100%p"
        android:toXDelta="0" />
</set>
slide_out_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="400"
        android:fromXDelta="0"
        android:toXDelta="-100%p" />
</set>
slide_in_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="400"
        android:fromXDelta="-100%p"
        android:toXDelta="0" />
</set>
slide_out_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="400"
        android:fromXDelta="0"
        android:toXDelta="100%p" />
</set>

slide.gif

今回は左右にスライドする画面遷移のアニメーションを設定しました。

疑問

ところで、このアニメーションは Android として自然、言い換えると Material Design に沿ったアニメーションなのでしょうか。次の節からは Material Design の公式サイト https://m3.material.io/ を読んで、それに沿ったアニメーションを設定します。

Material Design に沿って画面遷移アニメーションを設定する

Material Design の公式サイト https://m3.material.io/Styles → Motion → Transitions に画面遷移アニメーションのガイドラインがありました。

最初に Container transform という、共通要素の View を使って自然な画面遷移をする別名 Shared element transition に言及していますが、今回はその次の Forward and backward を設定します。

Forward and backward には、アニメーション動画とともに Android implementation というリンクがあるので、そこに飛びます。

Shared axis という節でアニメーションの設定方法を解説しているので、同じように設定します。

Screen1Fragment.kt
// 画面遷移アニメーションを設定する
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
// Screen3Fragment に遷移する
findNavController().navigate(Screen1FragmentDirections.actionScreen3())
Screen3Fragment.kt
class Screen3Fragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 画面遷移アニメーションを設定する
        enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
        returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
    }

    // 略
}

Forward and backward の解説通りのアニメーションが設定できました。

forward.gif

まとめ

この記事では画面遷移に Jetpack Navigation を使っているケースで、 Material Design で紹介されている  Forward and backward アニメーションの設定方法を解説しました。

例えば、iOS の画面遷移に寄せる形で Android 側は独自にアニメーションを設定していたが、やっぱり Android アプリは Android らしさを追求したい場合は、今回紹介した Material Design のサイトを参考にして Android らしい画面遷移アニメーションを設定することができます。

iOSの画面遷移アニメーションの例

ios_push.gif

3
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4