Estoy tratando de hacer un ArrayList
Parcelable
para pasar a una actividad una lista de objetos personalizados. Comienzo a escribir una clase myObjectList
que extiende ArrayList
e implementa Parcelable
.
Algunos atributos de MyObject
son boolean
pero Parcel
no tiene ningún método read/writeBoolean
.
¿Cuál es la mejor manera de manejar esto?
Así es como lo haría …
writeToParcel:
dest.writeByte((byte) (myBoolean ? 1 : 0)); //if myBoolean == true, byte == 1
readFromParcel:
myBoolean = in.readByte() != 0; //myBoolean == true if byte != 0
También puede hacer uso del método writeValue . En mi opinión esa es la solución más directa.
dst.writeValue( myBool );
Luego puede recuperarlo fácilmente con un simple lanzamiento a Boolean
:
boolean myBool = (Boolean) source.readValue( null );
Debajo del capó, Android Framework lo manejará como un entero:
writeInt( (Boolean) v ? 1 : 0 );
usted declara así
private boolean isSelectionRight;
escribir
out.writeInt(isSelectionRight ? 1 : 0);
leer
isSelectionRight = (in.readInt() == 0) ? false : true;
El tipo booleano necesita ser convertido a algo que Parcel soporte y así podamos convertirlo a int.
out.writeInt(mBool ? 1 : 0); //Write this.mBool =in.readInt()==1; //Read
Normalmente los tengo en una matriz y llamo writeBooleanArray
y readBooleanArray
Si es un booleano único que necesita empacar, puede hacer esto:
parcel.writeBooleanArray(new boolean[] {myBool});
Te sugerí la forma más fácil de implementar Parcelable si estás usando Android Studio.
Simplemente vaya a Archivo-> Configuración-> Complementos-> Examinar repository y busque plotble .Ver imagen
Creará automáticamente Parcelable.
Y hay un sitio web también para hacer esto. http://www.plotbler.com/
AndroidStudio (utilizando 2.3 atm), después de implementar Parcelable en su clase, simplemente puede mantener el puntero del mouse sobre el nombre de su clase y le pedirá que agregue la implementación plotble:
De los cuatro campos, genera lo siguiente:
public class YourClass implements Parcelable{ String someString; int someInt; boolean someBoolean; List 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); } ...
Puede empaquetar sus valores booleanos en un byte usando enmascaramiento y desplazamiento. Esa sería la forma más eficiente de hacerlo y es probablemente lo que esperarían que hicieras.
Es difícil identificar la verdadera pregunta aquí. Supongo que es cómo lidiar con booleanos cuando se implementa la interfaz Parcelable
.
Algunos atributos de MyObject son booleanos pero Parcel no tiene ningún método read / writeBoolean.
Deberá almacenar el valor como una cadena o como un byte. Si elige una cadena, deberá usar el método estático de la clase String
llamada valueOf()
para analizar el valor booleano. No es tan efectivo como guardarlo en un byte difícil.
String.valueOf(theBoolean);
Si elige un byte, deberá implementar una lógica de conversión usted mismo.
byte convBool = -1; if (theBoolean) { convBool = 1; } else { convBool = 0; }
Al desasignar el objeto Parcel
, debe encargarse de la conversión al tipo original.
Implementación corta y simple en Kotlin , con soporte para nulos:
Agregar métodos al paquete
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 } }
Y úsala:
parcel.writeBoolean(isUserActive) parcel.readBoolean() // For true, false, null parcel.readBoolean()!! // For only true and false
Esta pregunta ya ha sido respondida perfectamente por otras personas, si quieres hacerlo por tu cuenta.
Si prefiere encapsular o esconder la mayor parte del código de plotción de bajo nivel, puede considerar usar parte del código que escribí hace algún tiempo para simplificar el manejo de plots.
Escribir en un paquete es tan fácil como:
parcelValues(dest, name, maxSpeed, weight, wheels, color, isDriving);
donde color es una enumeración e isDriving es un booleano, por ejemplo.
Leer de un paquete tampoco es mucho más difícil:
color = (CarColor)unparcelValue(CarColor.class.getClassLoader()); isDriving = (Boolean)unparcelValue();
Solo eche un vistazo al “ParceldroidExample” que agregué al proyecto.
Finalmente, también mantiene corto el inicializador CREATOR:
public static final Parcelable.Creator CREATOR = Parceldroid.getCreatorForClass(Car.class);
Hay muchos ejemplos en las fonts de Android (AOSP). Por ejemplo, la clase PackageInfo
tiene un miembro booleano requiredForAllUsers
y se serializa de la siguiente manera:
public void writeToParcel(Parcel dest, int plotbleFlags) { ... dest.writeInt(requiredForAllUsers ? 1 : 0); ... } private PackageInfo(Parcel source) { ... requiredForAllUsers = source.readInt() != 0; ... }