17

I am working with CustomView which extends some Android view like FrameLayout. In my layout I use a ViewPager with a custom PagerAdapter.

The problem is that my View did not restore it's state when the fragment is re-attached to the ViewPager/Activity. For example, I have three fragments, if I swipe to the last one and come back to the first, the ScrollView is not where I let it : it's back to default, on top.

I know that with a PagerAdapter, not all fragment are active on the same time, basically juste the +1/-1.

I can't find why my View.onSaveInstanceState() is not called, so as onRestoreInstanceState.

Hugo Gresse
  • 17,195
  • 9
  • 77
  • 119

2 Answers2

42

The easy answer : it's because I was not setting id to my view (custom or not). Android didn't manage the onSaveInstanceState/onRestoreInstanceState if no id is set to the view.

So as my customView was extending base View, with not extra property, setting an ID to the view solved the issue and so onSaveInstanceState/onRestoreInstanceState are called as it should.

So to summary, use one of this approach :

from XML

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    ...
    android:id="@+id/scrollView">
</ScrollView>

OR from Java

yourCustomView.setId(R.id.myCustomView);

is last case, you add static id to res/values/ids.xml <item name="myCustomView" type="id"/>

Hugo Gresse
  • 17,195
  • 9
  • 77
  • 119
  • 2
    for me this is not working on an orientation change with to different layouts for landscape and portrait. OnSaveInstanceState is called, but onRestoreInstanceState isn't – Boy Sep 08 '15 at 08:15
  • @Boy i'm having the same issue. is your view within a fragment which is hosted on a viewpager? – Andrea Baccega Oct 05 '15 at 21:14
  • @AndreaBaccega that is the case indeed. It seems ViewPager does some restoring as well of the fragments – Boy Oct 06 '15 at 07:29
  • @AndreaBaccega you can try with `android:configChanges="orientation|keyboardHidden|screenSize"` it will maybe fix it – Hugo Gresse Oct 06 '15 at 07:34
4

Saving State by Default

We now have everything in place for our view to save and restore its state. However, this will not happen by default. If you want instances of your view to save state automatically, you can add this line to the init method:

setSaveEnabled(true);

Whether or not to do this is up to you. Even if your view does not save state by default, users of the view can always enable saving state by calling setSaveEnabled(true), or by specifying android:saveEnabled=“true” in the layout xml.

Eric
  • 16,397
  • 8
  • 68
  • 76
LeX
  • 91
  • 5
  • the view also still needs an `android:id` for this to work...the documentation for `setSaveEnabled()` says: "...the view still must have an id assigned to it (via {@link #setId(int)}) for its state to be saved....". `saveEnabled` is also `true` by default. – Eric Oct 31 '19 at 00:59