我的项目使用SafeArgs。我已切换到其他人创建的分支,并且在构建项目时会生成编译器错误,因为即使在nav_graph中,该生成的“〜Directions”类的方法也可以返回ActionOnlyNavDirections(未将参数传递给目标片段)吵架
例如,使用以下nav_graph.xml:
<fragment
android:id="@+id/fragment_a"
android:name="com.myapp.ui.fragment.FragmentA"
android:label="Fragment A"
tools:layout="@layout/fragment_a">
<argument
android:name="userName"
android:defaultValue=" "
app:argType="string" />
<action
android:id="@+id/action_fragment_a_to_fragmentX"
app:destination="@id/fragmentX" />
<action
android:id="@+id/action_fragment_a_to_homeFragment"
app:destination="@id/homeFragment" />
<action
android:id="@+id/action_fragmentA_to_fragmentC"
app:destination="@id/fragmentC"
app:popUpTo="@id/loginFragment" />
</fragment>
<fragment
android:id="@+id/fragment_b"
android:name="com.myapp.ui.fragment.FragmentB"
android:label="Fragment B"
tools:layout="@layout/fragment_b">
<argument
android:name="from"
app:argType="com.myapp.data.local.model.ToFragmentBFrom"/>
<action
android:id="@+id/action_fragmentB_to_homeFragment"
app:destination="@id/homeFragment" />
<action
android:id="@+id/action_fragmentB_to_fragmentC"
app:destination="@id/fragmentC"
app:popUpTo="@id/homeFragment" />
</fragment>
<fragment
android:id="@+id/fragment_c"
android:name="com.myapp.fragment.fragmentC"
android:label="Fragment C"
tools:layout="@layout/fragment_c">
<argument
android:name="userName"
app:argType="string" />
</fragment>
最后我获得了以下Directions课程:
class FragmentADirections private constructor() {
private data class ActionFragmentAToFragmentC(val userName: String) : NavDirections {
override fun getActionId(): Int = R.id.action_fragmentA_to_fragmentC
override fun getArguments(): Bundle {
val result = Bundle()
result.putString("userName", this.userName)
return result
}
}
companion object {
fun actionFragmentAToFragmentX(): NavDirections =
ActionOnlyNavDirections(R.id.action_fragmentA_to_fragmentX)
fun actionFragmentAToHomeFragment(): NavDirections =
ActionOnlyNavDirections(R.id.action_fragmentA_to_homeFragment)
fun actionFragmentAToFragmentC(userName: String): NavDirections =
ActionFragmentAToFragmentC(userName)
fun actionGlobalFragmentA(userName: String = " "): NavDirections =
NavGraphDirections.actionGlobalFragmentA(userName)
}
}
和:
class FragmentBDirections private constructor() {
companion object {
fun actionFragmentBToHomeFragment(): NavDirections =
ActionOnlyNavDirections(R.id.action_fragmentA_to_homeFragment)
fun actionFragmentBToFragmentC(): NavDirections =
ActionOnlyNavDirections(R.id.action_fragmentB_to_fragmentC)
}
}
正如您所看到的,FragmentC带有一个“ userName”参数,而actionFragmentAToFragmentC则遵循此参数,而actionFragmentBToFragmentC则不这样做。 我尝试清理,手动删除构建文件夹,使缓存无效,然后重新启动,然后重新构建,但是生成的类始终看起来相同。为什么SafeArgs为一个Directions类而不是为另一个Directions类生成参数?
如何在构建时调试SafeArgs插件,以了解更多有关造成这种情况的原因?
答案 0 :(得分:0)
这听起来有些尴尬,因为生成的FragmentBDirections.class
应该自动包含FragmentC
的参数。我有时也会遇到这个问题,但是我无法告诉您为什么安全的args插件会以这种方式运行,尤其是为什么它始终不具有相似性。
要解决此问题,请在<argument>
中明确添加<action>
。
<action
android:id="@+id/action_fragmentB_to_fragmentC"
app:destination="@id/fragmentC"
app:popUpTo="@id/homeFragment" />
<argument
android:name="userName"
app:argType="String" />
</action>
可以肯定的是,这会在NavGraph中产生一些代码开销,因为您需要始终在<fragment>
和<action>
中指定参数。这并非是“最干净”的解决方案。但这始终对我有效,我仍然可以从SafeArgs中获利。
答案 1 :(得分:0)
对我来说,这是因为我的源和目标片段位于同一个 xml 文件中,但位于不同的导航元素下。在同一导航元素下移动两个片段会生成参数
我改变了这个(带有嵌套的导航元素)
<navigation
...
android:id="@+id/nav_main">
<fragment
android:id="@+id/fragment_a"
android:name="com.myapp.ui.fragment.FragmentA"
android:label="Fragment A"
tools:layout="@layout/fragment_a">
<action
android:id="@+id/action_fragment_a_to_fragment_b"
app:destination="@id/fragment_b" />
</fragment>
<navigation
...
android:id="@+id/nav_other">
<fragment
android:id="@+id/fragment_b"
android:name="com.myapp.ui.fragment.FragmentB"
android:label="Fragment B"
tools:layout="@layout/fragment_b">
<argument
android:name="from"
app:argType="com.myapp.data.local.model.ToFragmentBFrom"/>
</fragment>
</navigation>
</navigation>
为此
<navigation
...
android:id="@+id/nav_main">
<fragment
android:id="@+id/fragment_a"
android:name="com.myapp.ui.fragment.FragmentA"
android:label="Fragment A"
tools:layout="@layout/fragment_a">
<action
android:id="@+id/action_fragment_a_to_fragment_b"
app:destination="@id/fragment_b" />
</fragment>
<fragment
android:id="@+id/fragment_b"
android:name="com.myapp.ui.fragment.FragmentB"
android:label="Fragment B"
tools:layout="@layout/fragment_b">
<argument
android:name="from"
app:argType="com.myapp.data.local.model.ToFragmentBFrom"/>
</fragment>
</navigation>
在导航元素或整个图形之间导航时,似乎您可能需要双重定义参数(在目标和参数中),尽管我在 {{3 }}
答案 2 :(得分:0)
我从“safeargs”改为“safeargs.kotlin”并且它起作用了。 尽管 Docs 说“safeargs”应该适用于 Java 和 Kotlin。
plugins {
// id 'androidx.navigation.safeargs'
id 'androidx.navigation.safeargs.kotlin'
}
答案 3 :(得分:0)
FragmentA 中的默认值定义为
android:defaultValue=" "
但不在 FragmentB 中。默认情况下,导航组件不知道将什么分配给不可为空的字符串。
尝试在片段 B 中做同样的事情。