Come passare un oggetto parcellizzabile che contiene un elenco di oggetti?


96

Ho creato un Parcelableoggetto qui sotto, il mio oggetto contiene uno Listdei Prodotti. Nel mio costruttore come gestisco la ricreazione del mio Parcelableper il List?

Ho controllato tutti i metodi disponibili dal pacco e tutto ciò che è disponibile è readArrayList(ClassLoader). Non sono sicuro che questo sia l'approccio migliore, il tuo consiglio sarebbe davvero apprezzato.

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

E cosa c'è che non va readList()?
Alex Gitelman

Il metodo readList (List, ClassLoader) nel tipo Parcel non è applicabile per gli argomenti ()
Byron

Niente di sbagliato negli argomenti. È così che vengono spesso utilizzate le liste. Ho aggiunto la risposta.
Alex Gitelman

Risposte:


102

Se la classe Productè compatibile con il protocollo parcelable, seguire dovrebbe funzionare secondo la documentazione.

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

Non necessariamente. La documentazione afferma che writeList()scriverà gli oggetti in base alle specifiche descritte dal writeValue()metodo. developer.android.com/reference/android/os/… Tra le altre cose si dice che l'oggetto può essere serializzabile. readList()è la controparte di writeList()e leggerà gli stessi dati.
Alex Gitelman

6
@AlexGitelman Ma l'uso della serializzazione è considerato un male per le prestazioni, quindi è per questo che hanno reso disponibile Parcable, non lo farebbe lo rende inutile?
eric.itzhak

30
Non ho avuto fortuna nell'usare questa soluzione così com'è. Il ClassLoader di null in.readList(products,null);, ottenendo eccezioni come ... Caused by: android.os.BadParcelableException: ClassNotFoundException quando unmarshalling: com.example.MyApplication.Product. La variazione per leggere l'elenco che funziona davvero per me èin.readList(products,Product.class.getClassLoader());
Peter Dietz

2
Inoltre, non dimenticare che il prodotto deve implementare Serializable
agmezr

40

Innanzitutto, l'oggetto Product deve essere implementato Parcelable.

E poi, usa dest.writeTypedList(products)nel writeToParcel()metodo.

Infine, usa il seguente codice per analizzare l'elenco:

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

Per ulteriori informazioni, fare riferimento al documento ufficiale :


6

Nella mia esperienza personale, http://www.parcelabler.com/ è un sito straordinario per questo. Devi solo creare la tua classe e copiarla e incollarla nel sito web, e questo genera una versione Parcelable della tua classe.

L'ho testato con una classe denominata "Theme" che conteneva le seguenti variabili:

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

La funzione writeToParcel diventa:

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

costruttore generato:

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

MODIFICA: assicurati che anche l'oggetto Carta sia parcellizzabile!


5

Questo dovrebbe funzionare:

in.readTypedList(products, Product.CREATOR);

1
Mi sta creando problemi, funziona meglio: products = new ArrayList<Product>(); in.readList(products, Product.class.getClassLoader());
Shyam Sunder

1

implementare anche Parcelablesulla classe Product e poi

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

se una delle soluzioni di cui sopra non ha funzionato.


1

L'altro modo è usare readValue e writeValue .

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

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

Gli elementi della lista dovrebbero implementare Parcelable


1

Ecco qui...

Assicurati che "Products.java" dovrebbe essere esteso con Parcelable

Passo 1:

 private List<Products> products; 

Passo 2:

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

Passaggio 3:

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

0

Supponendo che Productsia implementato Parcelable, puoi usarlo per scrivere:

dest.writeValue(products);

e questo per leggere:

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

0

Il prodotto deve essere implementato Parcelable

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

Quindi scrivi che l'oggetto contiene l'elenco come

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

     }

 }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.