Search code examples
javaandroidinner-classesparcelable

Nested Class Parcelable


I need to know how to make a nested class Parcelable.

When I create a nested class I get an error (it requires the parcel as a param.)

Code:

public class BookingDetailsItem implements Parcelable {
    private ServiceProviderItem serviceProvider;

    public Appointment appointmentDetails;
    private String notes;

    public BookingDetailsItem(ServiceProviderItem serviceProvider)
    {
        this.serviceProvider = serviceProvider;
        appointmentDetails = new Appointment();  // here it requires the parcel as required parameter
    }

    protected BookingDetailsItem(Parcel in) {
        serviceProvider = in.readParcelable(ServiceProviderItem.class.getClassLoader());
        appointmentDetails = in.readParcelable(Appointment.class.getClassLoader());
        notes = in.readString();
    }

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

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

    public String getNotes() {
        return notes;
    }

    public void setNotes(String notes) {
        this.notes = notes;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeParcelable(serviceProvider, flags);
        dest.writeParcelable(appointmentDetails, flags);
        dest.writeString(notes);
    }

    public static class Appointment implements Parcelable {
        private boolean isPickup;
        private Date servicingDate; // servicing date and time. In case of pickup, it will  be pick up date and time.

        private String additionalRequirements;

        protected Appointment(Parcel in) {
            isPickup = in.readByte() != 0;
            additionalRequirements = in.readString();
        }

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

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

        public boolean isPickup() {
            return isPickup;
        }

        public void setPickup(boolean pickup) {
            isPickup = pickup;
        }

        public Date getServicingDate() {
            return servicingDate;
        }

        public void setServicingDate(Date servicingDate) {
            this.servicingDate = servicingDate;
        }

        public String getAdditionalRequirements() {
            return additionalRequirements;
        }

        public void setAdditionalRequirements(String additionalRequirements) {
            this.additionalRequirements = additionalRequirements;
        }

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

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeByte((byte) (isPickup ? 1 : 0));
            dest.writeString(additionalRequirements);
        }
    }
}

Solution

  • The error appears because Appointment does not have a parameterless constructor. To fix this, just add a parameterless constructor:

    public Appointment() {}
    

    "Why did this work before I implemented Parcelable?" you might ask. This is because if a class has no constructors, a parameterless constructor is automatically and implicitly added for you. So after you added your constructor with the in parameter, the original parameterless constructor is lost.