Navigation Component Lifecycle

Navigation component only supports fragment replacement as of now. So you won't be able to add() a fragment as you do it with Manual fragment transaction.

However, if your worry is about re-inflating the layout and re-fetching the data for the fragment, it could be easily resolved with below two methods.

Once the view is created, store it in a variable and use it whenever onCreateView() is called.

private var view: View? = null

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

    if (view == null) {
        view = inflater.inflate(R.layout.fragment_list, container, false)
                //...
    }

    return view

 }

Source: https://twitter.com/ianhlake/status/1103522856535638016

Use ViewModel with the Fragment and hold the data required as a member variable. By this way, the data is not cleared when you replace the associated fragment. The ViewModel gets cleared only on onDestroy() of the fragment, which will only happen when you destroy the parent activity. https://developer.android.com/images/topic/libraries/architecture/viewmodel-lifecycle.png


The way that we use fragments to bridge data and views has changed slightly, and in a good way, when migrating to the Navigation library. It forces us to distinguish between Fragment and View lifecycles.

Pre-navigation: observe LiveData in onCreate() using Fragment's lifecycleScope.

import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
...
import kotlinx.android.synthetic.main.old_fragment.*

class OldFragment : Fragment(R.layout.old_fragment) {
  private val vm by activityViewModels<MainViewModel>()

  override fun onCreate(savedInstanceState: Bundle?) {
    vm.getLiveData().observe(this) { data ->
      oldTextView.text = data.name
    }
  }
}

Navigation: observe LiveData in onViewCreated() using viewLifecycleOwner scope.

...

class NewFragment : Fragment() {
  private val vm by activityViewModels<MainViewModel>()

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    vm.getLiveData().observe(viewLifecycleOwner) { data ->
      oldTextView.text = data.name
    }
  }
}

Key Notes:

  1. Not all Lifecycle Owners are the same. The fragment lifecycle will not execute the observer when the view is recreated (while using Navigation library and navigating up/back).
  2. The viewLifecycleOwner cannot be accessed before the view is created.

Hopefully, this can help prevent replacement of LiveData code as developers migrate to Navigation.