如何在 android 导航组件中传递参数名称?
How to pass argument name in android navigation component?
我正在使用导航图在片段之间导航。一切正常,但我想知道如何以优雅的方式传递参数名称。
这是我的代码片段 navSheet.xml
:
源片段操作:
<action
android:id="@+id/action_go_to_B"
app:destination="@id/id_fragment_b">
<argument
android:name="@string/fragment_b_arg_key_name"
app:argType="integer"/>
</action>
目标片段:
<fragment
android:id="@+id/id_fragment_b"
android:name="pl.asd.FragmentB"
tools:layout="@layout/fragment_b">
<argument
android:name="@string/fragment_b_arg_key_name"
app:argType="integer"/>
</fragment>
我将参数键存储在 string.xml
:
<string name="fragment_b_arg_key_name" translatable="false">arg_fragment_b</string>
最后我尝试在目标片段中获取我的参数:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
selectedId = it.getInt(getString(R.string.fragment_b_arg_key_name))
}
}
问题出在 android:name="@string/fragment_b_arg_key_name"
。
我在调试器上看到有一个不正确的包密钥。它应该是这样的:
Bundle[{arg_fragment_b=-730732511}]
但我得到:
Bundle[{@string/fragment_b_arg_key_name=-730732511}]
两个问题:
在 navSheet.xml 中使用 @string/fragment_b_arg_key_name
有什么问题所以它不是 returns @string/fragment_b_arg_key_name
的内容而是原始引用。
如何不对我在 Fragments、navSheet.xml
和其他 类 中使用的参数名称进行硬编码?如何将这些密钥存储在一个地方?
What's wrong with using a @string/fragment_b_arg_key_name in navSheet.xml so it not returns the content of @string/fragment_b_arg_key_name but raw reference.
仅仅是因为Android 导航组件不支持解析字符串的功能。 android:name 中的每个字符串都将成为包的原始 ID。您可以在 https://issuetracker.google.com/issues
中发布
但是,对此有更好的解决方案。见下文。
How to not hard-code arguments name that I use in Fragments, navSheet.xml and other classes? How to store such keys in one place?
使用安全参数
https://developer.android.com/jetpack/androidx/releases/navigation#safe_args
您可以像下面这样更改您的代码
片段A
findNavController().navigate(R.id.id_fragment_b, FragmentBArgs(id).toBundle())
片段B
private val args : FragmentBArgs by navArgs()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
selectedId = args.arg_fragment_b
}
在navSheet.xml中:
<argument
android:name="arg_fragment_b"
app:argType="integer"/>
因此,无需存储密钥,因为 safeargs 将为您生成参数,默认情况下它是不可空的。
要将参数设置为 Nullable,请使用 app:nullable="true"
我正在使用导航图在片段之间导航。一切正常,但我想知道如何以优雅的方式传递参数名称。
这是我的代码片段 navSheet.xml
:
源片段操作:
<action
android:id="@+id/action_go_to_B"
app:destination="@id/id_fragment_b">
<argument
android:name="@string/fragment_b_arg_key_name"
app:argType="integer"/>
</action>
目标片段:
<fragment
android:id="@+id/id_fragment_b"
android:name="pl.asd.FragmentB"
tools:layout="@layout/fragment_b">
<argument
android:name="@string/fragment_b_arg_key_name"
app:argType="integer"/>
</fragment>
我将参数键存储在 string.xml
:
<string name="fragment_b_arg_key_name" translatable="false">arg_fragment_b</string>
最后我尝试在目标片段中获取我的参数:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
selectedId = it.getInt(getString(R.string.fragment_b_arg_key_name))
}
}
问题出在 android:name="@string/fragment_b_arg_key_name"
。
我在调试器上看到有一个不正确的包密钥。它应该是这样的:
Bundle[{arg_fragment_b=-730732511}]
但我得到:
Bundle[{@string/fragment_b_arg_key_name=-730732511}]
两个问题:
在 navSheet.xml 中使用
@string/fragment_b_arg_key_name
有什么问题所以它不是 returns@string/fragment_b_arg_key_name
的内容而是原始引用。如何不对我在 Fragments、
navSheet.xml
和其他 类 中使用的参数名称进行硬编码?如何将这些密钥存储在一个地方?
What's wrong with using a @string/fragment_b_arg_key_name in navSheet.xml so it not returns the content of @string/fragment_b_arg_key_name but raw reference.
仅仅是因为Android 导航组件不支持解析字符串的功能。 android:name 中的每个字符串都将成为包的原始 ID。您可以在 https://issuetracker.google.com/issues
中发布但是,对此有更好的解决方案。见下文。
How to not hard-code arguments name that I use in Fragments, navSheet.xml and other classes? How to store such keys in one place?
使用安全参数 https://developer.android.com/jetpack/androidx/releases/navigation#safe_args
您可以像下面这样更改您的代码
片段A
findNavController().navigate(R.id.id_fragment_b, FragmentBArgs(id).toBundle())
片段B
private val args : FragmentBArgs by navArgs()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
selectedId = args.arg_fragment_b
}
在navSheet.xml中:
<argument
android:name="arg_fragment_b"
app:argType="integer"/>
因此,无需存储密钥,因为 safeargs 将为您生成参数,默认情况下它是不可空的。
要将参数设置为 Nullable,请使用 app:nullable="true"