web-dev-qa-db-fra.com

Comment lire / écrire un booléen lors de l'implémentation de l'interface Parcelable?

J'essaie de créer une ArrayListParcelable 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?

396
grunk

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
926
b_yng

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 );
65
Taig

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.

15
Shaista Naaz

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:

enter image description here

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

...
10
Henk-Martijn

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});
8
Geobits
out.writeInt(mBool ? 1 : 0); //Write
this.mBool =in.readInt()==1; //Read
8
Meghna

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

enter image description here Il créera automatiquement Parcelable.

Et il y a aussi un site Web pour le faire. http://www.parcelabler.com/

5
Xar E Ahmer

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
4
comm1x

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.

3
fleetway76

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.

3
Octavian Damiean

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);
1
Michael Geier

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;
    ...
}
0
FireAphis