我正在使用导航组件,我有片段A 和片段B ,来自片段A ,我将对象发送到片段B 带有安全参数,然后导航到它。
override fun onSelectableItemClick(position:Int,product:Product) {
val action = StoreFragmentDirections.actionNavigationStoreToOptionsSelectFragment(product,position)
findNavController().navigate(action)
}
现在,在我的片段B 中经过逻辑处理后,我想再次将数据传送到片段A ,我将使用
btn_add_to_cart.setOnClickListener {button ->
findNavController().previousBackStackEntry?.savedStateHandle?.set("optionList",Pair(result,product_position))
findNavController().popBackStack()
}
然后在片段A 中,我用
捕获了这些数据findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<Pair<MutableList<ProductOptions>,Int>>("optionList")
?.observe(viewLifecycleOwner, Observer {
storeAdapter.updateProductOptions(it.second,it.first)
})
现在,这工作正常,但是如果我从片段A 转到片段B ,然后按返回按钮,上方的观察者将再次触发复制我的当前数据,当我只按 B片段中的btn_add_to_cart
按钮时,有什么方法可以解雇该观察者吗?
答案 0 :(得分:0)
不清楚您的代码在哪里调用了最后一段代码-在 LiveData 中添加了观察者。我猜想它在方法 onResume()或 onViewStateRestored()或任何其他生命周期回调中,每当您返回到 Fragment A < / strong>来自片段B 。如果是这种情况,那么您将向 LiveData 添加一个新的观察者,并且LiveData的任何观察者都会收到当前值的即时更新。
将这段代码移动到其中一个片段的生命周期中仅被调用一次的回调方法中。
答案 1 :(得分:0)
面临同样的问题
<块引用>通过从 savedStateHandle
实时数据中删除旧数据来解决此问题
在片段 B 中:
button?.setOnClickListener {
findNavController().previousBackStackEntry?.savedStateHandle?.set(key, data)
findNavController().popBackStack()
}
在片段 A 中:
<块引用>这里是使用实时数据删除旧数据的关键remove方法,它应该在创建视图之后,就像片段的onViewCreated方法
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>(key)?.observe(viewLifecycleOwner) {
result(it)
findNavController().currentBackStackEntry?.savedStateHandle?.remove<String>(key)
}
}
更新:
我为此创建了扩展以便更好地使用
fun <T> Fragment.setBackStackData(key: String, data: T, doBack: Boolean = false) {
findNavController().previousBackStackEntry?.savedStateHandle?.set(key, data)
if (doBack)
findNavController().popBackStack()
}
fun <T> Fragment.getBackStackData(key: String, singleCall : Boolean= true , result: (T) -> (Unit)) {
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<T>(key)
?.observe(viewLifecycleOwner) {
result(it)
//if not removed then when click back without set data it will return previous data
if(singleCall) findNavController().currentBackStackEntry?.savedStateHandle?.remove<T>(key)
}
}
在fragment里面调用就像
同时在片段 B 中设置数据
var user : User = User(data) // Make sure this is parcelable or serializable
setBackStackData("key",user,true)
在片段 A 中获取数据时
getBackStackData<User>("key",true) { it ->
}
感谢This Guy