How to pass a parcelable object that contains a li

2019-01-12 22:42发布

问题:

I have created a Parcelable object below, my object contains a List of Products. In my constructor how do I handle re-creating my Parcelable for the List?

I have checked all of the methods available from the parcel and all that is available is readArrayList(ClassLoader). I'm not sure if this is the best approach, your advice would really be appreciated.

public class Outfits implements Parcelable {

    private String url;
    private String name;
    private List<Product> products;

    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Product> getProducts() {
        return products;
    }
    public void setProducts(List<Product> products) {
        this.products = products;
    }

    public void writeToParcel(Parcel dest, int flags) {
        Log.v("", "writeToParcel..." + flags);
        dest.writeString(url);
        dest.writeString(name);
        dest.writeList(products);
    }


    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public Outfits createFromParcel(Parcel in) {
            return new Outfits(in);
        }

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

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

    /*** Here how do I populate my List of Products ***/
    private Outfits(Parcel in) {
        url = in.readString();
        name = in.readString();
        products = in.read ???????;
    }
}

回答1:

If class Product is compatible with parcelable protocol, following should work according to documentation.

products = new ArrayList<Product>();
in.readList(products,null);


回答2:

First, your Product object must implements Parcelable.

And then, use dest.writeTypedList(products) in writeToParcel() method.

Finally, use following code to parse the list:

products = new ArrayList<Product>();
in.readTypedList(products, Product.CREATOR);

For more infomation, please reference the Official Document:



回答3:

This should work:

in.readTypedList(products, Product.CREATOR);


回答4:

In my personal experience, http://www.parcelabler.com/ is an amazing site for this. You just create your class, and copy paste it into the website, and it generates a Parcelable version of your class.

I tested it with a class named "Theme" that contained the following variables:

private String name;
private int image;
private List<Card> cards;

The writeToParcel function becomes:

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(name);
    dest.writeInt(image);
    if (cards == null) {
        dest.writeByte((byte) (0x00));
    } else {
        dest.writeByte((byte) (0x01));
        dest.writeList(cards);
    }
}

generated constructor:

protected Theme(Parcel in) {
    name = in.readString();
    image = in.readInt();
    if (in.readByte() == 0x01) {
        cards = new ArrayList<Card>();
        in.readList(cards, Card.class.getClassLoader());
    } else {
        cards = null;
    }
}

EDIT: make sure that the Card object is also Parcelable!



回答5:

implement Parcelable on the Product class as well and then

in.readList(this.list, Product.class.getClassLoader());

if any of the above solutions didn't work.



回答6:

The other way is to use readValue&writeValue.

protected Product (Parcel in) {
        ...
        in.readValue(this.getClass().getClassLoader());
    }

@Override
public void writeToParcel(Parcel parcel, int i) {
    ...
    parcel.writeValue(**list**);
}

Items of the list should implement Parcelable