107 votes

Comment passer un objet parcellisable qui contient une liste d'objets ?

J'ai créé un Parcelable ci-dessous, mon objet contient un List de produits. Dans mon constructeur, comment puis-je gérer la recréation de mes produits ? Parcelable pour le List ?

J'ai vérifié toutes les méthodes disponibles dans le colis et tout ce qui est disponible est readArrayList(ClassLoader) . Je ne suis pas sûr que ce soit la meilleure approche, votre avis serait vraiment apprécié.

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

0 votes

Et quel est le problème avec readList() ?

0 votes

La méthode readList(List, ClassLoader) dans le type Parcel n'est pas applicable pour les arguments ()

0 votes

Rien de mal avec les arguments. C'est ainsi que les listes sont souvent utilisées. J'ai ajouté la réponse.

109voto

Alex Gitelman Points 15062

Si la classe Product est compatible avec le protocole parcelable, ce qui suit devrait fonctionner selon la documentation.

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

0 votes

Pas nécessairement. La documentation indique que writeList() écrira des objets selon les spécifications décrites par writeValue() méthode. developer.Android.com/reference/Android/os/ Entre autres choses, il est dit que l'objet peut être Serializable. readList() est la contrepartie de writeList() et liront les mêmes données.

6 votes

@AlexGitelman Mais l'utilisation de la sérialisation est considérée comme mauvaise pour la performance, c'est pourquoi ils ont rendu Parcable disponible, est-ce que cela ne rendrait pas cela inutile ?

30 votes

Je n'ai pas eu de chance en utilisant cette solution telle quelle. Le ClassLoader de null in.readList(products,null); Je reçois des exceptions comme... Causé par : Android.os.BadParcelableException : ClassNotFoundException when unmarshalling : com.example.MyApplication.Product. La variante de lecture de la liste qui fonctionne réellement pour moi est la suivante in.readList(products,Product.class.getClassLoader());

41voto

codezjx Points 6567

D'abord, votre objet Produit doit implémenter Parcelable .

Et ensuite, utilisez dest.writeTypedList(products) en writeToParcel() méthode.

Enfin, utilisez le code suivant pour analyser la liste :

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

Pour plus d'informations, veuillez consulter le Document officiel :

6voto

Pieter Desseyn Points 73

D'après mon expérience personnelle, http://www.parcelabler.com/ est un site extraordinaire pour cela. Il vous suffit de créer votre classe, de la copier-coller dans le site web, et il génère une version Parcelable de votre classe.

Je l'ai testé avec une classe nommée "Theme" qui contenait les variables suivantes :

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

La fonction writeToParcel devient :

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

généré par le constructeur :

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 : assurez-vous que l'objet Carte est également Parcelable !

5voto

user3875399 Points 69

Cela devrait fonctionner :

in.readTypedList(products, Product.CREATOR);

3voto

Shyam Kumar Points 291

Voilà...

Assurez-vous que "Products.java" doit être étendu avec Parcelable.

Étape 1 :

 private List<Products> products; 

Étape 2 :

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

Étape 3 :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X