Update: accepted answers to explanation questions (bug) with a workaround, but also see my Kotlin-based work attached as an answer below.
This code is in Kotlin, but I think this is the main problem of the android fragment life cycle.
I have a fragment that contains a link to another "sub-fragment"
Here is basically what I am doing:
- I have a main snippet that
retainInstance set to true - I have a field in the main fragment that will contain a link to the sub-fragment, initially this field is null
- In the main
onCreateView I check if the subfragment field is null, if so, I create an instance of the subfragment and assign it to the field - Finally, I add a sub-fragment to the container in the layout of the main fragment.
- If the field is not null, that is, we are in onCreateView due to a configuration change, I do not recreate the sub-fragment, I just try to add it to the container.
When the device rotates, I observe the onPaused() and onDestroyView() methods of the onPaused() called, but I donโt see any lifecyle methods being called on the subfragment while adding the saved link to the subfragment, the child of the container when the view of the main fragments is recreated.
The affect of the network is that I do not see the sub-fragment in the main fragment. If I comment on if (subfragment == null) and just create a new sub-fragment every time, I do see the sub-fragment in the view.
Update
The answer below indicates an error in which childFragmentManager is not saved when the configuration changes. This will ultimately violate my intended use, which was supposed to preserve the back after rotation, however I think that what I see is something else.
I added the code to the onWindowFocusChanged method, and I see something like this when I first run the application:
activity is in view fm = FragmentManager{b13b9b18 in Tab1Fragment{b13b2b98}} tab 1 fragments = [DefaultSubfragment{b13bb610
and then after rotation:
activity is in view fm = FragmentManager{b13f9c30 in Tab1Fragment{b13b2b98}} tab 1 fragments = null
here fm is a childFragmentManager, and as you can see, we still have the same instance of Tab1Fragment, but it has a new childFragmentManager, which I think is undesirable, and because of the error reported in the answer below. The fact is that I made adding a sub-fragment to this new childFragmentManger. Thus, it seems that the transaction is never executed with reference to the fragment that was saved, but is completed if I create a new fragment. (I tried calling executePendingTransactions in a new childFragmentManager)
class Tab1Fragment: Fragment() { var subfragment: DefaultSubfragment? = null override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val rootView = inflater!!.inflate(R.layout.fragment_main, container, false) if (subfragment == null ) { subfragment = DefaultSubfragment() subfragment!!.sectionLabel = "label 1" subfragment!!.buttonText = "button 1" } addRootContentToContainer(R.id.child_container, content = subfragment!!) return rootView } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) retainInstance = true } inline fun Fragment.addRootContentToContainer(containerId: Int, content: Fragment) { val transaction = childFragmentManager.beginTransaction() transaction.replace(containerId, content) transaction.commit() }