Fragments destroyed / recreated with Jetpack's Android Navigation components
android
android-fragments
android-jetpack
android-architecture-navigation
android-jetpack-navigation
Ian Lake from google replied me that we can store the view in a variable and instead of inflating a new layout, just return the instance of pre-stored view on onCreateView()
Source: https://twitter.com/ianhlake/status/1103522856535638016
Leakcanary may show this as leak but its false positive..
android
android-fragments
android-jetpack
android-architecture-navigation
android-jetpack-navigation
You can have a persistent view for your fragment through below implementation
BaseFragment
open class BaseFragment : Fragment(){ var hasInitializedRootView = false private var rootView: View? = null fun getPersistentView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?, layout: Int): View? { if (rootView == null) { // Inflate the layout for this fragment rootView = inflater?.inflate(layout,container,false) } else { // Do not inflate the layout again. // The returned View of onCreateView will be added into the fragment. // However it is not allowed to be added twice even if the parent is same. // So we must remove rootView from the existing parent view group // (it will be added back). (rootView?.getParent() as? ViewGroup)?.removeView(rootView) } return rootView } }
MainFragment
class MainFragment : BaseFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return getPersistentView(inflater, container, savedInstanceState, R.layout.content_main) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) if (!hasInitializedRootView) { hasInitializedRootView = true setListeners() loadViews() } }}
android
android-fragments
android-jetpack
android-architecture-navigation
android-jetpack-navigation
I tried like this, and it works for me.
- Init
ViewModel
bynavGraphViewModels
(Live on Navigation scope) - Store any to-restore state in
ViewModel
// fragment.ktprivate val vm by navGraphViewModels<VM>(R.id.nav_graph) { vmFactory }override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // Restore state vm.state?.let { (recycler.layoutManager as GridLayoutManager).onRestoreInstanceState(it) }}override fun onPause() { super.onPause() // Store state vm.state = (recycler.layoutManager as GridLayoutManager).onSaveInstanceState()}// vm.ktvar state:Parcelable? = null