首页 > 解决方案 > 如何在android导航组件中传递参数名称?

问题描述

我正在使用导航图在片段之间导航。一切正常,但我想知道如何以优雅的方式传递参数名称。

这是我的代码片段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}]

两个问题:

  1. @string/fragment_b_arg_key_name在 navSheet.xml中使用 a 有什么问题,因此它不会返回@string/fragment_b_arg_key_name原始引用的内容。

  2. 如何不对我在 FragmentsnavSheet.xml和其他类中使用的参数名称进行硬编码?如何将这些密钥存储在一个地方?

标签: androidxmlandroid-resourcesandroid-architecture-navigationandroid-bundle

解决方案


在 navSheet.xml 中使用 @string/fragment_b_arg_key_name 有什么问题,因此它不会返回 @string/fragment_b_arg_key_name 的内容,而是返回原始引用。

仅仅是因为 Android Navigation 组件不支持该功能来解析字符串。放在 android:name 中的每个字符串都将成为捆绑包的原始 id。您可以在https://issuetracker.google.com/issues中发布此问题

但是,对此有更好的解决方案。见下文。

如何不对我在 Fragments、navSheet.xml 和其他类中使用的参数名称进行硬编码?如何将这些密钥存储在一个地方?

使用安全参数 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"


推荐阅读