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

后端 未结 9 1093
时光说笑
时光说笑 2020-11-22 10:11

I\'ve successfully implemented onRetainNonConfigurationInstance() for my main Activity to save and restore certain critical components across screen orientation

9条回答
  •  广开言路
    2020-11-22 10:57

    I found that this answer was causing some crashes on Android versions 9 and 10. I think it's a good approach but when I was looking at some Android code I found out it was missing a constructor. The answer is quite old so at the time there probably was no need for it. When I added the missing constructor and called it from the creator the crash was fixed.

    So here is the edited code:

    public class CustomView extends View {
    
        private int stateToSave;
    
        ...
    
        @Override
        public Parcelable onSaveInstanceState() {
            Parcelable superState = super.onSaveInstanceState();
            SavedState ss = new SavedState(superState);
    
            // your custom state
            ss.stateToSave = this.stateToSave;
    
            return ss;
        }
    
        @Override
        protected void dispatchSaveInstanceState(SparseArray container)
        {
            dispatchFreezeSelfOnly(container);
        }
    
        @Override
        public void onRestoreInstanceState(Parcelable state) {
            SavedState ss = (SavedState) state;
            super.onRestoreInstanceState(ss.getSuperState());
    
            // your custom state
            this.stateToSave = ss.stateToSave;
        }
    
        @Override
        protected void dispatchRestoreInstanceState(SparseArray container)
        {
            dispatchThawSelfOnly(container);
        }
    
        static class SavedState extends BaseSavedState {
            int stateToSave;
    
            SavedState(Parcelable superState) {
                super(superState);
            }
    
            private SavedState(Parcel in) {
                super(in);
                this.stateToSave = in.readInt();
            }
    
            // This was the missing constructor
            @RequiresApi(Build.VERSION_CODES.N)
            SavedState(Parcel in, ClassLoader loader)
            {
                super(in, loader);
                this.stateToSave = in.readInt();
            }
    
            @Override
            public void writeToParcel(Parcel out, int flags) {
                super.writeToParcel(out, flags);
                out.writeInt(this.stateToSave);
            }    
    
            public static final Creator CREATOR =
                new ClassLoaderCreator() {
    
                // This was also missing
                @Override
                public SavedState createFromParcel(Parcel in, ClassLoader loader)
                {
                    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? new SavedState(in, loader) : new SavedState(in);
                }
    
                @Override
                public SavedState createFromParcel(Parcel in) {
                    return new SavedState(in, null);
                }
    
                @Override
                public SavedState[] newArray(int size) {
                    return new SavedState[size];
                }
            };
        }
    }
    

提交回复
热议问题