流暢なAndroidアプリの遷移体験を実現!KotlinでNavigationを使って、アプリの遷移問題を一気に解決!
Androidアプリケーション内の異なるフラグメント間のナビゲーションを簡単に処理する方法を提供します。
以下の例は
プロジェクトにnavigationを導入し
遷移を設定する例です
プロジェクトが完了したときに
全体の遷移ロジックが一目でわかります
関連するライブラリをbuild.gradleに追加します
注意:「Navigation」コンポーネントはAndroid Studio 3.3以上のバージョンが必要です
Android Studioを使用して
プロジェクトディレクトリ内のresフォルダを右クリック > New > Android Resource FileでNavigation xmlを新規作成します。
また、手動で追加したい場合は、resフォルダ内にnavigationフォルダを作成し、その中にnav_graph.xmlを新規作成します
フラグメントを追加
id = 名前を指定
name = フラグメントのパス
label = メッセージやタグのようなもの
tools:layout = プレビュー表示するレイアウトのxmlリソース
startDestinationを追加
例:app:startDestination="@id/landingFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/navigation_main"(オプション、追加するとIDEでプレビュー可能)
app:defaultNavHost="true"
fragment内にactionを追加
追加後、destinationを設定
例:app:destination="@id/signInFragment"
(actionを外に書くと全域での遷移も可能)
遷移したい場所に直接以下を追加
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
直接新しいnavigationを追加する方法:
新しいnav graph xmlを追加後
includeを使用して導入する方法:
上記と同様にnav graphに直接dialogタグを追加
作成したDialogFragmentを導入すれば使用可能
(id = 名前, name = fragmentのパス, label = 表示メッセージまたはタグ, tools:layout = 表示するlayout xmlリソース)
同様にnav graphに直接argumentを追加
これにより、渡す変数をデフォルトで設定可能
(argType = 変数の型, defaultValue = デフォルト値)
a. 上記のxml方式を使用せずにデフォルト値を設定する場合
以下の2つのコードで直接変数を渡すことができます
b. xml方式でデフォルト値を設定している場合
以下のコードで変数を直接受け取ることができます
enterAnim, exitAnim, popEnterAnim, popExitAnimを設定することで、簡単に遷移アニメーションをデフォルト設定できます
以下のコードを使用すると、navigation内蔵のactivity離脱アニメーションを使用できます
Navigationが提供するAPIを使用して関連するビューを関連付けることで
複数のback stackの遷移問題を処理できます
例えば、setupWithNavControllerとbottom navigation viewを関連付ける
setupActionBarWithNavControllerとaction barを関連付ける
この図は、一般的な遷移ロジックを説明しています
フラグメントは順番に遷移します 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 の例:
val options = NavOptions.Builder()
.set....
.build()
最後に遷移時に渡す
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment,null, options)