KC Blog

流暢なAndroidアプリの遷移体験を実現!KotlinでNavigationを使って、アプリの遷移問題を一気に解決!

8 min read
AndroidDev#Android#Kotlin#Navigation

Navigation の紹介

Navigation は強力なライブラリです

Androidアプリケーション内の異なるフラグメント間のナビゲーションを簡単に処理する方法を提供します。

以下の例は

プロジェクトにnavigationを導入し

遷移を設定する例です

プロジェクトが完了したときに

全体の遷移ロジックが一目でわかります

navigation

Navigation の導入開発

Navigation ライブラリをプロジェクトの build.gradle ファイルに追加します

関連するライブラリをbuild.gradleに追加します

<b>注意:「Navigation」コンポーネントはAndroid Studio 3.3以上のバージョンが必要です</b>

Navigation の導入開発

0. IDEを使って素早く作成

Android Studioを使用して プロジェクトディレクトリ内のresフォルダを右クリック > New > Android Resource FileでNavigation xmlを新規作成します。

また、手動で追加したい場合は、resフォルダ内にnavigationフォルダを作成し、その中にnav_graph.xmlを新規作成します

navigation_03 navigation_04
1. <fragment> の作成とstartDestinationの設定
実際のフォルダ構造
navigation_05

フラグメントを追加

id = 名前を指定

name = フラグメントのパス

label = メッセージやタグのようなもの

tools:layout = プレビュー表示するレイアウトのxmlリソース

startDestinationを追加

例:app:startDestination="@id/landingFragment"

navigation_06
2. ActivityのFragmentContainerViewに以下の3行を追加

android:name="androidx.navigation.fragment.NavHostFragment"

app:navGraph="@navigation/navigation_main"(オプション、追加するとIDEでプレビュー可能)

app:defaultNavHost="true"

navigation_07
3. <action>を追加し、目的地を設定

fragment内にactionを追加

追加後、destinationを設定

例:app:destination="@id/signInFragment"

(actionを外に書くと全域での遷移も可能)

navigation_08
4. コードに目的地への遷移を追加

遷移したい場所に直接以下を追加

findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)

navigation_09
5. Activityへの遷移は上記の<fragment>と同様に、<activity>に変更
navigation_010
6. 複数のnav graphを使用する場合、ネストまたはincludeを使用

直接新しいnavigationを追加する方法:

navigation_011

新しいnav graph xmlを追加後

includeを使用して導入する方法:

navigation_012

Navigation 開発事例 - dialog fragment

dialog fragmentからの遷移

上記と同様にnav graphに直接dialogタグを追加

作成したDialogFragmentを導入すれば使用可能

(id = 名前, name = fragmentのパス, label = 表示メッセージまたはタグ, tools:layout = 表示するlayout xmlリソース)

navigation_013

Navigation 開発事例 - 変数の受け渡し

argumentを追加

同様にnav graphに直接argumentを追加

これにより、渡す変数をデフォルトで設定可能 (argType = 変数の型, defaultValue = デフォルト値)

navigation_014
コードで変数を渡す
a. 上記のxml方式を使用せずにデフォルト値を設定する場合

以下の2つのコードで直接変数を渡すことができます

b. xml方式でデフォルト値を設定している場合

以下のコードで変数を直接受け取ることができます

navigationがサポートする変数の型
navigation_020

Navigation 開発事例 - アニメーション

直接設定できる遷移アニメーションのサポート
enterAnim, exitAnim, popEnterAnim, popExitAnimを設定することで、簡単に遷移アニメーションをデフォルト設定できます
Activityにポップアップアニメーションを追加するサポート
以下のコードを使用すると、navigation内蔵のactivity離脱アニメーションを使用できます

Navigation 開発事例 - multiple back stacksのサポート

複数のback stackを処理する方法のサポート
Navigationが提供するAPIを使用して関連するビューを関連付けることで

複数のback stackの遷移問題を処理できます

例えば、setupWithNavControllerとbottom navigation viewを関連付ける

setupActionBarWithNavControllerとaction barを関連付ける

Navigation 開発事例 - popUpToおよびpopUpToInclusive

popUpToを使用して目的地ページに遷移する際、そのページのstack上のすべてのページを削除する
popUpToInclusiveを使用して、最上層の同じページを削除する

この図は、一般的な遷移ロジックを説明しています

navigation_015

フラグメントは順番に遷移します 1 -> 2 -> 3 最後に3から1に戻ります

そして再び 1 -> 2 -> 3 に遷移して1に戻ります

この時、back stack内のフラグメントの順序は[1,2,3,1,2,3,1]です

目的のフラグメント以上の内容がstack内に残らないようにするには、xmlのaction内に

popUpToおよびpopUpToInclusiveを追加します

これにより、次回目的地のフラグメントに遷移する際に、その上のstackインスタンスがクリアされます

実際の例を見てみると、追加前
実際の例を見てみると、追加後

Navigation 開発事例 - NavOptions

NavOptions を使って NavController を設定する

同様に、navigation も対応するビルダーを提供しており、上記の機能を設定できます。NavOptions の例:

val options = NavOptions.Builder()
    .set....
    .build()

最後に遷移時に渡す

findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment,null, options)
設定可能な項目は以下の通りです:
navigation_018

Navigation 参考資料

Navigation Sample code