如何将数据从一个片段传输到另一个片段?

How to transfer data from one Fragment to another?

我正在使用 jetpack.navigation 架构在 Kotlin (Android Studio) 上编写应用程序。 有两个片段:第一个包含一个包含 class 个实例的列表,我将其显示在 RecyclerView 中,第二个用于 EditText(我填写客户端数据)。我还使用 Livedata 和 ViewModel。 问题是,当我转到第二个片段时,填写数据并确认,我转到第一个片段。据我了解,以下几行破坏了旧的 Fragment1,并创建了一个新的。第一个片段上的列表重置为零(尽管旋转屏幕和最小化应用程序时会保存列表)。

 val client = Clients(id,name,secondName,thirdName, address, creditCard, bankNum)
 val action = Fragment2Directions.actionFragment2ToFragment1(client)
 findNavController().navigate(action)

我找不到如何使用导航组件解决问题。我将不胜感激。

要使用 Jetpack 导航在两个片段之间传递数据,您必须使用 Safe Args

传递参数部分,如

 <fragment android:id="@+id/myFragment" >
     <argument
         android:name="myArg"
         app:argType="integer"
         android:defaultValue="0" />
 </fragment>

在顶级 gradle 文件中添加 classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"

并添加插件 apply plugin: "androidx.navigation.safeargs.kotlin" 现在像这样发送值

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)
}

并接收为

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()
}

但是 safeargs 仅适用于原始类型,因此如果您尝试传递对象,则必须解构和重建

由于您正在使用 ViewModel,我建议您使用 共享 ViewModel。它的工作方式是同一个 Activity 中的多个片段可以访问同一个 ViewModel 实例。

有一个 example on Android Developers 完全适合您的用例。它展示了如何使用共享 ViewModel 通过主从导航模式和 LiveData 来执行此操作。推荐大家看看

为什么不在这里使用安全参数:可以尝试使用安全参数来实现您想要实现的目标,但我强烈建议反对它:您将不得不以某种方式使用 Safe Args 来处理在片段之间来回传递 Client 对象(这意味着单独发送每个字段或捆绑)并且您将不得不手动更新您的 LiveData 对象 - 这违背了 LiveData 的目的。使用共享 ViewModel,您不必担心这些。无需来回发送数据,无需将 Client 对象分开或捆绑,无需手动更新 LiveData 对象 - 您只需通过 [=10] 从两个片段访问相同的 LiveData 实例=].