Android ViewPager.OnPageChangeListener lifecycle rotation issue -
Android ViewPager.OnPageChangeListener lifecycle rotation issue -
when screen rotated android calls onpagechangelistener.onpageselected event prior calling fragmentpageradapter.instantiateitem.
this seems fundamentally broken me. typically reference fragment during phone call instantiateitem. since onpageselected called first reference fragment null. what's best way work around problem? see code below improve explanation:
(code written in c# using mono android should identical java equivalent).
adapter:
public class mainpageradapter : fragmentpageradapter { public fragment[] fragments { get; private set; } public override java.lang.object instantiateitem(viewgroup view, int index) { var o = base.instantiateitem(view, index); fragments[index] = (fragment)o; homecoming o; } ... }
listener:
public class tabpagerlistener : java.lang.object, viewpager.ionpagechangelistener, tabpageindicator.iontabreselectedlistener { public void onpageselected(int tabindex) { var tabactivity = (itabactivity)instance; var currentfragment = tabadapter.fragments[tabpager.currentitem]; //currentfragment null since instantiateitem hasn't been called yet } ... }
while feels broken when exact issue bit me, think i've figured out "intended usage model", in it's not broken working intended. :/
first, when user rotates device , view hierarchy reconstructed, never phone call instantiateitem...instead saves , restores relevant fragments part of fragmentmanager (i think), avoid calling instantiateitem. there no "ordering" problem phone call onpageselected.
as subclasser of pageradapter own state (namely, fragments), responsible saving/restoring reference fragments (using fragmentmanager gets passed in constructor). believe next should work both fragmentstatepageradapter and fragmentpageradapter subclasses:
public eventinfopageradapter(fragmentmanager fm) { super(fm); mfragmentmanager = fm; } private static string state_superclass = "state_superclass"; private static string state_fragment_ids = "state_fragment_ids"; @override public parcelable savestate() { parcelable p = super.savestate(); bundle bundle = new bundle(); bundle.putparcelable(state_superclass, p); bundle fragmentsbundle = new bundle(); (int i=0; i<mfragments.size(); i++) { fragment f = mfragments.get(i); if (f != null) { mfragmentmanager.putfragment(fragmentsbundle, integer.tostring(i), f); } } bundle.putbundle(state_fragment_ids, fragmentsbundle); homecoming bundle; } @override public void restorestate(parcelable state, classloader loader) { bundle bundle = (bundle)state; if (bundle != null) { super.restorestate(bundle.getparcelable(state_superclass), loader); bundle fragmentsbundle = bundle.getbundle(state_fragment_ids); mfragments.clear(); mfragments.ensurecapacity(fragmentsbundle.size()); iterable<string> keys = fragmentsbundle.keyset(); (string key: keys) { int index = integer.parseint(key); fragment f = mfragmentmanager.getfragment(fragmentsbundle, key); if (f != null) { while (mfragments.size() <= index) { mfragments.add(null); } fragmentcompat.setmenuvisibility(f, false); mfragments.set(index, (eventinfofragment)f); } else { log.w(log_tag, "bad fragment @ key " + key); } } } }
android android-viewpager fragment android-lifecycle
Comments
Post a Comment