Làm thế nào để truyền một đối tượng có thể phân chia có chứa danh sách các đối tượng?


96

Tôi đã tạo một Parcelableđối tượng bên dưới, đối tượng của tôi chứa một Listtrong số các Sản phẩm. Trong hàm tạo của tôi, làm cách nào để xử lý việc tạo lại của tôi Parcelablecho List?

Tôi đã kiểm tra tất cả các phương pháp có sẵn từ bưu kiện và tất cả những gì có sẵn đều có readArrayList(ClassLoader). Tôi không chắc liệu đây có phải là cách tốt nhất hay không, lời khuyên của bạn sẽ thực sự được đánh giá cao.

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

Và có gì sai với readList()?
Alex Gitelman

Phương thức readList (Danh sách, ClassLoader) trong loại Parcel không áp dụng cho các đối số ()
Byron

Không có gì sai với các lập luận. Đó là cách danh sách thường được sử dụng. Tôi đã thêm câu trả lời.
Alex Gitelman

Câu trả lời:


102

Nếu lớp Producttương thích với giao thức có thể phân loại, thì phần sau sẽ hoạt động theo tài liệu.

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

Không cần thiết. Tài liệu nói rằng writeList()sẽ viết các đối tượng theo các thông số kỹ thuật được mô tả bằng writeValue()phương pháp. developer.android.com/reference/android/os/… Trong số những thứ khác, nó nói rằng đối tượng có thể được Serializable. readList()là đối tác của writeList()và sẽ đọc cùng một dữ liệu.
Alex Gitelman

6
@AlexGitelman Nhưng sử dụng tuần tự hóa được coi là không tốt cho hiệu suất, vì vậy đó là lý do tại sao họ cung cấp Parcable, có phải doig làm cho điều này trở nên vô nghĩa?
eric.itzhak

30
Tôi đã không gặp may khi sử dụng giải pháp này. ClassLoader của null in.readList(products,null);, nhận các ngoại lệ như ... Gây ra bởi: android.os.BadParcelableException: ClassNotFoundException khi unmarshalling: com.example.MyApplication.Product. Các biến thể đọc danh sách đó thực sự hoạt động đối với tôi làin.readList(products,Product.class.getClassLoader());
Peter Dietz

2
Cũng đừng quên rằng nhu cầu sản phẩm để thực hiện Serializable
agmezr

40

Đầu tiên, đối tượng Sản phẩm của bạn phải triển khai Parcelable.

Và sau đó, sử dụng dest.writeTypedList(products)trong writeToParcel()phương pháp.

Cuối cùng, sử dụng mã sau để phân tích cú pháp danh sách:

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

Để biết thêm thông tin, vui lòng tham khảo Tài liệu chính thức :


6

Theo kinh nghiệm cá nhân của tôi, http://www.parcelabler.com/ là một trang web tuyệt vời cho việc này. Bạn chỉ cần tạo lớp học của mình và sao chép, dán nó vào trang web và nó tạo ra phiên bản Có thể thay thế của lớp học của bạn.

Tôi đã thử nghiệm nó với một lớp có tên "Chủ đề" chứa các biến sau:

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

Hàm writeToParcel trở thành:

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

hàm tạo được tạo:

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

CHỈNH SỬA: đảm bảo rằng đối tượng Thẻ cũng là Có thể thay thế!


5

Điều này sẽ hoạt động:

in.readTypedList(products, Product.CREATOR);

1
Nó được tạo ra vấn đề đối với tôi, điều này hoạt động tốt hơn: products = new ArrayList<Product>(); in.readList(products, Product.class.getClassLoader());
Shyam Sunder

1

triển khai Parcelabletrên lớp Sản phẩm và sau đó

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

nếu bất kỳ giải pháp nào ở trên không hoạt động.


1

Cách khác là sử dụng readValue & writeValue .

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

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

Các mục của danh sách nên triển khai Parcelable


1

Của bạn đây ...

Đảm bảo "Products.java" phải được mở rộng bằng Parcelable

Bước 1:

 private List<Products> products; 

Bước 2:

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

Bước 3:

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

0

Giả sử Productđang triển khai Parcelable, bạn có thể sử dụng điều này để viết:

dest.writeValue(products);

và cái này để đọc:

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

0

Sản phẩm phải được thực hiện Có thể bán được

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

Sau đó viết bạn đối tượng chứa danh sách như

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

     }

 }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.