When I start the app everything works ok but when I rotate to landscape it crashes because in the Fragment
there is a field that is NULL
.
I dont use setRetainInstance(true)
or adding Fragments to FragmentManager
I create new Fragments on app start and when app rotate.
In the Activity
OnCreate()
I create the Fragment
and adding them to the viewPager
like this.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ParentBasicInfoFragment parentBasicInfoFragment = new ParentBasicInfoFragment();
ParentUTCFragment parentUTCFragment = new ParentUTCFragment();
ParentEventsFragment parentEventsFragment = new ParentEventsFragment();
this.mFragments = new ArrayList<>();
this.mFragments.add(parentBasicInfoFragment);
this.mFragments.add(parentUTCFragment);
this.mFragments.add(parentEventsFragment);
this.viewpage.setOffscreenPageLimit(3);
setCurrentTab(0);
this.viewpage.setAdapter(new MainActivityPagerAdapter(getSupportFragmentManager(), this.mFragments));
}
Then I have a test button on the app that when I press it will do like
public void test(View view) {
((BaseFragment) MainActivity.this.mFragments.get(MainActivity.this.viewpage.
getCurrentItem())).activityNotifiDataChange("hello");
}
This will work and the current Fragments
in the ViewPager
have the method, activityNotifiDataChange()
that are being called and all is ok.
When I rotate the app and do the same thing pressing the button the activityNotifiDataChange()
is being called alright but there a null pointer exception because the ArrayList<Fragment> mFragment
is now NULL.
Here´s a small sample Android Studio project showing this behavior: https://drive.google.com/file/d/1Swqu59HZNYFT5hMTqv3eNiT9NmakhNEb/view?usp=sharing
Start app and press button named "PRESS TEST", then rotate device and press the button again and watch the app crash
UPDATE SOLUTION thanks @GregMoens and @EpicPandaForce
public class MainActivityPagerAdapter extends PersistenPagerAdapter<BaseFragment> {
private static int NUM_ITEMS = 3;
public MainActivityPagerAdapter(FragmentManager fm) {
super(fm);
}
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return ParentBasicInfoFragment.newInstance(0, "Page # 1");
case 1:
return ParentUTCFragment.newInstance(1, "Page # 2");
case 2:
return ParentEventsFragment.newInstance(2, "Page # 3");
default:
return null;
}
}
}
public abstract class PersistenPagerAdapter<T extends BaseFragment> extends FragmentPagerAdapter {
private SparseArray<T> registeredFragments = new SparseArray<T>();
public PersistenPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
@Override
public T instantiateItem(ViewGroup container, int position) {
T fragment = (T)super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public T getRegisteredFragment(ViewGroup container, int position) {
T existingInstance = registeredFragments.get(position);
if (existingInstance != null) {
return existingInstance;
} else {
return instantiateItem(container, position);
}
}
}