I am currently thinking which implementation of the PagerAdapter I should use. I have dilemmas related to both of them. Let me show you what it is.
1 # FragmentPagerAdapter
It works great. It creates new fragments instances when none of the previous instances is available, and retrieves fragments earlier, when possible.
Recently I read an article about StackOverflow, the method of PagerAdapter's getItem() method is called ONLY when it needs to create a fragment, but - it is called again and again, and I had to process the creation of new instances and retrieve the old ones inside this body method.
BUT - Only a few callback and lifecycle methods are called. For example, I cannot make an onSaveInstanceState call to call. Thus, there is no way to preserve the state of the fragment - of course, I can use SharedPreferences or something else, but I wanted to use callback methods. Is there any way to do this?
2 # FragmentStatePagerAdapter
Works fine, saves the state of each fragment that has a ViewPager .
BUT - this PagerAdapter ALWAYS creates a new fragment. I checked it inside the constructor.
Is it inefficient? I saw Romain Guy in Google I / O, saying that creating a new Views inefficient, especially when we create many Views , like in a ListView , so we use convertView to extract the existing View and change it for our purposes as many times as we want . So turning between pages is pretty similar - a lot of new Views - because a fragment is a kind of View
In both PagerAdapters I tried the trick with the Overriding destroyItem() method, but it did not work at all.
And here is my question.
What should I do?
Should I use SharedPreferences and option # 1 with FragmentPagerAdapter or option # 2 with FragmentStatePagerAdapter ?
Is there any possibility that I am doing something wrong with these adapters, do they behave differently from what we expect?
Below, my code is divided into readable parts.
PagerAdapter Part Part 1:
public static class WizardCrazyAdapter extends FragmentStatePagerAdapter implements OnPageChangeListener{ public static final String tag = "android:switcher:"+R.id.pager_w+":"; WizardActivity wizardActivity; private final ArrayList<FragmentInfo> fInfos = new ArrayList<FragmentInfo>(); private short prevPageNumber = 0; public WizardCrazyAdapter(WizardActivity wizardActivity) { super(wizardActivity.getSupportFragmentManager()); this.wizardActivity = wizardActivity; } static final class FragmentInfo { private final Class<?> _clss; private Bundle _args; public FragmentInfo(Class<?> clss, Bundle args) { _clss =clss; _args =args; } } public void addPage(Class<?> clss, Bundle args){ FragmentInfo fi = new FragmentInfo(clss, args); fInfos.add(fi); } public int getCount() { return fInfos.size(); }
PagerAdapter Part Part 2:
private AbstractWizardFragment getFragmentAt(int position){ FragmentManager fm = wizardActivity.getSupportFragmentManager(); AbstractWizardFragment awf = (AbstractWizardFragment) fm.findFragmentByTag(tag+position); return awf; } @Override public Fragment getItem(int position) { AbstractWizardFragment awf = getFragmentAt(position); if(awf == null){ Log.v("WizardActivity", "creating new Fragment"); FragmentInfo fi = fInfos.get(position); awf = (AbstractWizardFragment) Fragment.instantiate(wizardActivity, fi._clss.getName()); }else{ Log.v("WizardActivity", "found existing Fragment"); } return awf; }
Part PagerAdapter No. 3:
@Override public void onPageSelected(int pageNumber) { wizardActivity.stepFragment.setCurrentStepAndChangeText(pageNumber); if(pageNumber != prevPageNumber){ AbstractWizardFragment prevFragment = (AbstractWizardFragment) getItem(prevPageNumber);//TODO change if any problems prevFragment.onDetachedFromViewPager(wizardActivity.mForm); } AbstractWizardFragment currFragment = (AbstractWizardFragment) getItem(pageNumber);//TODO change if any problems currFragment.onAttachedToViewPager(wizardActivity.mForm); prevPageNumber = (short) pageNumber; Log.d("WizardActivity", "onPageSelected"); } @Override public Object instantiateItem(ViewGroup arg0, int arg1) { Log.d("WizardActivity", "instantiateItem "+arg1); return super.instantiateItem(arg0, arg1); } @Override public void destroyItem(ViewGroup container, int position, Object object) { // super.destroyItem(container, position, object); Log.v("WizardActivity", "that would be destroy"); } }
ViewPager Code:
public class WizardPager extends ViewPager{ protected boolean isScrollable; public WizardPager(Context context) { super(context); isScrollable = true; } public WizardPager(Context context, AttributeSet attrs) { super(context, attrs); isScrollable = true; } @Override public boolean onTouchEvent(MotionEvent event) { if (this.isScrollable) { return super.onTouchEvent(event); } return false; } @Override public boolean onInterceptTouchEvent(MotionEvent event) { if (this.isScrollable) { return super.onInterceptTouchEvent(event); } return false; } public void enableScroll(){ this.isScrollable = true; } public void disableScroll(){ this.isScrollable = false; } public boolean isScrollable(){ return isScrollable; } }