Byron
Byron

Reputation: 3913

How to pass a parcelable object that contains a list of objects?

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 ???????;
    }
}

Upvotes: 107

Views: 88023

Answers (9)

Ven Ren
Ven Ren

Reputation: 3408

Product must be implements Parcelable

  Product class implements  Parcelable {
          ......
  }

Then write you object contains list like

public class Outfits implements Parcelable {

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

     public Outfits (Parcel pi) {

        bookName = p.readString();
        bookId = p.readInt();
        isColor = p.readInt() == 1;

        //use this well be get err
        //products=p.readArrayList(Thread.currentThread().getContextClassLoader());

        //Pass list use this 
        products= in.createTypedArrayList(Product.CREATOR);

      }

            ...get and set...

     public void writeToParcel(Parcel dest, int flags) {


        dest.writeString(url);
        dest.writeString(name);

        //use this will no working
        //dest.writeList(products);

        //Parcelable list
        out.writeTypedList(products);

     }

 }

Upvotes: 0

arenaq
arenaq

Reputation: 2380

Assuming the Product is implementing Parcelable, you can use this for writing:

dest.writeValue(products);

and this for reading:

products = (List<Product>) in.readValue(Product.class.getClassLoader());

Upvotes: 0

Alex Gitelman
Alex Gitelman

Reputation: 24732

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

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

Upvotes: 109

Shyam Kumar
Shyam Kumar

Reputation: 919

Here you go...

Make sure "Products.java" should be extended with Parcelable

Step 1:

 private List<Products> products; 

Step 2:

private Outfits(Parcel in) {
    products = in.createTypedArrayList(Products.CREATOR);
}

Step 3:

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeTypedList(products);
    }

Upvotes: 3

Pieter Desseyn
Pieter Desseyn

Reputation: 73

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!

Upvotes: 6

BlackRainbow
BlackRainbow

Reputation: 1904

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

Upvotes: 1

Faisal Naseer
Faisal Naseer

Reputation: 4258

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.

Upvotes: 1

codezjx
codezjx

Reputation: 9142

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:

Upvotes: 41

user3875399
user3875399

Reputation: 69

This should work:

in.readTypedList(products, Product.CREATOR);

Upvotes: 5

Related Questions