J'essaie de rendre mes objets parcellables. Cependant, j'ai des objets personnalisés et ces objets ont des ArrayList
attributs d'autres objets personnalisés que j'ai créés.
Quelle serait la meilleure façon de faire cela?
J'essaie de rendre mes objets parcellables. Cependant, j'ai des objets personnalisés et ces objets ont des ArrayList
attributs d'autres objets personnalisés que j'ai créés.
Quelle serait la meilleure façon de faire cela?
Réponses:
Vous pouvez en trouver des exemples ici , ici (le code est pris ici) , et ici .
Vous pouvez créer une classe POJO pour cela, mais vous devez ajouter du code supplémentaire pour le faire Parcelable
. Jetez un oeil à la mise en œuvre.
public class Student implements Parcelable{
private String id;
private String name;
private String grade;
// Constructor
public Student(String id, String name, String grade){
this.id = id;
this.name = name;
this.grade = grade;
}
// Getter and setter methods
.........
.........
// Parcelling part
public Student(Parcel in){
String[] data = new String[3];
in.readStringArray(data);
// the order needs to be the same as in writeToParcel() method
this.id = data[0];
this.name = data[1];
this.grade = data[2];
}
@Оverride
public int describeContents(){
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] {this.id,
this.name,
this.grade});
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Student createFromParcel(Parcel in) {
return new Student(in);
}
public Student[] newArray(int size) {
return new Student[size];
}
};
}
Une fois que vous avez créé cette classe, vous pouvez facilement passer des objets de cette classe par le biais de Intent
celui-ci et récupérer cet objet dans l'activité cible.
intent.putExtra("student", new Student("1","Mike","6"));
Ici, l'étudiant est la clé dont vous auriez besoin pour décompresser les données du bundle.
Bundle data = getIntent().getExtras();
Student student = (Student) data.getParcelable("student");
Cet exemple affiche uniquement les String
types. Mais, vous pouvez répartir tout type de données que vous souhaitez. Essaye le.
EDIT: Un autre exemple , suggéré par Rukmal Dias .
writeToParcel
méthode est-il important?
Voici un site Web pour créer une classe parcelable à partir de votre classe créée:
IntelliJ IDEA et Android Studio ont des plugins pour cela:
Ces plugins génèrent du code passe- partout Android Parcelable en fonction des champs de la classe.
Android Parcelable code generator
public class Sample {
int id;
String name;
}
File > Settings... > Plugins
et cliquez sur le Browse repositories...
bouton.
Vous annotez simplement un POJO avec une annotation spéciale et la bibliothèque fait le reste.
Avertissement!
Je ne suis pas sûr que Hrisey, Lombok et d'autres bibliothèques de génération de code soient compatibles avec le nouveau système de construction d'Android. Ils peuvent ou non jouer correctement avec le code d'échange à chaud (par exemple jRebel, Instant Run).
Avantages:
Les inconvénients:
Avertissement!
Hrisey a un problème connu avec Java 8 et ne peut donc pas être utilisé pour le développement Android de nos jours. Voir # 1 Impossible de trouver les erreurs de symbole (JDK 8) .
Hrisey est basé sur Lombok . Classe parcelable avec Hrisey :
@hrisey.Parcelable
public final class POJOClass implements android.os.Parcelable {
/* Fields, accessors, default constructor */
}
Maintenant, vous n'avez plus besoin d'implémenter de méthodes d'interface Parcelable. Hrisey générera tout le code requis pendant la phase de prétraitement.
Hrisey dans les dépendances de Gradle:
provided "pl.mg6.hrisey:hrisey:${hrisey.version}"
Voir ici pour les types pris en charge. Le ArrayList
est parmi eux.
Installez un plugin - Hrisey xor Lombok * - pour votre IDE et commencez à utiliser ses fonctionnalités incroyables!
* N'activez pas les plugins Hrisey et Lombok ensemble ou vous obtiendrez une erreur lors du lancement de l'IDE.
Classe parcelable utilisant Parceler :
@java.org.parceler.Parcel
public class POJOClass {
/* Fields, accessors, default constructor */
}
Pour utiliser le code généré, vous pouvez référencer la classe générée directement, ou via la Parcels
classe utilitaire en utilisant
public static <T> Parcelable wrap(T input);
Pour déréférencer le @Parcel
, appelez simplement la méthode de Parcels
classe suivante
public static <T> T unwrap(Parcelable input);
Parceler dans les dépendances Gradle:
compile "org.parceler:parceler-api:${parceler.version}"
provided "org.parceler:parceler:${parceler.version}"
Recherchez dans README les types d'attributs pris en charge .
AutoParcel est une AutoValue extension qui permet la génération de valeurs Parcelable.
Ajoutez simplement implements Parcelable
à vos @AutoValue
modèles annotés:
@AutoValue
abstract class POJOClass implements Parcelable {
/* Note that the class is abstract */
/* Abstract fields, abstract accessors */
static POJOClass create(/*abstract fields*/) {
return new AutoValue_POJOClass(/*abstract fields*/);
}
}
AutoParcel dans le fichier de construction Gradle:
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
repositories {
/*...*/
maven {url "https://clojars.org/repo/"}
}
dependencies {
apt "frankiesardo:auto-parcel:${autoparcel.version}"
}
PaperParcel est un processeur d'annotation qui génère automatiquement du code passe-partout Parcelable de type sécurisé pour Kotlin et Java. PaperParcel prend en charge les classes de données Kotlin, AutoValue de Google via une extension AutoValue, ou tout simplement des objets de bean Java standard.
Exemple d'utilisation de documents .
Annotez votre classe de données avec @PaperParcel
, implémentez PaperParcelable
et ajoutez une instance statique JVM, PaperParcelable.Creator
par exemple:
@PaperParcel
public final class Example extends PaperParcelable {
public static final PaperParcelable.Creator<Example> CREATOR = new PaperParcelable.Creator<>(Example.class);
private final int test;
public Example(int test) {
this.test = test;
}
public int getTest() {
return test;
}
}
Pour les utilisateurs de Kotlin, voir Utilisation de Kotlin ; Pour les utilisateurs d'AutoValue, voir Utilisation d'AutoValue .
ParcelableGenerator (README est écrit en chinois et je ne le comprends pas. Les contributions à cette réponse de développeurs anglophones sont les bienvenues)
Exemple d'utilisation de README .
import com.baoyz.pg.Parcelable;
@Parcelable
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Le plugin android-apt aide à travailler avec les processeurs d'annotation en combinaison avec Android Studio.
C'est très simple, vous pouvez utiliser un plugin sur android studio pour créer des objets Parcelables.
public class Persona implements Parcelable {
String nombre;
int edad;
Date fechaNacimiento;
public Persona(String nombre, int edad, Date fechaNacimiento) {
this.nombre = nombre;
this.edad = edad;
this.fechaNacimiento = fechaNacimiento;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.nombre);
dest.writeInt(this.edad);
dest.writeLong(fechaNacimiento != null ? fechaNacimiento.getTime() : -1);
}
protected Persona(Parcel in) {
this.nombre = in.readString();
this.edad = in.readInt();
long tmpFechaNacimiento = in.readLong();
this.fechaNacimiento = tmpFechaNacimiento == -1 ? null : new Date(tmpFechaNacimiento);
}
public static final Parcelable.Creator<Persona> CREATOR = new Parcelable.Creator<Persona>() {
public Persona createFromParcel(Parcel source) {
return new Persona(source);
}
public Persona[] newArray(int size) {
return new Persona[size];
}
};}
Vous pouvez maintenant utiliser la bibliothèque Parceler pour convertir vos classes personnalisées en parcelable. Annotez simplement votre classe POJO avec @Parcel . par exemple
@Parcel
public class Example {
String name;
int id;
public Example() {}
public Example(int id, String name) {
this.id = id;
this.name = name;
}
public String getName() { return name; }
public int getId() { return id; }
}
vous pouvez créer un objet de la classe Example et passer par Parcels et l'envoyer en tant que bundle par intention. par exemple
Bundle bundle = new Bundle();
bundle.putParcelable("example", Parcels.wrap(example));
Maintenant, pour obtenir un objet de classe personnalisé, utilisez simplement
Example example = Parcels.unwrap(getIntent().getParcelableExtra("example"));
Le parcable Android a des choses uniques. Ceux-ci sont donnés ci-dessous:
Exemple: Pour faire une classe Parceble, il faut implémenter Parceble. Percable a 2 méthodes:
int describeContents();
void writeToParcel(Parcel var1, int var2);
Supposons que vous ayez une classe Person et qu'elle ait 3 champs, firstName, lastName et age. Après avoir implémenté l'interface Parceble. cette interface est donnée ci-dessous:
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable{
private String firstName;
private String lastName;
private int age;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(firstName);
parcel.writeString(lastName);
parcel.writeInt(age);
}
}
Voici la writeToParcel
méthode que nous écrivons / ajoutons des données sur le colis dans une commande. Après cela, nous devons ajouter un code ci-dessous pour lire les données du colis:
protected Person(Parcel in) {
firstName = in.readString();
lastName = in.readString();
age = in.readInt();
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
Ici, la classe Person prend un colis et obtient les données dans un même ordre lors de l'écriture.
Maintenant, pendant l'intention getExtra
et le putExtra
code est donné ci-dessous:
Mettez en extra :
Person person=new Person();
person.setFirstName("First");
person.setLastName("Name");
person.setAge(30);
Intent intent = new Intent(getApplicationContext(), SECOND_ACTIVITY.class);
intent.putExtra()
startActivity(intent);
Obtenez Extra:
Person person=getIntent().getParcelableExtra("person");
La classe Personne Complète est donnée ci - dessous :
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable{
private String firstName;
private String lastName;
private int age;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(firstName);
parcel.writeString(lastName);
parcel.writeInt(age);
}
protected Person(Parcel in) {
firstName = in.readString();
lastName = in.readString();
age = in.readInt();
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
Hope this will help you
Thanks :)
Créer une classe Parcelable sans plugin dans Android Studio
implémente Parcelable dans votre classe, puis placez le curseur sur "implémente Parcelable" et appuyez sur Alt+Enter
et sélectionnez Add Parcelable implementation
(voir image). c'est tout.
Mettre:
bundle.putSerializable("key",(Serializable) object);
Obtenir:
List<Object> obj = (List<Object>)((Serializable)bundle.getSerializable("key"));
ClassCastException
si l'objet n'est pas implémenté Serializable
.