OK, I finally figured this out:
As suggested above, first I changed the creation of the fragment, which will be executed programmatically, and whether they added it to the manager of the child fragments, for example:
public override View OnCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstance) { var view = inflater.Inflate(Resource.Layout.MyView, viewGroup, false);
As expected, every time I switch tabs, an additional instance of Lhs / RhsFragment will be created, but I noticed that the old LHs / RhsFragment OnCreateView will also be called. Therefore, after each tab switch in OnCreateView there will be another call. Tab switching 10 times = 11 OnCreateView calls. This is obviously wrong.
After looking at the source code for FragmentTabHost, I can see that it just detaches and reattaches a fragment of the contents of the tab when switching tabs. It seems that the parent Fragment ChildFragmentManager supports child fragments and automatically recreates their views when the parent fragment is reattached.
So, I moved the creation of fragments to OnCreate and only if we do not boot from the saved state:
public override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); if (savedInstanceState == null) { var tx = ChildFragmentManager.BeginTransaction(); tx.Add(Resource.Id.lhs_fragment_frame, new LhsFragment()); tx.Add(Resource.Id.rhs_fragment_frame, new RhsFragment()); tx.Commit(); } } public override View OnCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstance) {
This fixed the creation of additional views and switching tabs, mostly working now.
The next question is saving and restoring the state of a view. In child fragments, I need to save and restore the selected item. I originally had something like this (this is a child fragment of OnCreateView)
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance) { var view = inflater.Inflate(Resource.Layout.CentresList, container, false);
The problem is that on the tab, the host does not call OnSaveInstanceState when switching tabs. Rather, the child fragment is kept alive, and the _selection variable can simply be left alone.
So, I moved the selection control code to OnCreate:
public override void OnCreate(Bundle savedInstance) { base.OnCreate(savedInstance); if (savedInstance != null) {
Now everything works fine, both when switching tabs, and when changing orientation.