Search code examples
androidparcelable

intent.putExtra a list of Parcelable objects and enums


This question is different from all the other questions because here the list of parcelable objects is created outside on the fly just sending it before via Intent.

Problem: Product is parcelable but the custom List<Product> is not. How to make the List Parcelable??

Product

public class Product implements Parcelable {

    public String id;
    public String name;

    public Product(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    protected Product(Parcel in) {
        id = in.readString();
        name = in.readString();
    }

    public static final Creator<Product> CREATOR = new Creator<Product>() {
        @Override
        public Product createFromParcel(Parcel in) {
            return new Product(in);
        }

        @Override
        public Product[] newArray(int size) {
            return new Product[size];
        }
    };

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(id);
        parcel.writeString(name);
    }
}

Activity class

Intent intent = new Intent(this, ShowProducts.class);
List<Product> products = getSpecificProducts();

intent.putExtra("PRODUCTS", products); // error

startActivity(intent);

Edit

The question is two fold, it's not a duplicate, the other part is List<Enum>

public enum Department implements Parcelable {

    SALES("Sales", 0),
    HR("HR", 1),

    public String name;
    public int ordinal;

    Department(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }

    public static final Creator<Department> CREATOR = new Creator<Department>() {
        @Override
        public Department createFromParcel(Parcel in) {
            return Department.values()[in.readInt()];
        }

        @Override
        public Department[] newArray(int size) {
            return new Department[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeInt(ordinal);
    }

}

Based on the suggested answers, I've tried.

List<Department> departments = getSpecificDepartments();

intent.putParcelableArrayListExtra("Departments", departments);

error: incompatible types: List<Department> cannot be converted to ArrayList<? extends Parcelable>


Solution

  • You don't need to make List parcelable. To put it, just use existing method.

    final Intent i = new Intent(this,SecondActivity.class);
    final ArrayList<Product> list = new ArrayList< Product >();
    i.putParcelableArrayListExtra(PRODUCT_KEY, list);
    startActivity(i);
    

    To retrieve almost in the same way.

    final ArrayList<Product> list = this.getIntent()
                .getParcelableArrayListExtra(PRODUCT_KEY);
    

    UPDATE

    To answer you newer question. You cannot pass generic List inside. Because by List you could have different collection. To know system, which type to use you need to have explicit type.

    // This will work. 
    final ArrayList<Department> departments = getSpecificDepartments();
    intent.putParcelableArrayListExtra(DEPARTMENTS_KEY, departments);