I'm working on a TabHost whose tabs have associated a Fragment (each tab a different one). Each of those Fragments have inside an instance of another Fragment which is a login bar that has two states: Logged in or not.
Logged out example

Logged in example

In layout terms, each of these states have associated a View (a TextView for the non-logged-in case and a LinearLayout for the logged-in case), so if one of them is VISIBLE, the other one is GONE. As per the tab content, this is an example of the code of one of them (firsttab.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.android.gms.ads"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0000FF"
android:orientation="vertical">
<!-- That's the login bar -->
<fragment
android:id="@+id/firsttab_loginrow"
class="com.mydomain.myproject.LoginRowFragment"
android:tag="1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/firsttab_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout>
The inner Fragment (com.mydomain.myproject.LoginRowFragment) is defined this way:
<!-- If the user is not logged in -->
<TextView
android:id="@+id/identification_nologin"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="#FFFFFF" />
<!-- if the user is logged in -->
<LinearLayout
android:id="@+id/identification_didlogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
...
</LinearLayout>
A general schema would be something like this:

The problem comes when I'm handling the tab change event by either attach()ing or detach()ing the correspondent parent Fragment (in this case, firsttab.xml). Previously to attaching/detaching the parent, I try detach()ing the login Fragment (the inner one), but it doesn't fire the onDetach() callback. The same happens when attach()ing. The weird thing is that if I replace .detach() with .remove(), it works just fine.
@Override
public void onTabChanged(final String tag) {
final TabInfo newTab = mTabInfo.get(tag);
if (lastTab != newTab) {
final FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
if ((lastTab != null) && (lastTab.getFragment() != null)) {
// This is where it fails detaching. tabInfo is just a structure where I store some data
// about the tabs to handle them. If I use remove() instead of the next detach() on loginFrag,
// the onAttach()/onDetach() callbacks are not called. I'm quite sure everything is ok, loginFrag
// is not null, it's actually the Fragment that should be detached, etc.
final Fragment loginFrag = (Fragment) lastTab.getFragment().getActivity().getSupportFragmentManager().findFragmentById(lastTab.getLoginFragId());
ft.detach(loginFrag);
ft.detach(lastTab.getFragment());
}
if (newTab != null) {
if (newTab.getFragment() == null) {
final TabFragmentInflater tabInf = new TabFragmentInflater();
newTab.setFragment(Fragment.instantiate(this, tabInf.getClass().getName(), newTab.getArgs()));
ft.add(R.id.realtabcontent, newTab.getFragment(), newTab.getTag());
}
else
ft.attach(newTab.getFragment());
}
ft.commit();
this.getSupportFragmentManager().executePendingTransactions();
lastTab = newTab;
}
}
So the question is the following:
Why onAttach()/onDetach() callbacks are not fired in the LoginRowFragment class when using .attach() or .detach() on them, but get fired if I use .add() or .remove() respectively?