Как передать объект, который можно отправить, который содержит список объектов? - PullRequest
87 голосов
/ 10 июня 2011

Я создал объект Parcelable ниже, мой объект содержит List Продуктов. В моем конструкторе, как мне обработать воссоздание моего Parcelable для List?

Я проверил все методы, доступные в посылке, и все, что доступно, это readArrayList(ClassLoader). Я не уверен, что это лучший подход, ваш совет был бы очень признателен.

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

Ответы [ 8 ]

94 голосов
/ 10 июня 2011

Если класс Product совместим с протоколом посылки, в соответствии с документацией должно работать следующее.

products = new ArrayList<Product>();
in.readList(products, Product.class.getClassLoader());
36 голосов
/ 01 июля 2015

Во-первых, ваш объект Product должен реализовывать Parcelable.

И затем использовать dest.writeTypedList(products) в методе writeToParcel().

Наконец, используйте следующий код для анализа списка:

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

Для получения дополнительной информации, пожалуйста, обратитесь к Официальному документу :

5 голосов
/ 27 июля 2018

По моему личному опыту, http://www.parcelabler.com/ - замечательный сайт для этого. Вы просто создаете свой класс и копируете, вставляете его на веб-сайт, и он генерирует версию вашего класса, доступную для отправки.

Я протестировал его с классом "Theme", который содержал следующие переменные:

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

Функция writeToParcel становится:

@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);
    }
}

сгенерированный конструктор:

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

РЕДАКТИРОВАТЬ: убедитесь, что объект карты также Parcelable!

5 голосов
/ 03 июня 2015

Это должно работать:

in.readTypedList(products, Product.CREATOR);
1 голос
/ 26 января 2019

Вот, пожалуйста ...

Убедитесь, что «Products.java» следует расширить с помощью Parcelable

Шаг 1:

 private List<Products> products; 

Шаг 2:

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

Шаг 3:

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeTypedList(products);
    }
1 голос
/ 14 сентября 2017

Другой способ - использовать readValue & writeValue .

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

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

Элементы списка должны реализовывать Parcelable

1 голос
/ 30 января 2017

реализовать Parcelable в классе Product, а затем

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

если какое-либо из вышеперечисленных решений не сработало.

0 голосов
/ 20 февраля 2019

Предполагая, что Product реализует Parcelable, вы можете использовать это для записи:

dest.writeValue(products);

и это для чтения:

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