I have a ViewPager with 2 fragments setup as swipeable tabs. Everything works fine but when I rotate the screen, only the first fragment is properly recreated. In the second I get a NullPointerException as soon as a method is called that deals with a widget in the second fragment. I can work around this by setting setRetainInstance(true);
on the second fragment. But shouldn't both fragments get recreated properly by the system?
My Activity is:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState !=null ) {
mPersons = savedInstanceState.getInt(STATE_PERSONS);
mPercentage = savedInstanceState.getInt(STATE_TIP);
}
// setup ActionBar
String[] mTabTitles = getResources().getStringArray(R.array.tabs);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// setup TabsAdapter and ViewPager
mTabsAdapter = new TabsAdapter(getFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.viewPager);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
mViewPager.setAdapter(mTabsAdapter);
for (String tab_name : mTabTitles) {
actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
}
...
My TabsAdapter is:
public class TabsAdapter extends FragmentPagerAdapter {
final int NUMBER_OF_TABS = 2;
public TabsAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new SharedBillFragment();
case 1:
return new SeparateBillFragment();
}
return null;
}
@Override
public int getCount() {
return NUMBER_OF_TABS;
}
}
In my fragments i initialize my widgets in onActivityCreate(), e.g. (I also tried to initialize them in onCreateView(), same result...:
private EditText etPersons;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
etPersons = (EditText) getActivity().findViewById(R.id.etPersonsS);
etPersons.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
if (etPersons.length() > 0) {
mCallback.onPersonsSelected(Integer.parseInt(etPersons.getText().toString()));
} else {
mCallback.onPersonsSelected(0);
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
...
}
E.g. the following method in the second fragment throws a NPE when called after a screen rotation:
public int getPersons() {
int persons = 0;
if (etPersons.length() > 0 ) {
persons = Integer.parseInt(etPersons.getText().toString());
}
return persons;
}
Specifically the line if (etPersons.length() > 0 ) {