【问题标题】:Android Class Parcelable with ArrayListAndroid 类 Parcelable 与 ArrayList
【发布时间】:2014-04-22 04:27:19
【问题描述】:

我有一个 android 项目,我有一个类。那个班级是ArrayList<Choices>。我将获取一些 XML,将其解析出来,然后从中生成对象,然后将其传递给另一个活动。我为此选择 Parcelable。

Parcelable 是一个不错的选择吗?我做的一切正确吗?我对 Parcelable 并不熟悉。我的 ArrayList 是我在这个类中创建的另一个类。它会正确地将对象的 ArrayList 传递给 Parcel,而不会扩展 Parcelable 和其他东西吗?

import java.util.ArrayList;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.os.ParcelableCompat;

public class Question implements Parcelable{


String id;
String text;
String image;
ArrayList<Choices> CHOICES;


public Question(String id, String text, String image) {
    super();
    this.id = id;
    this.text = text;
    this.image = image;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getText() {
    return text;
}

public void setText(String text) {
    this.text = text;
}

public String getImage() {
    return image;
}

public void setImage(String image) {
    this.image = image;
}

@Override
public String toString() {
    return "Question [id=" + id + ", text=" + text + ", image=" + image
            + "]";
}




// Answer Choices class
class Choices {

    boolean isCorrect;
    String choice;

    public Choices(boolean isCorrect, String choice) {
        this.isCorrect = isCorrect;
        this.choice = choice;
    }

    public String getChoice() {
        return choice;
    }

    public boolean getIsCorrect() {
        return isCorrect;
    }

    @Override
    public String toString() {
        return "Choices [isCorrect=" + isCorrect + ", choice=" + choice
                + "]";
    }

}


public static final Parcelable.Creator<Question> CREATOR = new Parcelable.Creator<Question>() {

    @Override
    public Question createFromParcel(Parcel in) {
        return new Question(in);
    }

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

};

@Override
public int describeContents() {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {

    dest.writeString(id);
    dest.writeString(text);
    dest.writeString(image);
    dest.writeList(CHOICES);

}

private Question(Parcel in) {
    this.id = in.readString();
    this.text = in.readString();
    this.image = in.readString();
    this.CHOICES = in.readArrayList(Choices.class.getClassLoader());
}

}

感谢您的帮助!

【问题讨论】:

    标签: android class arraylist parcelable


    【解决方案1】:

    如果您需要在活动之间传递ArrayList,那么我也会实施Parcelable,因为我猜没有其他办法。 但是,我认为您不需要那么多 getter 和 setter。这是实现ParcelableQuestion 类:

    public class Question implements Parcelable {
        public String id;
        public String text;
        public String image;
        public ArrayList<Choice> choices;
    
    
        /**
         * Constructs a Question from values
         */
        public Question (String id, String text, String image, ArrayList<Choice> choices) {
            this.id = id;
            this.text = text;
            this.image = image;
            this.choices = choices;
        }
    
        /**
         * Constructs a Question from a Parcel
         * @param parcel Source Parcel
         */
        public Question (Parcel parcel) {
            this.id = parcel.readString();
            this.text = parcel.readString();
            this.image = parcel.readString();
            this.choices = parcel.readArrayList(null);
        }
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        // Required method to write to Parcel
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(id);
            dest.writeString(text);
            dest.writeString(image);
            dest.writeList(choices);
        }
    
        // Method to recreate a Question from a Parcel
        public static Creator<Question> CREATOR = new Creator<Question>() {
    
            @Override
            public Question createFromParcel(Parcel source) {
                return new Question(source);
            }
    
            @Override
            public Question[] newArray(int size) {
                return new Question[size];
            }
    
        };
    }
    

    【讨论】:

    • 我拥有的 ArrayList 怎么样,我的 Question 课程中还可以有这个课程吗?放在我的包裹里?
    • 没有。与其他答案中的建议类似,您必须创建一个单独的 Choice 类并将其作为属性添加到 Question 类。 (就像idtext。)
    • 好的,我将把 Choice 移到它的单独类中。那么你是说我可以从那个类中调用列表并将其添加到parcelable?我将如何“将其添加为属性”?
    • @Kenny:我编辑了答案,包括如何将Choice 列表添加到Question 类。
    • 谢谢@kenny。只需添加以下信息。当我添加“choices = parcel.readArrayList(Choice.class.getClassLoader());”时,它对我有用。以下对我不起作用“parcel.readArrayList(null)”。
    【解决方案2】:

    您几乎拥有它,但不完全是,对。 Question 类看起来几乎正确 Parcelable。唯一行不通的就是将 Choices 数组打包。

    有两种方法可以做到:

    1. 使选择可打包。您必须添加所有必需的方法和 CREATOR。因为 Android 知道如何对 Parcelables 的 ArrayLists 进行打包,所以这将起作用。
    2. 将选择数组打包成为问题打包的一部分。为此,您可能会将数组的大小推入 Parcel,然后遍历 Choices,推入它们的值。另一方面,您将首先读取计数,然后读取每个选项的值,创建每个选项并将其推送到新问题中。

    【讨论】:

    • 您好成功地使用了选项 2(存储数组列表大小并在从包中写入/读取期间进行迭代),特别是当我为数组列表对象使用内部静态类时,它本身具有嵌套的数组列表对象.相当长的课程,但更喜欢把它们放在一起!看到所有使用 Parcelable 接口的单个​​对象与一个类迭代数组列表对象并放入包裹中的性能差异会很有趣。
    【解决方案3】:

    用途:

    in.createTypedArrayList(Product.CREATOR)
    

    在将 Parable 对象作为参数的构造函数中。

    在 writeToParcel 方法中使用dest.writeTypedList(product);

    【讨论】:

      【解决方案4】:

      为“Choices”创建一个新的 java 文件并实现“Parcelable”。如果您不实现 parcelable,您将获得运行时异常(无法编组)。所以使用下面的代码:

          public class Choices implements Parcelable{
      
              boolean isCorrect;
              String choice;
      
              public Choices(boolean isCorrect, String choice) {
                  this.isCorrect = isCorrect;
                  this.choice = choice;
              }
              //Create getters and setters 
      
              protected Choices(Parcel in) {
                  isCorrect = in.readByte() != 0;
                  choice = in.readString();
              }
      
              public static final Creator<Choices> CREATOR = new Creator<Choices>() {
                  @Override
                  public Choices createFromParcel(Parcel in) {
                      return new Choices(in);
                  }
      
                  @Override
                  public Choices[] newArray(int size) {
                      return new Choices[size];
                  }
              };
      
              @Override
              public String toString() {
                  return "Choices [isCorrect=" + isCorrect + ", choice=" + choice
                          + "]";
              }
      
              @Override
              public int describeContents() {
                  return 0;
              }
      
              @Override
              public void writeToParcel(Parcel dest, int flags) {
                  dest.writeByte((byte) (isCorrect ? 1 : 0));
                  dest.writeString(choice);
              }
          }
      

      正如@G.Blake 在上面的回答中提到的,您需要使 Choices Parcelable 并且 Android 知道如何打包 Parcelables 的 ArrayLists

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-12
        • 2019-07-30
        • 1970-01-01
        • 1970-01-01
        • 2017-07-27
        相关资源
        最近更新 更多