OnBackPressedCallback 内的 NavController 出现问题

Trouble with NavController inside OnBackPressedCallback

我在 OnBackPressedCallback 中收到 does not have a NavController set 错误。这是代码

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

    fragmentView = inflater.inflate(R.layout.patient_info_fragment, container, false)

    if(Utils.connectedToInternet()){
        fragmentView.pastScreeningsButton.visibility = View.GONE
    }

    requireActivity().onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
                Navigation.findNavController(fragmentView).navigate(R.id.action_patientInfoFragment_to_patientsList)
        }
    })
    setHasOptionsMenu(true)


    return fragmentView
}

当我回到实现它的片段时,我才收到这个错误。

我在主页片段中有 android:name="androidx.navigation.fragment.NavHostFragment"

澄清一下,我正在使用导航控制器围绕我的应用程序进行所有导航,它工作得很好。我只在这个 OnBackPressedCallback 中得到这个错误,并且只有当用户导航回到实现它的片段时。

如果您需要查看我的更多代码,请告诉我。

您可能 运行 遇到片段旧实例泄漏的问题。此外,将创建的视图存储在另一个变量(如 fragmentView)中也不是一个好习惯。总而言之,您的 onCreateView 实施做了太多与其目的无关的事情。

我建议将功能拆分为相关的 life-cycle 方法并直接在回调中使用 fragment.view。为了避免 运行 出现未附加视图的问题,您可以使用 life-cycle.

绑定和取消绑定回调
class PatientInfoFragment: Fragment() {

    private val callback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            Navigation.findNavController(view).navigate(R.id.action_patientInfoFragment_to_patientsList)
        }
    }

    override fun onCreate(
        savedInstanceState: Bundle?
    ) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View = inflater.inflate(R.layout.patient_info_fragment, container, false)

    override fun onViewCreated(
        view: View,
        savedInstanceState: Bundle?
    ) {
        if(Utils.connectedToInternet()){
            view.pastScreeningsButton.visibility = View.GONE
        }
    }

    override fun onStart() {
        super.onStart()
        requireActivity().onBackPressedDispatcher.addCallback(callback)
    }

    override fun onStop() {
        callback.remove()
        super.onStop()
    }
}

回调 life-cycle 绑定可以与片段绑定,作为生命周期所有者调用另一个 addCallback(LifecycleOwner, OnBackPressedCallback)

此外,您可以查看 Android KTX and Kotlin Android Extensions 以简化您的实施。

将您的代码移至 onViewCreated 并传递覆盖方法提供的 view

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        requireActivity().onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
                Navigation.findNavController(view).navigate(R.id.action_patientInfoFragment_to_patientsList)
        }
    })
    }

如果这也不起作用,请将 .navigate() 替换为 popBastack(R.id.framgment_where_you_want to go, false),以防您之前的片段留在 backStack