〈kotlin〉Navigation② SafeArgs
Android studioでkotlinを使ってAndroidアプリ作成の勉強中。
画面遷移の設定に使用するNavigationコンポーネントのSafe Argsについて。
デスティネーション間を移動する際は、Safe Args Gradle プラグインの使用が推奨されている。
Safe Argsによってデスティネーション間でタイプセーフなナビゲーションと引数の受け渡しができる。
準備
//プロジェクトレベルのgradle buildscript { dependencies { classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.4.1" } } //アプリレベルのgradle plugins { id "androidx.navigation.safeargs.kotlin" }
Safe Argsを使用した画面遷移の設定
ナビゲーショングラフ
例としてfirstFragmentからsecondFragmentへ遷移するナビゲーショングラフを以下のように定義する。
<navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_graph" app:startDestination="@id/firstFragment"> <fragment android:id="@+id/firstFragment" android:name="com.example.sampleApp.firstFragment" android:label="fragment_first" tools:layout="@layout/fragment_first" > <action android:id="@+id/action_firstFragment_to_secondFragment" app:destination="@id/secondFragment" /> </fragment> <fragment android:id="@+id/secondFragment" ... </fragment> </navigation>
Safe Argsによって作成されるクラスとメソッド
Safe Argsが有効になっていると、
アクションの発生元となる送信側デスティネーションごとにクラスとメソッドを自動生成する。
(生成されていなければRebuildする。)
上記のナビゲーショングラフ(firstFragment→secondFragment)では
送信側のfragment名を使用してFirstFragmentDirectionsクラスが生成され、
その中にactionFirstFragmentToSecondFragment()メソッドを持つ。
このメソッドはNavDirections オブジェクトを返し、
NavDirections オブジェクトはnavigate()メソッドに直接渡すことができる。
画面遷移
actionにNavDirectionsオブジェクトを取得し、navigate()メソッドに渡すことで画面遷移を設定できる。
binding.button.setOnClickListener{ val action = FirstFragmentDirections.actionFirstFragmentToSecondFragment() this.findNavController().navigate(action) }
Safe Argsを使用した引数の受け渡し
ナビゲーショングラフ
例としてfirstFragmentからsecondFragmentに遷移する際、
String型の変数dataを受け渡すことにする。
受け渡す引数は受け取り側のFragmentのargumentタグに定義する。
<navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_graph" app:startDestination="@id/firstFragment"> <fragment android:id="@+id/firstFragment" android:name="com.example.sampleApp.firstFragment" android:label="fragment_first" tools:layout="@layout/fragment_first" > <action android:id="@+id/action_firstFragment_to_secondFragment" app:destination="@id/secondFragment" /> </fragment> <fragment android:id="@+id/secondFragment" ... <argument android:name="data" app:argType="string"/> </fragment> </navigation>
SecondFragmentにargumentを設定すると、
SecondFragmentArgsというクラスが生成される。
送信側
FirstFragment側のactionFirstFragmentToSecondFragment()の引数に渡すデータを入れる。
val sampleData = "sample" binding.button.setOnClickListener{ val action = FirstFragmentDirections.actionFirstFragmentToSecondFragment(sampleData) this.findNavController().navigate(action) }
受信側
SecondFragmentでは、by navArgs()プロパティデリゲートを使用して引数にアクセスする。
val args: SecondFragmentArgs by navArgs() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val tv: TextView = view.findViewById(R.id.textView) val sampleData = args.data //ナビゲーショングラフに記述したargument nameを使用してアクセス //args.dataにFirstFragmentで渡したsampleDataが格納されている tv.text = sampleData.toString() }
https://developer.android.com/guide/navigation/navigation-pass-data?hl=ja#Safe-args