I came across a frustrating glitch in my app.
I have a FragmentTabHost in my Activity. This tab host is hosting 5 fragments, each of these getting rendered correctly.
Now, the trick is that when I rotate the screen, sometimes the fragment is not being rendered. The tab widget is still being rendered and is clickable, but the view corresponding to that fragment is not displayed.
Here is an example below.
Note that I put a red background on my realtabcontent FrameLayout:
Rotating the screen: randomly the screen becomes partially empty

Switching to other tabs executes the OnCreate/OnCreateView of the relevant fragment, but nothing is displayed

Switching back to the first screen does not even show the button of the Fragment anymore

Note that: - the first time I rotate, there is still a button showing up (it belongs to the fragment that should be rendered). - once the bug is triggered, I can switch to other tabs. The other tabs are loaded correctly (notice the action bar changing), but nothing is rendered in the FrameLayout - If I go back to the first tab, the button that was still being displayed is not even rendered anymore
Notice also a detail: the reddot of the tab disappears, even though the code that set the reddot is correctly executed. It's as if the tab host is not responding to the drawing requests.
Here is the code in charge of displaying the reddot:
public void showReddotForTab(int tabIndx, Boolean showFlag){
try {
if (tabIndx < mTabHost.getTabWidget().getTabCount()) {
RelativeLayout tabRootView = (RelativeLayout) mTabHost.getTabWidget().getChildTabViewAt(tabIndx);
WhovaNotificationBadge notifBadge = tabRootView.findViewById(R.id.notif_badge);
if (showFlag) {
notifBadge.setVisibility(View.VISIBLE);
notifBadge.setLabel(null);
}
else {
notifBadge.setVisibility(View.GONE);
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
Here is the layout of the activity containing the FragmentTabHost
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp" />
<FrameLayout
android:id="@+id/realtabcontent"
android:background="@color/red"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="2px"
android:background="@color/separate_gray"/>
<TabWidget
android:id="@android:id/tabs"
android:orientation="horizontal"
android:background="@color/new_whova_tab_bg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="6dp"
android:layout_weight="0"/>
</LinearLayout>
</androidx.fragment.app.FragmentTabHost>
<TextView
android:id="@+id/text_network"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="40dp"
android:layout_alignParentTop="true"
android:background="@color/orange"
android:text="@string/network_off_indicator_msg"
android:visibility="gone"
android:textColor="@color/white"
android:gravity="center"/>
</RelativeLayout>
Here is the code setting up the tabhost
mTabHost = findViewById(android.R.id.tabhost);
mTabHost.setOnTabChangedListener(tabId -> {
...
})
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.getTabWidget().setDividerDrawable(null);
//! simplified below, but the code is simlar to it
//! spec is basically TabHost.TabSpec spec = mTabHost.newTabSpec("someID").setImageResource(...).setIndicator(...).setContent(tag -> findViewById(R.id.realtabcontent));
mTabHost.addTab(spec, FragmentXXXX.class, fragmentBundleXXXX);
mTabHost.addTab(spec, FragmentXXXX.class, fragmentBundleXXXX);
mTabHost.addTab(spec, FragmentXXXX.class, fragmentBundleXXXX);
mTabHost.addTab(spec, FragmentXXXX.class, fragmentBundleXXXX);
mTabHost.addTab(spec, FragmentXXXX.class, fragmentBundleXXXX);

Found how to solve it, but I have no idea what is the reason.
My actionbar is a toolbar containing an
AppCompatSpinner. The spinner is only used for the tab showed in the pictures and hassetOnItemSelectedListenerset.When rotating the screen, the listener is called (not sure why, because the initial selection is done before setting the listener and not selection occurred afterwhile.
Either way, sometimes when this listener is called, the data loaded from DB is still processing in the background. The weird thing being that once it is done, we refresh the UI but it stays blank and the other tabs are affected. I suspect that there is something wrong in the way the listener is called and it blocks the processing of other UI events, but not sure.
When I set the listener within a post, the problem disappear