在导航中使用 TypeSafe 将多个 Agument 传递给片段

Passing Multiple Agument to fragment using TypeSafe in Navigation

我知道可以在源片段中使用 Action 传递单个参数

  override fun onClick(v: View) {
       val amountTv: EditText = view!!.findViewById(R.id.editTextAmount)
       val amount = amountTv.text.toString().toInt()
       val action = SpecifyAmountFragmentDirections.confirmationAction(amount)
       v.findNavController().navigate(action)

}

并在 android 文档

中指定的目标片段中获取它
    val args: ConfirmationFragmentArgs by navArgs()
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            val tv: TextView = view.findViewById(R.id.textViewAmount)
            val amount = args.amount
            tv.text = amount.toString()
}

请告诉我有没有办法以 TypeSafe 方式传递多个参数

是的,您可以通过在导航图中为片段定义多个参数,然后将它们传递给代码中的 action 来实现。这是一个例子:

navigation.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/navigation"
    app:startDestination="@id/firstFragment">
    <fragment
        android:id="@+id/firstFragment"
        android:name="com.example.app.FirstFragment"
        android:label="FirstFragment"
        tools:layout="@layout/fragment_first">
        <action
            android:id="@+id/action_firstFragment_to_secondFragment"
            app:destination="@id/secondFragment"
            app:enterAnim="@anim/slide_in_right"
            app:popExitAnim="@anim/slide_out_left" />
    </fragment>
    <fragment
        android:id="@+id/secondFragment"
        android:name="com.example.app.SecondFragment"
        android:label="secondFragment"
        tools:layout="@layout/fragment_second">
        <argument
            android:name="firstDataList"
            app:argType="com.example.app.domain.FirstData[]" />
        <argument
            android:name="secondDataList"
            app:argType="com.example.app.domain.SecondData[]" />

        <argument
            android:name="isOkey"
            app:argType="boolean" />
        <argument
            android:name="myString"
            app:argType="string" />
    </fragment>


</navigation>

然后在您的代码中:

你应该按原样分别传递参数navigation.xml

FirstFragment.kt

findNavController().navigate(
    FirstFragmentDirections.actionFirstFragmentToSecondFragment(
        firstDataList.toTypedArray(),
        secondDataList.toTypedArray(),
        isOkey,
        myString
    )

然后在目的地将其检索为 bundle,如下所示:

SecondFragment.kt

val args = arguments?.let {
    SecondFragmentArgs.fromBundle(
        it
    )
}
if (args != null) {
    firstDataList = args.firstDataList.toCollection(ArrayList())
    secondDataList = args.secondDataList.toCollection(ArrayList())
    isOkey = args.isOkey
    myString = args.myString

}

要传递复杂的对象,您应该制作它们 parcelable。在我的示例中,我传递了两个复杂模型列表,我将它们像这样分割:

DataModels.kt

@Parcelize
data class FirstData(var id: Int, var color: Int = 0) : Parcelable

@Parcelize
data class SecondData(var name: String, var position: ArrayList<Int>) : Parcelable