android - 当我从一个 fragment 回到另一个 fragment 时,我的观察者总是开火

标签 android android-fragments kotlin android-viewmodel android-architecture-navigation

我正在使用导航组件,我有 Fragment AFragment B,从 Fragment A 我发送一个对象到 带有安全参数的 fragment B 并导航到它。

override fun onSelectableItemClick(position:Int,product:Product) {
        val action = StoreFragmentDirections.actionNavigationStoreToOptionsSelectFragment(product,position)
        findNavController().navigate(action)
    }

现在,在我的 Fragment B 中进行一些逻辑处理后,我想再次将该数据传送到我使用的 Fragment A

  btn_add_to_cart.setOnClickListener {button ->     
 findNavController().previousBackStackEntry?.savedStateHandle?.set("optionList",Pair(result,product_position))
                findNavController().popBackStack()
            }

然后在 fragment A中,我用

获取了这些数据
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<Pair<MutableList<ProductOptions>,Int>>("optionList")
            ?.observe(viewLifecycleOwner, Observer {
                storeAdapter.updateProductOptions(it.second,it.first)
            })

现在,这工作正常,但是如果我从 Fragment A 转到 Fragment B 并按下后退按钮,上面的观察器会再次触发复制我当前的数据,当我只按下 Fragment B 中的 btn_add_to_cart 按钮时,有没有一种方法可以触发这个观察者?

最佳答案

你使用这个扩展:

fun <T> Fragment.getResult(key: String = "key") =
    findNavController().currentBackStackEntry?.savedStateHandle?.get<T>(key)


fun <T> Fragment.getResultLiveData(key: String = "key"): MutableLiveData<T>? {

    viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event ->
        if (event == Lifecycle.Event.ON_DESTROY) {
            findNavController().previousBackStackEntry?.savedStateHandle?.remove<T>(key)
        }
    })

    return findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<T>(key)
}

fun <T> Fragment.setResult(key: String = "key", result: T) {
    findNavController().previousBackStackEntry?.savedStateHandle?.set(key, result)
}

例子:

fragment A -> fragment B

Fragment B需要设置TestModel.class的结果

ResultTestModel.class

data class ResultTestModel(val id:String?, val name:String?)

fragment A:

 override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
    // ...

    getNavigationResultLiveData<PassengerFragmentResultNavigationModel>(
           "UNIQUE_KEY")?.observe(viewLifecycleOwner) { result ->
           Log.i("-->","${result.id} and ${result.name}")
    }

    //...
}

fragment B:设置数据并调用popBackStack。

ResultTestModel(id = "xyz", name = "Rasoul")
setNavigationResult(key = "UNIQUE_KEY", result = resultNavigation)
findNavController().popBackStack()

关于android - 当我从一个 fragment 回到另一个 fragment 时,我的观察者总是开火,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62311797/

相关文章:

android - 如何为 Galaxy S3 和 Nexus 7 创建不同的布局?

java - 我应该如何处理服务器超时和对 Android 应用程序中的 http 帖子的错误代码响应?

android - 为什么 Fragment 隐藏时 Fragment 中的 SurfaceView 仍然可见?

android - 切换 android map fragment -- 崩溃

android - 传递结果失败 ResultInfo 继续抛出

android - 无法透明位图图像的像素

java - 警报对话框内的微调器和按钮 onClick 返回 NullPointerException

安卓设置界面

Android:快速双击与导航组件相关的任何 View 会使应用程序崩溃

android - Android Room强制通过自动增量值重写属性