Why can't I pass an argument to fragment using navigation component when that argument has a default value?

大兔子大兔子 提交于 2021-01-29 19:20:34

问题


I am using navigation component and I don't understand why I get an error passing the argument to the method below if the argument is defined. I am using SafeArgs and I only get this error when I define a default value for this argument.

Could someone explain me why this happens and how can I solve it?

Here is a part of the code of the navigation graph.

<fragment
        android:id="@+id/sleepTrackerFragment"
        android:name="com.example.sleeptracker.fragments.sleep_tracker.SleepTrackerFragment"
        android:label="fragment_sleep_tracker"
        tools:layout="@layout/fragment_sleep_tracker" >
        <action
            android:id="@+id/action_sleepTrackerFragment_to_sleepQualityFragment"
            app:destination="@id/sleepQualityFragment" />
        <argument
            android:name="qualityLastSleep"
            app:argType="integer"
            android:defaultValue="-1" />
    </fragment>
    <fragment
        android:id="@+id/sleepQualityFragment"
        android:name="com.example.sleeptracker.fragments.sleep_quality.SleepQualityFragment"
        android:label="fragment_sleep_quality"
        tools:layout="@layout/fragment_sleep_quality" >
        <action
            android:id="@+id/action_sleepQualityFragment_to_sleepTrackerFragment"
            app:destination="@id/sleepTrackerFragment" >
        </action>
    </fragment>

回答1:


seems like what you really want is destination level argument:

Try the following:

<fragment
        android:id="@+id/sleepTrackerFragment"
        android:name="com.example.sleeptracker.fragments.sleep_tracker.SleepTrackerFragment"
        android:label="fragment_sleep_tracker"
        tools:layout="@layout/fragment_sleep_tracker" >
        <action
            android:id="@+id/action_sleepTrackerFragment_to_sleepQualityFragment"
            app:destination="@id/sleepQualityFragment" />
    </fragment>
    <fragment
        android:id="@+id/sleepQualityFragment"
        android:name="com.example.sleeptracker.fragments.sleep_quality.SleepQualityFragment"
        android:label="fragment_sleep_quality"
        tools:layout="@layout/fragment_sleep_quality" >
        <action
            android:id="@+id/action_sleepQualityFragment_to_sleepTrackerFragment"
            app:destination="@id/sleepTrackerFragment" >
            <argument
               android:name="qualityLastSleep"
               app:argType="integer"
               android:defaultValue="-1" />
        </action>
    </fragment>

You can also Ctrl+Click on actionSleepQualityFragmentToSleepTrackerFragment() to check if the generated function accepts an argument.

Do try clean and rebuild if IDE complains about argument passing

Doc link: https://developer.android.com/guide/navigation/navigation-pass-data#override_a_destination_argument_in_an_action

Let me know if this does not work for you




回答2:


As mentioned in documentation

Destination-level arguments and default values are used by all actions that navigate to the destination. If needed, you can override the default value of an argument (or set one if it doesn't already exist) by defining an argument at the action level. This argument must be of the same name and type as the argument declared in the destination.

so you have to override this value to do so you can follow any of the both solutions below

solution one

 val action =  SleepQualityFragmentDirections.actionSleepQualityFragmentToSleepTrackerFragment()
 action.qualityLastSleep = 5 // your value
 findNavController().navigate(action)

solution two

<fragment
    android:id="@+id/sleepTrackerFragment"
    android:name="com.example.sleeptracker.fragments.sleep_tracker.SleepTrackerFragment"
    android:label="fragment_sleep_tracker"
    tools:layout="@layout/fragment_sleep_tracker" >
   <argument
           android:name="qualityLastSleep"
           app:argType="integer"
           android:defaultValue="-1" />
    <action
        android:id="@+id/action_sleepTrackerFragment_to_sleepQualityFragment"
        app:destination="@id/sleepQualityFragment" />
</fragment>
<fragment
    android:id="@+id/sleepQualityFragment"
    android:name="com.example.sleeptracker.fragments.sleep_quality.SleepQualityFragment"
    android:label="fragment_sleep_quality"
    tools:layout="@layout/fragment_sleep_quality" >
    
    <action
        android:id="@+id/action_sleepQualityFragment_to_sleepTrackerFragment"
        app:destination="@id/sleepTrackerFragment" >
     <argument
           android:name="qualityLastSleep"
           app:argType="integer"
           android:defaultValue="-1" />
       
    </action>
</fragment>

and then you can call your navigation like this

findNavController().navigate(SleepQualityFragmentDirections.actionSleepQualityFragmentToSleepTrackerFragment(5))


来源:https://stackoverflow.com/questions/63058373/why-cant-i-pass-an-argument-to-fragment-using-navigation-component-when-that-ar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!