Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write enum with String to parcel

I had Parcelable enum like this:

 public enum Option implements Parcelable {

    DATA_BASE, TRIPS, BIG_PHOTOS,
    OLD_PHOTOS, FILTERS_IMAGES,
    CATEGORIES_IMAGES, PAGES,
    SOUNDS, PUBLIC_TRANSPORT, MAPS;        

    public static final Parcelable.Creator<Option> CREATOR = new Parcelable.Creator<Option>() {

        public Option createFromParcel(Parcel in) {
            return Option.values()[in.readInt()];
        }

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

    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(ordinal());
    }
}

Now I modified it and it looks like:

 public enum Option implements Parcelable {

    DATA_BASE("Database"), TRIPS("Trips"), BIG_PHOTOS("BigPhotos"),
    OLD_PHOTOS("OldPhotos"), FILTERS_IMAGES("FiltersImages"),
    CATEGORIES_IMAGES("CategoriesImages"), PAGES("Pages"),
    SOUNDS("Sounds"), PUBLIC_TRANSPORT("PublicTransport"), MAPS("Maps");

    private String option;

    Option(String option){
        this.option = option;
    }

    public String getName(){
        return option;
    }

    public static final Parcelable.Creator<Option> CREATOR = new Parcelable.Creator<Option>() {

        public Option createFromParcel(Parcel in) {
            //...
        }

        public Option[] newArray(int size) {
            //...
        }

    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        //...
    }
}

How should I implement writeToParcel(), createFromParcel() and newArray() int this Enum? I need that to pass it through extra in intent.

like image 833
Dawid Hyży Avatar asked Aug 12 '14 11:08

Dawid Hyży


4 Answers

This is an old question but there is a better solution:

dest.writeString(myEnumOption.name());

and

myEnumOption = MyEnum.valueOf(in.readString());
like image 66
Nick Cardoso Avatar answered Nov 15 '22 20:11

Nick Cardoso


It may be late for the OP, but it may help others, so I'll still post this.

  1. As it was mentioned before, it's a bad practice to have a setter to an enum's member. If you need that member, make it final (which excludes the possibility of a setter for it)

  2. You don't need to save that member (in your case the String 'option') into the Parcel and restore it on recreation.

My implementation would be as follows

public enum Option implements Parcelable {

    DATA_BASE("Database"), TRIPS("Trips"), BIG_PHOTOS("BigPhotos"),
    OLD_PHOTOS("OldPhotos"), FILTERS_IMAGES("FiltersImages"),
    CATEGORIES_IMAGES("CategoriesImages"), PAGES("Pages"),
    SOUNDS("Sounds"), PUBLIC_TRANSPORT("PublicTransport"), MAPS("Maps");

    private final String option;

    Option(String option){
        this.option = option;
    }

    public String getName() {
        return option;
    }

    public static final Parcelable.Creator<Option> CREATOR = new Parcelable.Creator<Option>() {

        public Option createFromParcel(Parcel in) {
            return values()[in.readInt()];
        }

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

    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(ordinal());
    }

}
like image 34
Cosmin Radu Avatar answered Nov 15 '22 21:11

Cosmin Radu


I solved it by:

public enum Option implements Parcelable {

    DATA_BASE("Database"), TRIPS("Trips"), BIG_PHOTOS("BigPhotos"),
    OLD_PHOTOS("OldPhotos"), FILTERS_IMAGES("FiltersImages"),
    CATEGORIES_IMAGES("CategoriesImages"), PAGES("Pages"),
    SOUNDS("Sounds"), PUBLIC_TRANSPORT("PublicTransport"), MAPS("Maps");

    private String option;

    Option(String option){
        this.option = option;
    }

    public String getName(){
        return option;
    }

    private void setOption(String option){
        this.option = option;
    }

    public static final Parcelable.Creator<Option> CREATOR = new Parcelable.Creator<Option>() {

        public Option createFromParcel(Parcel in) {
            Option option = Option.values()[in.readInt()];
            option.setOption(in.readString());
            return option;
        }

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

    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(ordinal());
        out.writeString(option);
    }
}
like image 4
Dawid Hyży Avatar answered Nov 15 '22 20:11

Dawid Hyży


If the only reason you're making your enum Parcelable is to pass it in an Intent, you don't need to to that. enums are Serializable, so you can pass it like:

intent.putExtra("EnumValue", Option.DATA_BASE);

and retrieve it using:

Option myEnum = (Option) intent.getSerializableExtra("EnumValue");
like image 1
HexAndBugs Avatar answered Nov 15 '22 19:11

HexAndBugs