because I don't like the default implementation of Android's Bottom Navigation Bar, I have made my own and connected it with a FragmentStatePagerAdapter. I just want to know how I can get already created Fragments with their saved instance state from my adapter just like viewpager does?
It would be nice if anyone could help me solve this.
I solved it on my own. I totally had forgotten to care about the Saved Instance State of my view. I got it from the ViewPager source code and modified it slightly because some Methods were marked as deprecated. Here the implementation.
#Nullable
#Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SaveState ss = new SaveState(superState);
ss.position = lastSelectedPosition;
ss.itemId = lastSelectedItemId;
if (mAdapter != null) {
ss.adapterState = mAdapter.saveState();
}
return ss;
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
if (!(state instanceof SaveState)) {
super.onRestoreInstanceState(state);
return;
}
SaveState ss = (SaveState) state;
super.onRestoreInstanceState(ss.getSuperState());
if (mAdapter != null) {
mAdapter.restoreState(ss.adapterState, ss.loader);
setSelectedItem(ss.position, ss.itemId);
lastSelectedItemId = ss.itemId;
lastSelectedPosition = ss.position;
}
}
public static class SaveState extends BaseSavedState {
int position;
int itemId;
Parcelable adapterState;
ClassLoader loader;
SaveState(Parcelable superState) {
super(superState);
}
#Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(position);
out.writeInt(itemId);
out.writeParcelable(adapterState, flags);
}
public static final Parcelable.ClassLoaderCreator<SaveState> CREATOR = new
Class later dater<SaveState>() {
#Override
public SaveState createFromParcel(Parcel source) {
return new SaveState(source, null);
}
#Override
public SaveState[] newArray(int size) {
return new SaveState[size];
}
#Override
public SaveState createFromParcel(Parcel source, ClassLoader loader) {
return new SaveState(source, loader);
}
};
SaveState(Parcel in, ClassLoader loader) {
super(in);
if (loader == null) {
loader = getClass().getClassLoader();
}
position = in.readInt();
itemId = in.readInt();
adapterState = in.readParcelable(loader);
this.loader = loader;
}
}
Related
I have extended the MaterialButton to display a consistent loading state on the button when clicked however I ran into a minor issue when implementing SavedState restoration.
The progress button variant of this I have written, disables the view, displays an animated loading spinner, optionally displays loading text and restores then restores the previously displayed text/state when the view is enabled.
MaterialButton.SavedState is package-private so cannot be extended externally. This does not create a problem with my implementation as I don't use the 'checked' field it extends but it does raise these questions:
TLDR
Is it wrong to extend this MaterialButton?
If not would it be appropriate to submit a PR to the public repo to make SavedState public?
material-components-android:1.2.0
Is it wrong to extend this MaterialButton?
The MaterialButton is not a final class then you can extend it, and for example the ExtendedFloatingActionButton extends it.
If not would it be appropriate to submit a PR to the public repo to make SavedState public?
You don't need to make MaterialButton.SavedState public. You can do something like:
public class MyButton extends MaterialButton
{
private String text;
//....
static class SavedState extends AbsSavedState {
#Nullable CharSequence myText;
SavedState(Parcelable superState) {
super(superState);
}
SavedState(#NonNull Parcel source, ClassLoader loader) {
super(source, loader);
myText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
}
#Override
public void writeToParcel(#NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
TextUtils.writeToParcel(myText, dest, flags);
}
#NonNull
#Override
public String toString() {
return "MyButton.SavedState{"
+ " text="
+ myText
+ "}";
}
public static final Creator<SavedState> CREATOR =
new ClassLoaderCreator<SavedState>() {
#NonNull
#Override
public SavedState createFromParcel(#NonNull Parcel in, ClassLoader loader) {
return new SavedState(in, loader);
}
#Nullable
#Override
public SavedState createFromParcel(#NonNull Parcel in) {
return new SavedState(in, null);
}
#NonNull
#Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
#Nullable
#Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
ss.myText = text;
return ss;
}
#Override
public void onRestoreInstanceState(#Nullable Parcelable state) {
if (!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
text = ss.myText.toString();
}
}
In this way the MyButton.SavedState will contain also the MaterialButton.SaveState without extending it.
So I have an app that searches for an artist on the internet, via an API and displays the list of the results (artist names) after performing this search at hand. I want to retain this list as I change the orientation (portrait - landscape) of my device and not having to perform the search again. Here is some code:
public class MainActivityFragment extends Fragment{
public static final String ARTIST_ID = "artistId";
private final String NO_RESULTS = "No artists found. Please check your input!";
private List<Artist> artists = new ArrayList<>();
private ArtistArrayAdapter adapter;
public MainActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
final SearchView searchView = (SearchView) rootView.findViewById(R.id.search_artist);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String artistName) {
SearchArtist(artistName);
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0);
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
ListView listView = (ListView) rootView.findViewById(android.R.id.list);
adapter = new ArtistArrayAdapter(getActivity(), R.layout.artist_list_item, artists);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Artist artist = artists.get(position);
String artistId = artist.id;
Intent detailArtist = new Intent(getActivity(), DetailActivity.class);
detailArtist.putExtra(ARTIST_ID, artistId);
startActivity(detailArtist);
}
});
return rootView;
}
So I think I have to make the List of artists parcelable and then pass it to the onSaveInstanceState method. But how do make this list parcelable?
Thanks a lot, I hope this isn't too confusing...
You'll need to implement the Parcelable Interface for your Artist Data Model class. For example
public class ArtistParcelable implements Parcelable {
public String id;
public String artistName;
public List<String> artistImageUrls = Collections.emptyList();
public ArtistParcelable(Artist artist) {
// Do the assignments here
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
//write
dest.writeString(this.id);
dest.writeString(this.artistName);
dest.writeStringList(this.artistImageUrls);
}
protected ArtistParcelable(Parcel in) {
//retrieve
this.id = in.readString();
this.artistName = in.readString();
this.artistImageUrls = in.createStringArrayList();
}
public static final Parcelable.Creator<ArtistParcelable> CREATOR = new Parcelable.Creator<ArtistParcelable>() {
public ArtistParcelable createFromParcel(Parcel source) {
return new ArtistParcelable(source);
}
public ArtistParcelable[] newArray(int size) {
return new ArtistParcelable[size];
}
};
}
And in your fragment - if you have List mArtists, then you save and retrieve the list like
#Override
public void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(ARTISTS, (ArrayList<? extends Parcelable>) mArtists);
}
And in onCreateView
if (savedInstanceState != null) {
mArtists = savedInstanceState.getParcelableArrayList(ARTISTS);
Here's a good guide, which you can follow.
https://guides.codepath.com/android/Using-Parcelable
There's an IDE plugin called Android Parcelable Code Generator available also, which generates all the boilerplate code for you.
And there's also a library called Parceler, which is pretty handy. It removes the boilerplate entirely.
First your Artist class must implement parcelable
public class Artist implements Parcelable
Then you should override the method writeToParcel saying what you want to save, for example:
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mSavedString);
}
create a constructor to read the saved variables:
protected Artist(Parcel in){
mSavedString = in.readString();
}
Then the creator:
public static final Parcelable.Creator<Artist> CREATOR
= new Parcelable.Creator<Artist>() {
public Artist createFromParcel(Parcel in) {
return new Artist(in);
}
public Artist[] newArray(int size) {
return new Artist[size];
}
};
And finally on your activity override onsavedinstance:
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArray("AristArray", mArtistArray);
}
Also, do not forget to retrive by doing this onCreate of your activity:
if (savedInstanceState != null) {
mArtistArray= new List<Artist>(savedInstanceState.getParcelableArray("ArtistArray"));
}
Ps: did not try the code, so anything you want to know ask, I will try and help you ;)
src: http://developer.android.com/reference/android/os/Parcelable.html
Hope it help ;)
How About modifying your Artist class to make it Parcelabel.
public class Artist implements Parcelable {
public static final Creator<Artist> CREATOR = new Creator<Artist>() {
public Artist createFromParcel(Parcel source) {
return new Artist(source);
}
public Artist[] newArray(int size) {
return new Artist[size];
}
};
private final String name;
public Artist(String name) {
this.name = name;
}
private Artist(Parcel in) {
name = in.readString();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
}
#Override
public int describeContents() {
return 0;
}
public String getName() {
return name;
}
}
Then use following.
protected void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList("key_artists",artists);
}
in my application i'm trying to use Parcelable class to save savedInstanceState bundle, for this action i'm create this below code:
public class SaveInstanceState implements Parcelable {
String stringStates;
Integer integerStates;
boolean booleanStates;
public SaveInstanceState(String str) {
this.stringStates = str;
}
public SaveInstanceState(Integer value) {
this.integerStates = value;
}
public SaveInstanceState(boolean value) {
this.booleanStates = value;
}
public SaveInstanceState(String str, Integer ivalue, boolean bvalue) {
this.stringStates = str;
this.integerStates = ivalue;
this.booleanStates = bvalue;
}
private SaveInstanceState(Parcel in) {
stringStates = in.readString();
integerStates = in.readInt();
booleanStates = in.readByte() != 0;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(stringStates);
out.writeInt(integerStates);
out.writeByte((byte) (booleanStates ? 1 : 0));
}
public static final Parcelable.Creator<SaveInstanceState> CREATOR = new Parcelable.Creator<SaveInstanceState>() {
#Override
public SaveInstanceState createFromParcel(Parcel in) {
return new SaveInstanceState(in);
}
#Override
public SaveInstanceState[] newArray(int size) {
return new SaveInstanceState[size];
}
};
}
in Activity i'm try to save into class by:
private ArrayList<SaveInstanceState> InstanceStateList;
public class ActivityMainView ... {
if (savedInstanceState == null || !savedInstanceState.containsKey("ActivityMain")) {
InstanceStateList = new ArrayList<SaveInstanceState>();
InstanceStateList.add(new SaveInstanceState(mLastMenuItemSelected));
InstanceStateList.add(new SaveInstanceState(mIsShowingExitDialogs));
} else
InstanceStateList = savedInstanceState.getParcelableArrayList("ActivityMain");
}
now for this blow function i can not get from Parcable class and restore savedInstanceState from it
public void RestoreInstanceState(Bundle savedInstanceState) {
savedInstanceState.getParcelableArrayList("ActivityMain");
}
whats my code problem?
I have a layout in which I have dynamically added custom views at a push of a button. These layouts extend LinearLayout and each carry their own unique Action objects.
The views will disappear, however, if onCreate is called again, when the user navigates away or rotates the screen. I want to keep these custom ActionHolder views there. To add to the problem, the ActionHolder objects contain sensitive information. The Action objects themselves store a live timer(that is supposed to keep on ticking even if the app is off), as well as other information.
According to an answer below, I have done the following, but to no avail. Here is what I have so far:
public class ActionHolder extends LinearLayout implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2271402255369440088L;
private Action action;
private String timer;
public static final int ACTION_TITLE = 0, ACTION_TIMER = 1,
PAUSEANDPLAY_BTN = 2, FINISH_BTN = 3;
public ActionHolder(Context context) {
super(context);
}
public ActionHolder(Context context, AttributeSet attr) {
super(context, attr);
}
public ActionHolder(Context context, AttributeSet attr, int defStyle) {
super(context, attr, defStyle);
}
public void initiate(Action input) {
// int hashedID = input.getActionName().hashCode();
// if (hashedID < 0)
// hashedID *= -1;
// this.setId(hashedID);
this.setOrientation(LinearLayout.VERTICAL);
this.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
action = input;
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.action_holder_layout, this, true);
TextView actionTitle = (TextView) view
.findViewById(com.tonimiko.mochi_bean.R.id.action_holder_title);
actionTitle.setText(action.getActionName());
actionTitle.setId(ActionHolder.ACTION_TITLE);
TextView actionTimer = (TextView) view
.findViewById(R.id.action_holder_timer);
actionTimer.setId(ActionHolder.ACTION_TIMER);
Button pauseBtn = (Button) view
.findViewById(com.tonimiko.mochi_bean.R.id.pause_and_play_timer_btn);
pauseBtn.setId(ActionHolder.PAUSEANDPLAY_BTN);
Button finishBtn = (Button) view
.findViewById(com.tonimiko.mochi_bean.R.id.finish_activity_button);
finishBtn.setId(ActionHolder.FINISH_BTN);
action.setActivityStartTime();
}
public Action finishAction() {
action.setActivityStopTime();
return action;
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
}
public String toString() {
return "Action stored: " + action.getActionName();
}
#Override
public boolean equals(Object other) {
ActionHolder otherObj = (ActionHolder) other;
if (this.action.getActionName().toUpperCase()
.equals(otherObj.action.getActionName().toUpperCase()))
return true;
return false;
}
#Override
public int hashCode() {
return action.getActionName().hashCode();
}
#Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
Bundle data = new Bundle();
data.putString("Timer", timer);
data.putSerializable("Action", action);
Log.e("debug", "View onSaveInstanceState called!"); // TODO
Parcelable test = new ActionHolderSavedState(superState, data);
if(test==null)
Log.e("debug", "NULL PARCELABLE"); // TODO
return new ActionHolderSavedState(superState, data);
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
Log.e("debug", "View onRestore called!");
if (state instanceof ActionHolderSavedState) {
final ActionHolderSavedState savedState = (ActionHolderSavedState) state;
this.action = savedState.getAction();
this.timer = savedState.getTimer();
// this.initiate(action);
super.onRestoreInstanceState(savedState.getSuperState());
Log.e("debug", "View onRestoreInstanceState finished"); // TODO
}
}
static class ActionHolderSavedState extends BaseSavedState {
private Action storedAction;
private String storedTimer;
public ActionHolderSavedState(Parcelable superState, Bundle data) {
super(superState);
storedTimer = data.getString("Timer");
storedAction = (Action) data.getSerializable("Action");
}
private ActionHolderSavedState(Parcel in) {
super(in);
storedTimer = in.readString();
storedAction = in.readParcelable(ActionHolder.class.getClassLoader());
}
public Action getAction() {
return storedAction;
}
public String getTimer() {
return storedTimer;
}
#Override
public void writeToParcel(final Parcel out, final int flags) {
super.writeToParcel(out, flags);
out.writeString(storedTimer);
out.writeSerializable(storedAction);
}
// required field that makes Parcelables from a Parcel
public static final Parcelable.Creator<ActionHolderSavedState> CREATOR = new Parcelable.Creator<ActionHolderSavedState>() {
public ActionHolderSavedState createFromParcel(final Parcel in) {
return new ActionHolderSavedState(in);
}
public ActionHolderSavedState[] newArray(int size) {
return new ActionHolderSavedState[size];
}
};
}
}
Is there SOMETHING I am doing wrong? I've spend almost 4 days already on this.
I have a situation very similar to yours, with custom views being added dynamically to the screen and that need to save state when the activity is killed by the OS and recreated later, for example.
I'm overriding onSaveInstanceState on the custom view. It needs to return a Parcelable object. The key is to create a custom class that extends BaseSavedState and stores your data into that Parcelable. It would look somewhat like this:
#Override
protected Parcelable onSaveInstanceState() {
final Parcelable state = super.onSaveInstanceState();
return new ContainerLayoutSavedState(state, data);
}
#Override
protected void onRestoreInstanceState(final Parcelable state) {
if (state instanceof ContainerLayoutSavedState) {
final ContainerLayoutSavedState savedState = (ContainerLayoutSavedState)state;
this.data = savedState.getData();
super.onRestoreInstanceState(savedState.getSuperState());
}
}
public static class ContainerLayoutSavedState extends BaseSavedState {
private String data;
ContainerLayoutSavedState(final Parcelable superState, final String data) {
super(superState);
// Here in this constructor you inject whatever you want to get saved into the Parcelable object. In this contrived example, we're just saving a string called data.
this.data = data;
}
private ContainerLayoutSavedState(final Parcel in) {
super(in);
data = in.readString();
}
public String getData()
return data;
}
#Override
public void writeToParcel(final Parcel out, final int flags) {
super.writeToParcel(out, flags);
out.writeString(data);
}
// required field that makes Parcelables from a Parcel
public static final Parcelable.Creator<ContainerLayoutSavedState> CREATOR = new Parcelable.Creator<ContainerLayoutSavedState>() {
#Override
public ContainerLayoutSavedState createFromParcel(final Parcel in) {
return new ContainerLayoutSavedState(in);
}
#Override
public ContainerLayoutSavedState[] newArray(final int size) {
return new ContainerLayoutSavedState[size];
}
};
} }
Also, don't forget to set IDs to your dynamically added views, so they get re-added to the View tree when you come back.
Assume you want to derive your own View class from an existing View implementation, adding a bit of value, hence maintaining a few variables which represent your View's state in a meaningful way.
It would be nice if your View would save its state automatically just like others do (if an ID is assigned) so you would want to override onRestoreInstanceState() and onSaveInstanceState().
Of course, you need to call the respective methods of your base class, and you need to combine your state information with that of your base class.
Obviously, the only safe way to do so is to wrap your super class' Parcelable in an own Parcelable such that the keys won't get mixed up.
Now there's View.BaseSavedState and its interesting getSuperState() method but I somehow fail to understand how this really adds value to just storing the base class' Parcelable in a Bundle along with the derived View's state values and return that. On the other hand, maybe some other system component will expect all InstanceState information to be of type View.AbsSavedState (e.g. such that getSuperState() can be called)?
Any experiences you're willing to share?
To complement James Chen's answer, here is a full example of how to use this method, based on blog article by Charles Harley.
Code from the link:
public class LockCombinationPicker extends LinearLayout {
private NumberPicker numberPicker1;
private NumberPicker numberPicker2;
private NumberPicker numberPicker3;
public LockCombinationPicker(Context context) {
this(context, null);
}
public LockCombinationPicker(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LockCombinationPicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
loadViews();
}
private void loadViews() {
LayoutInflater.from(getContext()).inflate(R.layout.lock_combination_picker, this, true);
numberPicker1 = (NumberPicker) findViewById(R.id.number1);
numberPicker1.setMinValue(0);
numberPicker1.setMaxValue(10);
numberPicker2 = (NumberPicker) findViewById(R.id.number2);
numberPicker2.setMinValue(0);
numberPicker2.setMaxValue(10);
numberPicker3 = (NumberPicker) findViewById(R.id.number3);
numberPicker3.setMinValue(0);
numberPicker3.setMaxValue(10);
}
#Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
return new SavedState(superState, numberPicker1.getValue(), numberPicker2.getValue(), numberPicker3.getValue());
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
numberPicker1.setValue(savedState.getNumber1());
numberPicker2.setValue(savedState.getNumber2());
numberPicker3.setValue(savedState.getNumber3());
}
#Override
protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
// As we save our own instance state, ensure our children don't save and restore their state as well.
super.dispatchFreezeSelfOnly(container);
}
#Override
protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
/** See comment in {#link #dispatchSaveInstanceState(android.util.SparseArray)} */
super.dispatchThawSelfOnly(container);
}
/**
* Convenience class to save / restore the lock combination picker state. Looks clumsy but once created is easy to maintain and use.
*/
protected static class SavedState extends BaseSavedState {
private final int number1;
private final int number2;
private final int number3;
private SavedState(Parcelable superState, int number1, int number2, int number3) {
super(superState);
this.number1 = number1;
this.number2 = number2;
this.number3 = number3;
}
private SavedState(Parcel in) {
super(in);
number1 = in.readInt();
number2 = in.readInt();
number3 = in.readInt();
}
public int getNumber1() {
return number1;
}
public int getNumber2() {
return number2;
}
public int getNumber3() {
return number3;
}
#Override
public void writeToParcel(Parcel destination, int flags) {
super.writeToParcel(destination, flags);
destination.writeInt(number1);
destination.writeInt(number2);
destination.writeInt(number3);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
I think the design needs us, and as the name implies, to implement a subclass of View.BaseSavedState to store values by overriding Parcelable's interface.
TextView.SavedState is a good example
public static class SavedState extends BaseSavedState {
int selStart;
int selEnd;
CharSequence text;
boolean frozenWithFocus;
CharSequence error;
SavedState(Parcelable superState) {
super(superState);
}
#Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(selStart);
out.writeInt(selEnd);
out.writeInt(frozenWithFocus ? 1 : 0);
TextUtils.writeToParcel(text, out, flags);
if (error == null) {
out.writeInt(0);
} else {
out.writeInt(1);
TextUtils.writeToParcel(error, out, flags);
}
}
#Override
public String toString() {
String str = "TextView.SavedState{"
+ Integer.toHexString(System.identityHashCode(this))
+ " start=" + selStart + " end=" + selEnd;
if (text != null) {
str += " text=" + text;
}
return str + "}";
}
#SuppressWarnings("hiding")
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];
}
};
private SavedState(Parcel in) {
super(in);
selStart = in.readInt();
selEnd = in.readInt();
frozenWithFocus = (in.readInt() != 0);
text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
if (in.readInt() != 0) {
error = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
}
}
}