Android Parcelable Arraylist

Android Parcelable Arraylist

我正在制作一个非营利慈善应用程序。尽管我检查了堆栈中的许多问题并且google,但我无法解决问题。
我有 3 个 classes:
- BaseCell 实现 Parcelable (Base class)
- 需要扩展 BaseCell
- UserBasket class 包含所有 classes 扩展 BaseCell

的列表

问题

我在 UserBasket class 中持有带有 Arraylist 的 Needy classes。当我将它发送到另一个 activity 时,如果我将 1 项添加到 UserBasket,我会得到荒谬的结果(缺少或错误的字符),如果我添加超过 1 项,则会出现异常。
我需要将 UserBasket class(需要的物品列表)交付给付款 activity,这样我就可以计算慈善总价并执行必要的操作。

public abstract class BaseCell implements Parcelable {


String imageUrl;
int percentageOfCollectedDonation;
String needyTitle;
String needyDescription;

protected String category;
protected int amountOfCollectedDonation=0;
protected int amountOfTargetDonation=0;
protected int amountOfDonater=0;
protected int drawableID;
protected String campaignCode;

protected int maxInstallmentNumber;

int price;

public String getCellType() {
    return cellType;
}

protected String cellType ;

/**
 * How many of this campaign purchased by user
 * */
protected int userPurchaseAmount = 1;

protected BaseCell(String cellType)
{
    this.cellType = cellType;
}
protected BaseCell(Parcel in)
{

    drawableID = in.readInt();
    price = in.readInt();
    imageUrl = in.readString();
    needyTitle = in.readString();
    needyDescription = in.readString();
    category = in.readString();
    campaignCode = in.readString();
    maxInstallmentNumber = in.readInt();
    userPurchaseAmount = in.readInt();
}

public static final Parcelable.Creator<BaseCell> CREATOR = new Parcelable.Creator<BaseCell>() {
    @Override
    public BaseCell createFromParcel(Parcel in) {
        String cellType = in.readString();
        BaseCell baseCell = null;

        if (cellType.equals("Needy"))
        {
            baseCell = (Needy)new Needy(in);
        }else
        if (cellType.equals("Qurban"))
        {
            baseCell = (Qurban)new Qurban(in);
        }

        return baseCell;
    }

    @Override
    public BaseCell[] newArray(int size) {
        return new BaseCell[size];
    }
};
public void writeToParcel(Parcel out, int flags) {
    out.writeString(getCellType());
}


public BaseCell(String imageUrl, int drawableID, String needyTitle, String needyDescription, int amountOfCollectedDonation, int amountOfTargetDonation, int amountOfDonater, String category,String campaignCode, int maxInstallmentNumber, int price)
{
    this.imageUrl = imageUrl;
    this.drawableID = drawableID;
    this.needyTitle = needyTitle;
    this.needyDescription = needyDescription;
    this.amountOfCollectedDonation = amountOfCollectedDonation;
    this.amountOfTargetDonation = amountOfTargetDonation;
    this.amountOfDonater = amountOfDonater;
    this.category = category;
    this.campaignCode = campaignCode;
    this.maxInstallmentNumber = maxInstallmentNumber;
    this.price= price;
}


}


有需要

    public class Needy extends BaseCell {

    protected Needy(Parcel in) {
    super(in);
    cellType ="Needy";
    }



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

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


public Needy(String imageUrl, int drawableID, String needyTitle, String needyDescription, int amountOfCollectedDonation, int amountOfTargetDonation, int amountOfDonater, String category, String campaignCode, int maxInstallmentNumber, int price) {

    super(imageUrl, drawableID, needyTitle, needyDescription, amountOfCollectedDonation, amountOfTargetDonation, amountOfDonater, category, campaignCode, maxInstallmentNumber,price);
    cellType = "Needy";
}


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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(getCellType());
    super.writeToParcel(dest,flags);
    dest.writeInt(drawableID);
    dest.writeInt(price);
    dest.writeString(imageUrl);
    dest.writeString(needyTitle);
    dest.writeString(needyDescription);
    dest.writeString(category);
    dest.writeString(campaignCode);
    dest.writeInt(maxInstallmentNumber);
    dest.writeInt(userPurchaseAmount);
}

@Override
public void setUserPurchaseAmount(int userPurchaseAmount) {
    super.setUserPurchaseAmount(userPurchaseAmount);
 }
}


用户篮

    public class UserBasket implements Parcelable{


List<BaseCell> userBasket;

/**
 * holds all items to be purchased
 * */
public UserBasket(List<BaseCell> userBasket) {
    this.userBasket = userBasket;
}

public UserBasket() {
    userBasket = new ArrayList<>();
}


protected UserBasket(Parcel in) {
    super();
    setUserBasket(new ArrayList<BaseCell>());
    userBasket = in.createTypedArrayList(BaseCell.CREATOR);
    //in.readTypedList(userBasket,BaseCell.CREATOR);
}

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

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

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

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



public List<BaseCell> getUserBasket() {
    return userBasket;
}

public void setUserBasket(List<BaseCell> userBasket) {
    this.userBasket = userBasket;
}

/**
 * Add to the basket list
 * */
public void add(Needy donation) {
    if (donation != null)
        userBasket.add(donation);
}

/**
 * Remove from basket list
 * */
public void remove(int position)
{
    if (userBasket.size()>0)
        userBasket.remove(position);
}

}


向 userBasket arrayList 发送来自 MainActivity

的项目 Navigate.navigateToPaymentPayuStart (MainActivity.this,userBasket,"basket"); // userBasket arrayList with "basket" key
在 paymentPayu 中接收 UserBasket activity
UserBasket userBasket = getIntent().getParcelableExtra("basket");
我如何在 paymentPayuActivity 中正确获取 UserBasket。
感谢您的帮助
谢谢。

看来您对 Parcelable 实施的处理有误。 e.i。您正在两次读取 Parcel 中的某些变量,这是不允许的。因此,为了改进这一点,我们将尝试使您的代码更简单一些。由于 Needy 实际上没有任何变量,让 BaseCell 处理所有可打包的实现似乎更好,我已经尝试为您创建一个模拟,因此取决于您的其余代码它可能需要一些调整。

首先,我删除了 Needy 中的所有 Parcelable 实现,只是将 CREATOR 指向 BaseCell

public class Needy extends BaseCell {

    protected Needy(Parcel in) {
        super(in);
        cellType ="Needy";
    }

    // Since Needy doesn't actually store any variables, we don't need a Creator for it.
    // Just point it to BaseCell.CREATOR and let it handle it
    public static final Parcelable.Creator<BaseCell> CREATOR = BaseCell.CREATOR;

    public Needy(String imageUrl, int drawableID, String needyTitle, String needyDescription, int amountOfCollectedDonation, int amountOfTargetDonation, int amountOfDonater, String category, String campaignCode, int maxInstallmentNumber, int price) {
        super(imageUrl, drawableID, needyTitle, needyDescription, amountOfCollectedDonation, amountOfTargetDonation, amountOfDonater, category, campaignCode, maxInstallmentNumber,price);
        cellType = "Needy";
    }

}

然后我们将让 BaseCell 处理所有 Parcelable 实现,如下所示:

public abstract class BaseCell implements Parcelable {

    /**
     * ALL OF YOUR VARIABLES, GETTERS, SETTERS AND CONSTRUCTORS GOES HERE
     */

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

    public static final Parcelable.Creator<BaseCell> CREATOR = new Parcelable.Creator<BaseCell>() {
        @Override
        public BaseCell createFromParcel(Parcel in) {
            String cellType = in.readString();
            if (cellType.equals("Needy")) {
                return (Needy)new Needy(in);
            } else if (cellType.equals("Qurban")) {
                return (Qurban)new Qurban(in);
            }
            return null;
        }

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

    protected BaseCell(Parcel in) {
        drawableID = in.readInt();
        price = in.readInt();
        imageUrl = in.readString();
        needyTitle = in.readString();
        needyDescription = in.readString();
        category = in.readString();
        campaignCode = in.readString();
        maxInstallmentNumber = in.readInt();
        userPurchaseAmount = in.readInt();
    }

    public void writeToParcel(Parcel out, int flags) {
        // cellType written first, and read by Creator
        out.writeString(cellType);
        // the rest is read by the BaseCell constructor
        out.writeInt(drawableID);
        out.writeInt(price);
        out.writeString(imageUrl);
        out.writeString(needyTitle);
        out.writeString(needyDescription);
        out.writeString(category);
        out.writeString(campaignCode);
        out.writeInt(maxInstallmentNumber);
        out.writeInt(userPurchaseAmount);
    }

}