📱

[Android]Navigation + SafeArgs

2022/06/20に公開

前提

  • Navigationの遷移がわかっていること
  • FirstFragmnetからSecondFragmentに遷移する画面を用意する

実現すること

FirstFragmentのeditTextに入力した内容をSecondFragmentに表示させる

依存関係

pluginsの中で

build.gradle(app)
id 'androidx.navigation.safeargs.kotlin'

dependenciesの中で

build.gradle(app)
def nav_version = "2.4.2"
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

pluginsより上に

build.gradle(project)
buildscript {
    repositories {
        google()
    }
    dependencies {
        def nav_version = "2.4.2"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}
navigation.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/navigation"
    app:startDestination="@id/firstFragment">

    <fragment
        android:id="@+id/firstFragment"
        android:name="com.samples.navigationpractice.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"
        android:name="com.samples.navigationpractice.SecondFragment"
        android:label="fragment_second"
        tools:layout="@layout/fragment_second" >
        <action
            android:id="@+id/action_secondFragment_to_firstFragment"
            app:destination="@id/firstFragment" />
        <argument
            android:name="text"
            app:argType="string" />
    </fragment>
</navigation>

作成したnavigationGraphのパラメータを受け取りたいFragmentタグの中で下記追加

<argument
android:name="text"
app:argType="string" />

nameは受け取る時に識別するやつ
argTypeは基本的な型、配列、enumをサポートしているみたい

FirstFragmentでSafeArgsを渡し、遷移処理追加

FirstFragment
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val btn = view.findViewById<Button>(R.id.button)

        btn.setOnClickListener {
            val editText = view.findViewById<EditText>(R.id.editText).text
      findNavController().navigate(FirstFragmentDirections.actionFirstFragmentToSecondFragment(editText.toString()))
        }
    }

このコードを書く前にビルドしておく
findNavControllerのnavigateを呼び出しの引数にFirstFragmentDirections.actionFirstFragmentToSecondFragmentを入れる
directionsは自動生成されるのでそのための事前ビルド
actionFirstFragmentToSecondFragmentの引数に渡したいパラメータを渡す

SecondFragmentでSafeArgsを受け取る

SecondFragment
class SecondFragment : Fragment() {
    private val args: SecondFragmentArgs by navArgs()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_second, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val textView = view.findViewById<TextView>(R.id.textView)
        textView.text = args.text
    }
}

まずトップレベルで受け取るパラメータを定義する

private val args: SecondFragmentArgs by navArgs()

args.~でアクセスできるようになる。
そしてここではtextViewに受け取った値を表示するので

textView.text = args.text

Discussion