当我从一个片段返回到另一个片段时,我的观察者总是会开火

SNM*_*SNM 3 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)
    }
Run Code Online (Sandbox Code Playgroud)

现在,在我的Fragment B中进行一些逻辑之后,我想再次将该数据传递给我使用的Fragment A

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

然后在片段 A中,我用

findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<Pair<MutableList<ProductOptions>,Int>>("optionList")
            ?.observe(viewLifecycleOwner, Observer {
                storeAdapter.updateProductOptions(it.second,it.first)
            })
Run Code Online (Sandbox Code Playgroud)

现在,这工作正常,但如果我从片段 A转到片段 B并按后退按钮,上面的观察者会再次触发,复制我当前的数据,有没有办法在我只按下片段btn_add_to_cart中的按钮时触发该观察者

Ras*_*iri 5

您使用这个扩展:

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)
}
Run Code Online (Sandbox Code Playgroud)

例子:

片段A -> 片段B

片段B需要设置TestModel.class的结果

结果测试模型.class

data class ResultTestModel(val id:String?, val name:String?)
Run Code Online (Sandbox Code Playgroud)

片段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}")
    }

    //...
}
Run Code Online (Sandbox Code Playgroud)

片段B:设置数据并调用popBackStack。

ResultTestModel(id = "xyz", name = "Rasoul")
setNavigationResult(key = "UNIQUE_KEY", result = resultNavigation)
findNavController().popBackStack()
Run Code Online (Sandbox Code Playgroud)