How to get reference to a ViewModel

I have a problem. I use the Navigation Framework and one of the screens manually sets child fragment. Most of the time there is portrait orientation, but there is the case where it goes into full screen and unlocks rotation. When rotation occurs previous fragment still exists and tries to do its onDestroy() function which leads to the crash because ViewModel still not initialized.

I think I did the wrong way (obviously).

This one leads to the crush (child fragment which directly set by the parent fragment):

private val vm: PlayCardsVm by lazy {
        (parentFragmentManager.findFragmentById(R.id.nav_host_fragment)
                as? PlayCardsFragment)?.vm ?: throw IllegalStateException()
    }

Previously I tried to use parentFragment as LifecycleOwner to obtain ViewModel. But it didn't work. This function from the parent fragment which manages child fragments:

private fun onCardPage(cardPage: CardPage?) {
        if (cardPage != null) {
            parentFragmentManager.beginTransaction()
                .replace(R.id.card_container, CardFragment.getInstance(cardPage), "tag")
                .commit()
            placeholder.isVisible = false
        } else {
            parentFragmentManager.findFragmentByTag("tag")?.let {
                parentFragmentManager.beginTransaction()
                    .remove(it)
                    .commit()
            }
            placeholder.isVisible = true
        }
    }

I thought that there childFragmentManager must be used, but It also didn't work, and I turned to use parent one instead. But I still need ViewModel when onDestroy has occurred in the child fragment.

Please help me.

Edit: Inthe child fragment:

override fun onDestroy() {
        super.onDestroy()
        vm.stopAudio()
    }

1 answer

  • answered 2020-02-16 12:39 Thunder

    Okay so you are not adding null check here. you can do this -

    override fun onDestroy() {
            super.onDestroy()
            vm?.stopAudio()
        }
    

    Just add a null check before calling stopAudio() method. It will avoid your crash.