android - studio - ¿Cómo leer/escribir un booleano cuando se implementa la interfaz Parcelable?
implementar parcelable android (12)
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<myObject>
e implemento 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?
Le sugerí la forma más fácil de implementar Parcelable si está utilizando Android Studio.
Simplemente vaya a Archivo-> Configuración-> Complementos-> Buscar repositorio y busque parcelable .Ver imagen
Se creará automáticamente parcelable.
Y hay una webista también para hacer esto. http://www.parcelabler.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 pide que agregue la implementación parcelable:
A partir de los cuatro campos, genera lo siguiente:
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);
}
...
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
Es difícil identificar la verdadera pregunta aquí. Supongo que es cómo tratar con los booleanos cuando se implementa la interfaz Parcelable
.
Algunos atributos de MyObject son booleanos pero Parcel no tiene ningún método read / writeBoolean.
Tendrá que almacenar el valor como una cadena o como un byte. Si eliges una cadena, tendrás que 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 duro.
String.valueOf(theBoolean);
Si va por un byte, tendrá que implementar una lógica de conversión usted mismo.
byte convBool = -1;
if (theBoolean) {
convBool = 1;
} else {
convBool = 0;
}
Cuando se desmarca el objeto Parcel
, debe hacerse cargo de la conversión al tipo original.
Esta pregunta ya ha sido respondida perfectamente por otras personas, si desea hacerlo por su cuenta.
Si prefiere encapsular u ocultar la mayor parte del código de parcelación de bajo nivel, puede considerar usar parte del código que escribí hace algún tiempo para simplificar el manejo de parcelables.
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.
La lectura de un paquete tampoco es mucho más difícil:
color = (CarColor)unparcelValue(CarColor.class.getClassLoader());
isDriving = (Boolean)unparcelValue();
Simplemente eche un vistazo a "ParceldroidExample" que agregué al proyecto.
Finalmente, también mantiene el inicializador CREATOR corto:
public static final Parcelable.Creator<Car> CREATOR =
Parceldroid.getCreatorForClass(Car.class);
Hay muchos ejemplos en las fuentes 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 parcelableFlags) {
...
dest.writeInt(requiredForAllUsers ? 1 : 0);
...
}
private PackageInfo(Parcel source) {
...
requiredForAllUsers = source.readInt() != 0;
...
}
Implementación corta y simple en Kotlin , con soporte anulable:
Añadir métodos a la parcela
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 úsalo:
parcel.writeBoolean(isUserActive)
parcel.readBoolean() // For true, false, null
parcel.readBoolean()!! // For only true and false
Normalmente los tengo en una matriz y llamo writeBooleanArray
y readBooleanArray
Si es un booleano que necesita empacar, puede hacer esto:
parcel.writeBooleanArray(new boolean[] {myBool});
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 esperan que hagas.
También puede hacer uso del método writeValue . En mi opinión, esa es la solución más sencilla.
dst.writeValue( myBool );
Después, puede recuperarlo fácilmente con un simple lanzamiento a Boolean
:
boolean myBool = (Boolean) source.readValue( null );
Bajo el 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 debe convertirse en algo que admita Parcel y así podamos convertirlo en int.
out.writeInt(mBool ? 1 : 0); //Write
this.mBool =in.readInt()==1; //Read