From 61ff9a6a4b634d2337125b6eaaf305f1876ca231 Mon Sep 17 00:00:00 2001 From: ahmedre Date: Tue, 10 Mar 2015 00:41:42 -0700 Subject: [PATCH] Fix parcelable crash when restoring SpinnerCompat. For some reason, we were having issues restoring the state of the Spinner when reviving the activity (BadParcelableException due to a ClassNotFoundException). After much searching and reading, solved the issue with this workaround, which involves only having saved state in AbsSpinnerCompat instead of having part of it in the parent and part in SpinnerCompat. This also turns out to be what ActionBarSherlock's IcsSpinner did as well. Note that this is a valid fix (though perhaps non-ideal due to AbsSpinnerCompat not really being a true abstraction), and that, in addition to fixing the crash, it does persist spinner state (including the open state of the menu) for something like the JumpDialog. The remaining spinners (shuyookh list, etc) that aren't persisting have never persisted before. We should definitely fix this in the future, as it's especially jarring when switching orientation on the device. --- .../ui/fragment/JumpFragment.java | 20 ++++----- .../widgets/spinner/AbsSpinnerCompat.java | 6 +++ .../widgets/spinner/SpinnerCompat.java | 44 ++----------------- 3 files changed, 20 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/com/quran/labs/androidquran/ui/fragment/JumpFragment.java b/app/src/main/java/com/quran/labs/androidquran/ui/fragment/JumpFragment.java index 67ad36cfe7..fe2de942f8 100644 --- a/app/src/main/java/com/quran/labs/androidquran/ui/fragment/JumpFragment.java +++ b/app/src/main/java/com/quran/labs/androidquran/ui/fragment/JumpFragment.java @@ -1,5 +1,14 @@ package com.quran.labs.androidquran.ui.fragment; +import com.quran.labs.androidquran.R; +import com.quran.labs.androidquran.data.Constants; +import com.quran.labs.androidquran.data.QuranInfo; +import com.quran.labs.androidquran.ui.PagerActivity; +import com.quran.labs.androidquran.ui.QuranActivity; +import com.quran.labs.androidquran.util.QuranUtils; +import com.quran.labs.androidquran.widgets.spinner.AdapterViewCompat; +import com.quran.labs.androidquran.widgets.spinner.SpinnerCompat; + import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; @@ -19,15 +28,6 @@ import android.widget.EditText; import android.widget.TextView; -import com.quran.labs.androidquran.R; -import com.quran.labs.androidquran.data.Constants; -import com.quran.labs.androidquran.data.QuranInfo; -import com.quran.labs.androidquran.ui.PagerActivity; -import com.quran.labs.androidquran.ui.QuranActivity; -import com.quran.labs.androidquran.util.QuranUtils; -import com.quran.labs.androidquran.widgets.spinner.AdapterViewCompat; -import com.quran.labs.androidquran.widgets.spinner.SpinnerCompat; - public class JumpFragment extends DialogFragment { public static final String TAG = "JumpFragment"; @@ -94,7 +94,7 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { suraSpinner.setOnItemSelectedListener(new AdapterViewCompat.OnItemSelectedListener() { @Override public void onItemSelected(AdapterViewCompat parent, View view, int position, long rowId) { - Context context = view.getContext(); + Context context = getActivity(); if (suraSpinner.getTag() == null) { // this is the initialization for (int i = 1; i <= QuranInfo.SURA_NUM_AYAHS[0]/*al-Fatiha*/; i++) { diff --git a/app/src/main/java/com/quran/labs/androidquran/widgets/spinner/AbsSpinnerCompat.java b/app/src/main/java/com/quran/labs/androidquran/widgets/spinner/AbsSpinnerCompat.java index 34814b4368..90f5add313 100644 --- a/app/src/main/java/com/quran/labs/androidquran/widgets/spinner/AbsSpinnerCompat.java +++ b/app/src/main/java/com/quran/labs/androidquran/widgets/spinner/AbsSpinnerCompat.java @@ -344,6 +344,7 @@ public int pointToPosition(int x, int y) { static class SavedState extends BaseSavedState { long selectedId; int position; + boolean showDropdown; /** * Constructor called from {@link AbsSpinnerCompat#onSaveInstanceState()} @@ -359,6 +360,7 @@ static class SavedState extends BaseSavedState { super(in); selectedId = in.readLong(); position = in.readInt(); + showDropdown = in.readByte() != 0; } @Override @@ -366,6 +368,7 @@ public void writeToParcel(Parcel out, int flags) { super.writeToParcel(out, flags); out.writeLong(selectedId); out.writeInt(position); + out.writeByte((byte) (showDropdown ? 1 : 0)); } @Override @@ -388,6 +391,8 @@ public SavedState[] newArray(int size) { }; } + protected abstract boolean isPopupShowing(); + @Override public Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); @@ -398,6 +403,7 @@ public Parcelable onSaveInstanceState() { } else { ss.position = INVALID_POSITION; } + ss.showDropdown = isPopupShowing(); return ss; } diff --git a/app/src/main/java/com/quran/labs/androidquran/widgets/spinner/SpinnerCompat.java b/app/src/main/java/com/quran/labs/androidquran/widgets/spinner/SpinnerCompat.java index 59fd23a4ea..928e803740 100644 --- a/app/src/main/java/com/quran/labs/androidquran/widgets/spinner/SpinnerCompat.java +++ b/app/src/main/java/com/quran/labs/androidquran/widgets/spinner/SpinnerCompat.java @@ -23,7 +23,6 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; -import android.os.Parcel; import android.os.Parcelable; import android.support.v4.view.GravityCompat; import android.support.v4.view.ViewCompat; @@ -683,19 +682,15 @@ int measureContentWidth(SpinnerAdapter adapter, Drawable background) { } @Override - public Parcelable onSaveInstanceState() { - final SavedState ss = new SavedState(super.onSaveInstanceState()); - ss.showDropdown = mPopup != null && mPopup.isShowing(); - return ss; + protected boolean isPopupShowing() { + return mPopup != null && mPopup.isShowing(); } @Override public void onRestoreInstanceState(Parcelable state) { - SavedState ss = (SavedState) state; + super.onRestoreInstanceState(state); - super.onRestoreInstanceState(ss.getSuperState()); - - if (ss.showDropdown) { + if (((AbsSpinnerCompat.SavedState) state).showDropdown) { ViewTreeObserver vto = getViewTreeObserver(); if (vto != null) { final ViewTreeObserver.OnGlobalLayoutListener listener @@ -716,37 +711,6 @@ public void onGlobalLayout() { } } - static class SavedState extends AbsSpinnerCompat.SavedState { - - boolean showDropdown; - - SavedState(Parcelable superState) { - super(superState); - } - - private SavedState(Parcel in) { - super(in); - showDropdown = in.readByte() != 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeByte((byte) (showDropdown ? 1 : 0)); - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - /** *

Wrapper class for an Adapter. Transforms the embedded Adapter instance into a * ListAdapter.