如何将数据从一个片段传输到另一个片段?
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
实例=].
我正在使用 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
实例=].