Skip to content

Commit

Permalink
Fix parcelable crash when restoring SpinnerCompat.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ahmedre committed Apr 1, 2015
1 parent cb1f51b commit 61ff9a6
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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";

Expand Down Expand Up @@ -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++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()}
Expand All @@ -359,13 +360,15 @@ static class SavedState extends BaseSavedState {
super(in);
selectedId = in.readLong();
position = in.readInt();
showDropdown = in.readByte() != 0;
}

@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeLong(selectedId);
out.writeInt(position);
out.writeByte((byte) (showDropdown ? 1 : 0));
}

@Override
Expand All @@ -388,6 +391,8 @@ public SavedState[] newArray(int size) {
};
}

protected abstract boolean isPopupShowing();

@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
Expand All @@ -398,6 +403,7 @@ public Parcelable onSaveInstanceState() {
} else {
ss.position = INVALID_POSITION;
}
ss.showDropdown = isPopupShowing();
return ss;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}

public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}

/**
* <p>Wrapper class for an Adapter. Transforms the embedded Adapter instance into a
* ListAdapter.</p>
Expand Down

0 comments on commit 61ff9a6

Please sign in to comment.