0

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 ) {

fnberta
  • 353
  • 5
  • 13

1 Answers1

0

You Should be using FragmentStatePagerAdapter instead of FragmentPagerAdapter. Only in FragmentStatePagerAdapter getItem() is called, hence recreated.

Community
  • 1
  • 1
VenomVendor
  • 15,064
  • 13
  • 65
  • 96
  • But the android docs suggest that a FragmentPagerAdapter "... is best when navigating between sibling screens representing a fixed, small number of pages." This is exactly my use case, shouldn't it be possible thus to solve this with a FragmentPagerAdapter? – fnberta Jun 15 '14 at 07:03