OnBackPressedCallback 中的 NavController 出现问题

Drk*_*Str 0 android kotlin android-architecture-components android-navigation-editor

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

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

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

android:name="androidx.navigation.fragment.NavHostFragment"在家庭片段中。

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

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

tyn*_*ynn 5

You might run into an issue with leaks of old instances of your fragment. Also it's not a good practice to store the created view within another variable like fragmentView. All in all your onCreateView implementation is doing too many things unrelated to its purpose.

I'd suggest to split up the functionality into relevant life-cycle methods and use the fragment.view directly within your callback. To not run into an issue with unattached views, you then bind and unbind the callback with the 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()
    }
}
Run Code Online (Sandbox Code Playgroud)

The callback life-cycle binding can be bound with the fragment as lifecycle owner calling the other addCallback(LifecycleOwner, OnBackPressedCallback).

Additionally you could have a look into Android KTX and Kotlin Android Extensions to simplify your implementation.