1

I'm still new to Android (and coding) and this is my first time working with Swipe views, i.e. ViewPagers and adapters. My activity has 3 fragments. When I move from Fragment A to Fragment B, all is fine. But when I move to Fragment C, onStop gets called for Fragment A. When I return to Fragment A, all of my views have been restored except for a few. The EditText views are fine, but other views have problems...

  • I have a couple of TextViews that I enable/disable. These states are not retained.
  • Other TextViews can be visible/invisible. These states are not retained.
  • I don't believe the TextView texts are being retained either.

It was my impression that onSaveInstanceState saves views. Do I have to save these states manually? Since these are Fragments, should that be done through arguments?

Here is my Fragment onCreateView

@Override
public View onCreateView(LayoutInflater inflater,
        ViewGroup container, Bundle savedInstanceState) {
    rootView = inflater.inflate(
            R.layout.activity_grade_calculator, container, false);
    Bundle args = getArguments();
    if(args.containsKey(PERSISTENT_FIRSTLOAD_BUNDLE_KEY)) {
        firstLoad = args.getBoolean(PERSISTENT_FIRSTLOAD_BUNDLE_KEY);
    }
    context = this.getActivity();

    if(firstLoad) {
        bindAll();
        setInitialViews();  
        setListeners();
    }
    firstLoad = false;
    return rootView;
}  

Here is MyPagerAdapter

@Override
public Fragment getItem(int i) {
    //System.out.println("We are trying to get item " + i);
    switch(i) {
        case 0:
            Fragment fragment = new FinalCalcFragment();
            return fragment;
        case 1:
            Fragment fragment1 = new NewGradeCalcFragment();
            return fragment1;
        case 2:
            Fragment fragment3 = new NewGradeCalcFragment();
            return fragment3;
        default:
            return null;
    }

}

Here are some TextViews that are not behaving nicely.

<TextView
                android:id="@+id/tv_grade_calc_forgrade"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/radioGroup1"
                android:layout_marginTop="4dp"
                android:text="@string/tv_grade_calc_forgrade" />

            <TextView
                android:id="@+id/tv_grade_calc_ifscore"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/radioGroup1"
                android:layout_marginTop="4dp"
                android:text="@string/tv_grade_calc_ifscore" />

             <TextView
                 android:id="@+id/tv_grade_calc_result"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_alignParentRight="true"
                 android:layout_below="@id/tv_grade_calc_ifscore"
                 android:layout_marginRight="10dp"
                 android:layout_marginTop="-7dp"
                 android:textSize="28sp" />  

Edit: Btw, I've played around with both FragmentPagerAdapter and FragmentStatePagerAdapter. I don't fully understand what they do differently, but neither seem to give me what I want.

NSouth
  • 5,067
  • 7
  • 48
  • 83
  • FragmentStatePagerAdapter is preferable in your case because it saves the state of your Fragments. – joao2fast4u Sep 10 '14 at 00:03
  • Thanks, although it still doesn't save the TextViews like I'd like. – NSouth Sep 10 '14 at 00:05
  • 1
    possible duplicate of [ViewPager Fragments getting destroyed over time?](http://stackoverflow.com/questions/9857420/viewpager-fragments-getting-destroyed-over-time) – rds Sep 10 '14 at 00:48

2 Answers2

2

If you only have those three Fragments in your ViewPager, you can define a minimum number of Fragments that are always being kept in memory at one time by using the method mViewPager.setOffscreenPageLimit(value); The default value is 1. That is the reason your Fragment A state is being lost when you swipe to Fragment C. If you increase this value to 2, that will not happen, as the ViewPager will always keep the state of two Fragments (ahead or before) your current showing Fragment.

joao2fast4u
  • 6,868
  • 5
  • 28
  • 42
  • 1
    Well, that did it! Thanks! I'll also look into manually saving these when my fragment is stopped so that I don't hit any problems down the road. – NSouth Sep 10 '14 at 00:59
1

The viewpager keeps only one page in advance. When you reach fragment C, the fragment A is released.

The fragment lifecycle is similar to the activity lifecycle, and a fragment can be stopped when it's not used anymore. You should be prepared for this.

Like for activities, you need to manually save the state in onSaveInstanceState() and restore the state later.

rds
  • 26,253
  • 19
  • 107
  • 134
  • Does that mean that--although `EditText`s have their states saved--the `TextView`s won't be retained? What are the rules regarding this? I suppose I can save the TextView states if I need to. – NSouth Sep 10 '14 at 00:23
  • Indeed, you should keep the state of the Views (visiblility/enabled/etc) yourself and restore it appropriately (for instance in `onCreate` or in `onCreateView`). – rds Sep 10 '14 at 00:41
  • `EditText` already natively saves it's data (see http://stackoverflow.com/questions/24553634/fragment-automatically-saving-and-restoring-state-of-edittexts) but I'd be surprised if they also save their visibility. – rds Sep 10 '14 at 00:43