I've got this activity, which holds a fragment. This fragment layout consists of a view pager with several fragments (two, actually).
When the view pager is created, its adapter is created, getItem
gets called and my sub fragments are created. Great.
Now when I rotate the screen, the framework handles the fragment re-creation, the adapter is created again in my onCreate
from the main fragment, but getItem
never gets called, so my adapter holds wrong references (actually nulls) instead of the two fragments.
What I have found is that the fragment manager (that is, the child fragment manager) contains an array of fragments called mActive
, which is of course not accessible from code. However there's this getFragment
method:
@Override
public Fragment getFragment(Bundle bundle, String key) {
int index = bundle.getInt(key, -1);
if (index == -1) {
return null;
}
if (index >= mActive.size()) {
throwException(new IllegalStateException("Fragement no longer exists for key "
+ key + ": index " + index));
}
Fragment f = mActive.get(index);
if (f == null) {
throwException(new IllegalStateException("Fragement no longer exists for key "
+ key + ": index " + index));
}
return f;
}
I won't comment the typo :)
This is the hack I have implemented in order to update the references to my fragments, in my adapter constructor:
// fm holds a reference to a FragmentManager
Bundle hack = new Bundle();
try {
for (int i = 0; i < mFragments.length; i++) {
hack.putInt("hack", i);
mFragments[i] = fm.getFragment(hack, "hack");
}
} catch (Exception e) {
// No need to fail here, likely because it's the first creation and mActive is empty
}
I am not proud. This works, but it's ugly. What's the actual way of having a valid adapter after a screen rotation?
PS: here's the full code