7

I'm having trouble with restoring state of a View inside a ViewPager. The content of the ViewPager is a view extending FrameLayout.

The problem is the FrameLayout.onRestoreInstanceState() is not being called if added programmatically into the ViewPager

Here's the code of my Activity.java

private ViewPager vPager;
private MainPagerAdapter mAdapter;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    setContentView(R.layout.activity_layout);
    // all the findViewById stuff

    CustomView cv1 = new CustomView(this);
    CustomView cv2 = new CustomView(this);

    cv1.setId(R.id.custom_view_id_1);
    cv2.setId(R.id.custom_view_id_2);

    mAdapter = MainPagerAdapter();
    mAdapter.addView(cv1);
    mAdapter.addView(cv2);
    vPager.setAdapter(mAdapter);
}

MainPagerAdapter is a class from the accepted answer of this question

Source code for CustomView.java

@Override
protected Parcelable onSaveInstanceState() {
    Log.d(TAG, "onSaveInstanceState() called");
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
    Log.d(TAG, "onRestoreInstanceState() called");
}

Here's my findings so far:

  1. onSaveInstanceState() will be called but onRestoreInstanceState() is not
  2. When I tried to add the View directly to the root of the Activity, it calls both functions.
  3. I found out that Activity's onRestoreState function will be called before the ViewPager calls the adapter's instantiateItem() function. So when the activity restore its state, the ViewPager doesn't have any children yet, thus the savedState doesn't belong to anyone

So I figure out that I need to make one of two things to work:

  1. Make sure the ViewPager instantiate the item before trying to restore the state, or
  2. Calls the CustomView's onRestoreInstanceState() manually.

I somehow managed to make option number 2, but is there any way to do option number 1?

Ahmad Fadli
  • 894
  • 10
  • 25
  • Have you found a workaround for this? I'm facing the same problem... – sockeqwe Feb 27 '16 at 22:32
  • @sockeqwe For now I'll only able to do no. 2 which is calls the CustomView's onRestoreInstanceState manually with providing the state from SparseArray. – Ahmad Fadli Feb 29 '16 at 06:48
  • Looks like this is an intended behaviour of ViewPager, and in it is worked around with Fragments in FragmentStatePagerAdapter, when fragments aren't really removed. Would love to see some proper solution when ViewPager is with Views, not Fragments – AAverin Apr 05 '18 at 12:15

1 Answers1

-1

If I understood your question, you can save your ViewPager items state using mPage.setOffscreenPageLimit(4); 4 is the number of my Fragments inside ViewPager.

Hayk Mkrtchyan
  • 1,365
  • 1
  • 12
  • 32
  • Doing this does not solve the problem. Calling `.setOffscreePageLimit(int)` means the fragments will be retained even though it's not displayed on screen. Imagine if the number of fragment is big (tens or hundreds) then the performance hit will occur. – Ahmad Fadli Apr 02 '18 at 08:12
  • Ok, so what you want? Because I don't understand your question, what you mean saying restore state of ViewPager's items – Hayk Mkrtchyan Apr 03 '18 at 07:17
  • It's basically how to utilize `onSaveInstanceState()` and `onRestoreInstanceState()` like the one in `Activity`, but this one on a custom `ViewGroup`'s state when being put inside `ViewPager`. – Ahmad Fadli Apr 03 '18 at 09:01
  • https://stackoverflow.com/questions/31013996/where-to-restore-fragment-state-that-is-inside-viewpager/31018943 . Try this, I think this will help you. – Hayk Mkrtchyan Apr 03 '18 at 09:08
  • Thanks. But I think that's for fragment while my case is for ViewGroup. – Ahmad Fadli Apr 03 '18 at 09:23
  • Ok, so saying save state of viewGroup, you want example if you destroy your app, when viewPager was in second fragment, and you open your app again, it opened second fragment instead of first? Am i understood you? – Hayk Mkrtchyan Apr 03 '18 at 09:26
  • Not that. First, look at my findings point (all 3 of them). Second, I'm using `ViewGroup` not a fragment. Third, what I want to achieve is to save the state of the individuals `ViewGroup`, not the position of the selected item. – Ahmad Fadli Apr 03 '18 at 20:53
  • SharedPreferences can help you? – Hayk Mkrtchyan Apr 04 '18 at 07:00