在导航组件中的片段之间传递数据很容易。假设从A
到B
,您只需将arguments
设置为SafeArgs
就可以了。
但是,当将数据从B
传递回A
时,它变得棘手。
根据documentation,我们可以使用效果很好的SharedViewModel
。但是,我正在寻找将数据从A
返回到B
的更好方法。
使用SharedViewModel
的问题是,您必须为需要传递数据的每个片段对创建SharedViewModel
。
有什么建议吗?如果您可以考虑使用任何注释处理方法,欢迎您提出建议。
答案 0 :(得分:1)
如果您不想使用SharedViewModel
的方式,则可以采用下一种方法:
1-为您的Details Fragment
定义一个委托人。 (该代表必须实施Serializable
或Parcelable
:
interface DetailsFragmentDelegate: Serializable {
fun onSomething1(someData1: SomeData1)
fun onSomething2(someData2: SomeData2)
}
2- 将委托添加到Details Fragment
nav_graph.xml
自变量中
在您的Details Fragment
导航到其目的地时, 3- 将委托人传递到您的Base Fragment
:
findNavController().navigate(
BaseFragmentDirections.actionBaseFragmentToDetailsFragment(
object: DetailsFragmentDelegate {
// override delegate methods
}
)
)
4- 在Details Fragment
中获取委托人参数并将数据传递回您需要的位置:
....
delegate.onSomething1(data1)
....
delegate.onSomething2(data2)
....
我不确定是否有更好的方法,但是它正在起作用...
答案 1 :(得分:0)
我为此使用了回调接口。所以我用一些方法创建了一个接口。我实现了该接口“ A”,然后从“ B”调用。非常简单,效果很好。
答案 2 :(得分:0)
您不需要为每个Fragment对创建一个ViewModel。我正在做的是每个片段创建一个ViewModel。每个ViewModel都有一个名为mailBox的map [Class [Fragment],Any]。
每个Fragment都会定义一个FragmentResult类型,每个Fragment类都不同。
在子片段 onBackPressedHandler 中,在弹出窗口之前,从Activity中获取父ViewModel并将结果放入类的邮箱中。您将需要一个ViewModel类。见下文。
父Fragment需要在启动之前将其ViewModel.class传递给子Fragment。
从堆栈弹出子级后重新启动“父级片段”时。从其ViewModel获取邮箱地图,检查是否有一个键值与预期的FragmentChild :: class相匹配。如果是这样,则强制转换为所需的类型。
父片段ViewModel需要保存谁是它启动的最后一个孩子。