Bagaimana cara melewatkan objek parcelable yang berisi daftar objek?


96

Saya telah membuat Parcelableobjek di bawah ini, objek saya berisi ListProduk. Dalam konstruktor saya, bagaimana cara menangani pembuatan ulang saya Parcelableuntuk List?

Saya telah memeriksa semua metode yang tersedia dari parsel dan semua yang tersedia adalah readArrayList(ClassLoader). Saya tidak yakin apakah ini pendekatan terbaik, saran Anda akan sangat dihargai.

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

Dan apa yang salah readList()?
Alex Gitelman

Metode readList (List, ClassLoader) dalam tipe Parcel tidak berlaku untuk argumen ()
Byron

Tidak ada yang salah dengan argumen. Begitulah cara daftar sering digunakan. Saya menambahkan jawaban.
Alex Gitelman

Jawaban:


103

Jika kelas Productkompatibel dengan protokol parcelable, berikut harus bekerja sesuai dengan dokumentasi.

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

Belum tentu. Dokumentasi menyatakan bahwa writeList()akan menulis objek menurut spesifikasi yang dijelaskan oleh writeValue()metode. developer.android.com/reference/android/os/… Antara lain dikatakan bahwa objek dapat bersambung. readList()adalah mitra writeList()dan akan membaca data yang sama.
Alex Gitelman

6
@AlexGitelman Tetapi menggunakan serialisasi dianggap buruk untuk kinerja sebelumnya, jadi itulah mengapa mereka membuat Parcable tersedia, bukankah doig yang membuat ini tidak berguna?
eric.itzhak

30
Saya tidak beruntung menggunakan solusi ini sebagaimana adanya. ClassLoader null in.readList(products,null);, mendapatkan pengecualian seperti ... Disebabkan oleh: android.os.BadParcelableException: ClassNotFoundException saat membatalkan marshalling: com.example.MyApplication.Product. Variasi untuk membaca daftar yang benar-benar cocok untuk saya adalahin.readList(products,Product.class.getClassLoader());
Peter Dietz

2
Juga jangan lupa bahwa Produk perlu mengimplementasikan Serializable
agmezr

40

Pertama, objek Produk Anda harus diimplementasikan Parcelable.

Dan kemudian, gunakan dest.writeTypedList(products)di writeToParcel()metode.

Terakhir, gunakan kode berikut untuk mengurai daftar:

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

Untuk informasi lebih lanjut, silakan lihat Dokumen Resmi :


6

Dalam pengalaman pribadi saya, http://www.parcelabler.com/ adalah situs yang luar biasa untuk ini. Anda cukup membuat kelas Anda, dan menyalinnya ke situs web, dan itu menghasilkan versi Parcelable dari kelas Anda.

Saya mengujinya dengan kelas bernama "Tema" yang berisi variabel berikut:

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

Fungsi writeToParcel menjadi:

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

konstruktor yang dihasilkan:

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: pastikan bahwa objek Kartu juga Dapat Dipaketkan!


5

Ini harus bekerja:

in.readTypedList(products, Product.CREATOR);

1
Ini menciptakan masalah bagi saya, ini bekerja lebih baik: products = new ArrayList<Product>(); in.readList(products, Product.class.getClassLoader());
Shyam Sunder

1

terapkan Parcelablepada kelas Produk juga dan kemudian

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

jika salah satu solusi di atas tidak berhasil.


1

Cara lainnya adalah dengan menggunakan readValue & writeValue .

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

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

Item dari daftar harus menerapkan Parcelable


1

Ini dia ...

Pastikan "Products.java" harus diperluas dengan Parcelable

Langkah 1:

 private List<Products> products; 

Langkah 2:

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

Langkah 3:

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

0

Dengan asumsi Productsedang mengimplementasikan Parcelable, Anda dapat menggunakan ini untuk menulis:

dest.writeValue(products);

dan ini untuk membaca:

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

0

Produk harus menerapkan Parcelable

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

Kemudian tulis objek Anda berisi daftar seperti

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

     }

 }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.