Search code examples
androidandroid-navigationandroid-navigation-graphandroid-safe-args

Why can't I get null as an argument when switching screens in navigation?


I use navigation and SafeArgs to switch screens and pass data.

When data is selected on screen A, data is transmitted at the same time as screen switching.

However, there are times when screen A switches to screen B without any action.

I decided to send null in this case.

But I keep getting the following error:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.lightweight, PID: 9555
    java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130) 
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at androidx.navigation.NavArgsLazy.getValue(NavArgsLazy.kt:54)
        at androidx.navigation.NavArgsLazy.getValue(NavArgsLazy.kt:35)
        at com.example.lightweight.fragment.WriteRoutineFragment.getArgs(WriteRoutineFragment.kt:20)
        at com.example.lightweight.fragment.WriteRoutineFragment.onViewCreated(WriteRoutineFragment.kt:44)
        at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2985)

navigation.xml

<fragment
        android:id="@+id/writeRoutine"
        android:name="com.example.lightweight.fragment.WriteRoutineFragment"
        android:label="fragment_write_routine"
        tools:layout="@layout/fragment_write_routine" >
        <action
            android:id="@+id/action_writeRoutineFragment_to_workoutListTabFragment"
            app:destination="@id/workoutListTabFragment" />
        <argument
            android:name="workout"
            app:argType="string"
            app:nullable="true" />
</fragment>

In Adapter

inner class ViewHolder(itemView: View, context: Context) : RecyclerView.ViewHolder(itemView) {
        private val tv: TextView = itemView.findViewById(R.id.workout)

        init {
            tv.setOnClickListener { view ->
                val workout = tv.text.toString()
                val action: NavDirections = WorkoutListTabFragmentDirections.actionWorkoutListTabToWriteRoutine(workout)
                view.findNavController().navigate(action)
            }
        }

        fun bind(item: String) {
            tv.text = item
        }
    }

what's the reason?


Solution

  • You should add defaultValue of the workaround argument. Here because you have set app:nullable="true", you should set android:defaultValue="@null".

    Modify the way you create workaround argument as follows:

    <argument
       android:name="workout"
       app:argType="string"
       android:defaultValue="@null"
       app:nullable="true" />
    

    More information: Supported argument types - Navigation