OnBackPressedCallback内的NavController出现问题

时间:2019-06-18 12:59:56

标签: android kotlin android-architecture-components android-navigation-editor

我在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内并且只有当用户导航回到实现此功能的片段时,才会收到此错误。

让我知道您是否需要查看更多我的代码。

2 个答案:

答案 0 :(得分:1)

您可能会遇到碎片旧实例泄漏的问题。同样,将创建的视图存储在另一个变量fragmentView中也不是一个好习惯。您的onCreateView实施中的所有工作都与它的目的无关。

我建议将功能分解为相关的生命周期方法,并直接在回调中使用fragment.view。为了避免出现未附加视图的问题,您可以将回调与生命周期绑定和取消绑定。

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()
    }
}

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

另外,您可以查看Android KTXKotlin Android Extensions来简化实现。

答案 1 :(得分:0)

getCodes cCodes中移动代码,并传递重写方法提供的Option Explicit

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()