J'essaie de créer une ArrayList
Parcelable
afin de transmettre à une activité une liste d'objets personnalisés. Je commence à écrire une classe myObjectList
qui étend ArrayList<myObject>
et à implémenter Parcelable
.
Certains attributs de MyObject
sont boolean
mais Parcel
n'ont pas de méthode read/writeBoolean
.
Quelle est la meilleure façon de gérer cela?
Voici comment je le ferais ...
writeToParcel:
dest.writeByte((byte) (myBoolean ? 1 : 0)); //if myBoolean == true, byte == 1
readFromParcel:
myBoolean = in.readByte() != 0; //myBoolean == true if byte != 0
Vous pouvez également utiliser la méthode writeValue . À mon avis, c'est la solution la plus simple.
dst.writeValue( myBool );
Ensuite, vous pouvez facilement le récupérer avec un casting simple en Boolean
:
boolean myBool = (Boolean) source.readValue( null );
Sous le capot, le framework Android le gérera comme un entier:
writeInt( (Boolean) v ? 1 : 0 );
vous déclarez comme ça
private boolean isSelectionRight;
écrire
out.writeInt(isSelectionRight ? 1 : 0);
lis
isSelectionRight = (in.readInt() == 0) ? false : true;
le type booléen doit être converti en quelque chose que Parcel prend en charge afin que nous puissions le convertir en int.
AndroidStudio (avec 2.3 atm), après avoir implémenté Parcelable sur votre classe, vous pouvez simplement maintenir le pointeur de la souris sur votre nom de classe et vous demander d’ajouter le implémentation parcellaire:
À partir des quatre champs, il génère les éléments suivants:
public class YourClass implements Parcelable{
String someString;
int someInt;
boolean someBoolean;
List<String> someList;
protected YourClass(Parcel in) {
someString = in.readString();
someInt = in.readInt();
someBoolean = in.readByte() != 0;
someList = in.createStringArrayList();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(someString);
dest.writeInt(someInt);
dest.writeByte((byte) (someBoolean ? 1 : 0));
dest.writeStringList(someList);
}
...
Je les ai normalement dans un tableau et appelle writeBooleanArray
et readBooleanArray
Si vous ne voulez emballer qu'un seul booléen, vous pouvez le faire:
parcel.writeBooleanArray(new boolean[] {myBool});
out.writeInt(mBool ? 1 : 0); //Write
this.mBool =in.readInt()==1; //Read
Je vous ai suggéré le moyen le plus simple d'implémenter Parcelable si vous utilisez Android Studio.
Il suffit d'aller à Fichier-> Paramètres-> Plugins-> Parcourir le référentiel et recherchez le fichier parcelable .See image
Il créera automatiquement Parcelable.
Et il y a aussi un site Web pour le faire. http://www.parcelabler.com/
Implémentation courte et simple dans Kotlin, avec support nullable:
Ajouter des méthodes à Parcel
fun Parcel.writeBoolean(flag: Boolean?) {
when(flag) {
true -> writeInt(1)
false -> writeInt(0)
else -> writeInt(-1)
}
}
fun Parcel.readBoolean(): Boolean? {
return when(readInt()) {
1 -> true
0 -> false
else -> null
}
}
Et utilisez-le:
parcel.writeBoolean(isUserActive)
parcel.readBoolean() // For true, false, null
parcel.readBoolean()!! // For only true and false
Vous pouvez compresser vos valeurs booléennes dans un octet en utilisant le masquage et le décalage. Ce serait le moyen le plus efficace de le faire et c'est probablement ce qu'ils s'attendent de vous.
Il est difficile d'identifier la vraie question ici. Je suppose que c'est comment traiter les booléens lors de la mise en œuvre de l'interface Parcelable
.
Certains attributs de MyObject sont booléens, mais Parcel n’a aucune méthode read/writeBoolean.
Vous devrez soit stocker la valeur sous forme de chaîne ou d'octet. Si vous optez pour une chaîne, vous devrez utiliser la méthode statique de la classe String
appelée valueOf()
pour analyser la valeur booléenne. Ce n'est pas aussi efficace que de le conserver dans un octet difficile.
String.valueOf(theBoolean);
Si vous choisissez un octet, vous devrez implémenter vous-même une logique de conversion.
byte convBool = -1;
if (theBoolean) {
convBool = 1;
} else {
convBool = 0;
}
Lorsque vous démasquez l'objet Parcel
, vous devez prendre en charge la conversion en type d'origine.
D'autres personnes ont déjà répondu parfaitement à cette question, si vous voulez le faire vous-même.
Si vous préférez encapsuler ou cacher la plupart du code de parcellaire de bas niveau, vous pouvez envisager d'utiliser ne partie du code que j'ai écrit il y a quelque temps pour simplifier le traitement des parcelles.
Écrire sur un colis est aussi simple que:
parcelValues(dest, name, maxSpeed, weight, wheels, color, isDriving);
où color est une énumération et isDriving est un booléen, par exemple.
La lecture d'un colis n'est pas beaucoup plus difficile:
color = (CarColor)unparcelValue(CarColor.class.getClassLoader());
isDriving = (Boolean)unparcelValue();
Jetez simplement un coup d’oeil au "ParceldroidExample" que j’ai ajouté au projet.
Enfin, l’initialisateur CREATOR reste court:
public static final Parcelable.Creator<Car> CREATOR =
Parceldroid.getCreatorForClass(Car.class);
Il existe de nombreux exemples dans les sources Android (AOSP). Par exemple, la classe PackageInfo
a un membre booléen requiredForAllUsers
et est sérialisée comme suit:
public void writeToParcel(Parcel dest, int parcelableFlags) {
...
dest.writeInt(requiredForAllUsers ? 1 : 0);
...
}
private PackageInfo(Parcel source) {
...
requiredForAllUsers = source.readInt() != 0;
...
}