web-dev-qa-db-fra.com

Android Class Parcelable avec ArrayList

J'ai un Android où j'ai une classe. Dans cette classe est un ArrayList<Choices>. J'obtiendrai du XML, je l'analyserai, puis j'en ferai des objets que je passerai à une autre activité. Je choisis Parcelable pour cela.

Parcelable est-il un bon choix? Suis-je en train de tout faire correctement? Je ne connais pas vraiment Parcelable. Ma liste de tableaux est d'une autre classe que j'ai créée dans cette classe. Est-ce que cela transmettra correctement cette liste d'objets à la parcelle sans qu'elle étende Parcelable et d'autres choses?

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

}

Merci pour toute aide!

22
Kenny

Si vous avez besoin de passer un ArrayList entre les activités, alors j'irais aussi avec l'implémentation de Parcelable, car il n'y a pas d'autre moyen, je suppose. Cependant, je ne pense pas que vous aurez besoin de beaucoup de getters et de setters. Voici votre classe Question qui implémente Parcelable:

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

    };
}
34
Miro Markaravanes

Vous l'avez presque, mais pas tout à fait, à droite. La classe Question semble presque correctement Parcelable. La seule chose qui ne fonctionnera pas est de regrouper le tableau des choix.

Vous pouvez le faire de deux manières:

  1. Faites des choix groupables. Vous devrez ajouter toutes les méthodes requises et le CRÉATEUR. Parce que Android sait comment répartir ArrayLists of Parcelables, cela fonctionnera.
  2. Faites de la parcellisation le tableau des choix dans la parcellisation de la question. Pour ce faire, vous devez probablement pousser la taille du tableau dans la parcelle, puis faire une boucle sur les choix, en poussant leurs valeurs. À l'autre extrémité, vous devez d'abord lire le nombre, puis lire les valeurs de chaque choix, en les créant et en les insérant dans la nouvelle question.
4
G. Blake Meike

Utilisation:

in.createTypedArrayList(Product.CREATOR)

Dans le constructeur qui prend un objet Parable comme paramètre.

Dans la méthode writeToParcel, utilisez dest.writeTypedList(product);

3
Derrick

Créez un nouveau fichier Java pour "Choices" et implémentez "Parcelable". Si vous n'implémentez pas parcelable, vous obtiendrez une exception d'exécution (Unable to Marshal). Utilisez donc le code ci-dessous:

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

Comme mentionné dans la réponse ci-dessus par @ G.Blake, vous devez rendre les choix parcellaires et Android sait comment répartir les tableaux de listes de parcelles

2
Hemant Shori