32

I'm aware of activity state saving and restoring. But what I want to do is saving and restoring the state of a view. I have a custom view and two overrided methods in it:

@Override
protected void onRestoreInstanceState(Parcelable state) {
    if (state instanceof Bundle) {
        Bundle bundle = (Bundle) state;
        currentLeftX = bundle.getInt(CURRENT_LEFT_X_PARAM, 0);
        currentTopY = bundle.getInt(CURRENT_TOP_Y_PARAM, 0);
    }
    super.onRestoreInstanceState(state);
}

@Override
protected Parcelable onSaveInstanceState() {
    super.onSaveInstanceState();
    Bundle bundle = new Bundle();
    bundle.putInt(CURRENT_LEFT_X_PARAM, currentLeftX);
    bundle.putInt(CURRENT_TOP_Y_PARAM, currentTopY);
    return bundle;
}

I expected this to work seamless, but encountered and error:

Caused by: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.os.Bundle instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/mapViewId. Make sure other views do not use the same id. at android.view.View.onRestoreInstanceState(View.java:6161)

But this view is the only one in my activity. So, I'm asking:

What is the right way to save the state of the view?

Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
  • I had to laugh because of how ridiculous the design of Android is. The method does not expect View state ***obviously***, it ***obviously*** expects an interface named ***Parcelable***. And yes we do return a valid ***Parcelable*** which is implemented by ***Bundle***. But it failed for a ridiculous reason. I've never encountered this kind of design in .NET, when it expects an interface, there should not be any exception if we do return that exact interface. The exception should say something else making more sense =))) Android is one big example of how ***bad*** design can make you annoyed. – King King Oct 12 '16 at 02:41
  • Take a look at this answer: https://stackoverflow.com/questions/3542333/how-to-prevent-custom-views-from-losing-state-across-screen-orientation-changes/3542895#3542895 – BFil May 18 '11 at 13:29

2 Answers2

4

You drop the result of super.OnSaveInstanceState() and return your own. Then later at OnRestoreInstanceState(Parcelable) you return the one which you created.

The solution for that is here:

How to prevent custom views from losing state across screen orientation changes #2

Community
  • 1
  • 1
Kobor42
  • 5,129
  • 1
  • 17
  • 22
  • 1
    you don't drop the result - your ancestors may have saved state, and then you'll read the entries out in the wrong order – ataulm May 12 '14 at 16:06
-4

I could be wrong, but I think you need to save the bundle the parent returns:

@Override
protected Parcelable onSaveInstanceState() {
    Parcelable bundle = super.onSaveInstanceState();
    bundle.putInt(CURRENT_LEFT_X_PARAM, currentLeftX);
    bundle.putInt(CURRENT_TOP_Y_PARAM, currentTopY);
    return bundle;
}

Otherwise you're losing everything the superclass saved.

dmon
  • 30,048
  • 8
  • 87
  • 96
  • 4
    default implementation of onSaveInstanceState returns null. Also, bundle here is Parcelable, which doesn't have any methods like putInt. – Vladimir Ivanov May 18 '11 at 14:45