Estou tentando fazer meus objetos serem paráveis. No entanto, tenho objetos personalizados e esses objetos têm ArrayList
atributos de outros objetos personalizados que criei.
Qual seria a melhor forma de fazer isso?
Estou tentando fazer meus objetos serem paráveis. No entanto, tenho objetos personalizados e esses objetos têm ArrayList
atributos de outros objetos personalizados que criei.
Qual seria a melhor forma de fazer isso?
Respostas:
Você pode encontrar alguns exemplos disso aqui , aqui (o código é obtido aqui) e aqui .
Você pode criar uma classe POJO para isso, mas precisa adicionar um código extra para fazê-lo Parcelable
. Dê uma olhada na implementação.
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];
}
};
}
Depois de criar essa classe, você pode facilmente passar objetos dessa classe por esse Intent
tipo e recuperar esse objeto na atividade de destino.
intent.putExtra("student", new Student("1","Mike","6"));
Aqui, o aluno é a chave necessária para desagrupar os dados do pacote.
Bundle data = getIntent().getExtras();
Student student = (Student) data.getParcelable("student");
Este exemplo mostra apenas String
tipos. Mas você pode agrupar qualquer tipo de dados que desejar. Experimente.
EDIT: Outro exemplo , sugerido por Rukmal Dias .
writeToParcel
método é importante?
Aqui está um site para criar uma classe Parcelable a partir da sua classe criada:
O IntelliJ IDEA e o Android Studio possuem plugins para isso:
Esses plug-ins geram o código padrão do Android Parcelable com base nos campos da classe.
Android Parcelable code generator
public class Sample {
int id;
String name;
}
File > Settings... > Plugins
e clique no Browse repositories...
botão.
Você simplesmente anota um POJO com uma anotação especial e a biblioteca faz o resto.
Atenção!
Não tenho certeza de que Hrisey, Lombok e outras bibliotecas de geração de código sejam compatíveis com o novo sistema de compilação do Android. Eles podem ou não funcionar bem com o código de troca quente (por exemplo, jRebel, Instant Run).
Prós:
Contras:
Atenção!
Hrisey tem um problema conhecido com o Java 8 e, portanto, não pode ser usado atualmente no desenvolvimento do Android. Consulte # 1 Não foi possível encontrar erros de símbolo (JDK 8) .
Hrisey é baseado em Lombok . Classe Parcelable usando Hrisey :
@hrisey.Parcelable
public final class POJOClass implements android.os.Parcelable {
/* Fields, accessors, default constructor */
}
Agora você não precisa implementar nenhum método da interface Parcelable. Hrisey irá gerar todo o código necessário durante a fase de pré-processamento.
Hrisey nas dependências de Gradle:
provided "pl.mg6.hrisey:hrisey:${hrisey.version}"
Veja aqui os tipos suportados. O ArrayList
está entre eles.
Instale um plug-in - Hrisey xor Lombok * - para o seu IDE e comece a usar seus incríveis recursos!
* Não ative os plug-ins Hrisey e Lombok juntos ou ocorrerá um erro durante o lançamento do IDE.
Classe Parcelable usando o Parceler :
@java.org.parceler.Parcel
public class POJOClass {
/* Fields, accessors, default constructor */
}
Para usar o código gerado, você pode referenciar a classe gerada diretamente ou através da Parcels
classe utilidade usando
public static <T> Parcelable wrap(T input);
Para remover a referência @Parcel
, basta chamar o seguinte método de Parcels
classe
public static <T> T unwrap(Parcelable input);
Pacote nas dependências Gradle:
compile "org.parceler:parceler-api:${parceler.version}"
provided "org.parceler:parceler:${parceler.version}"
Procure no README os tipos de atributos suportados .
AutoParcel é um AutoValue extensão do que permite a geração de valores Parcelable.
Basta adicionar implements Parcelable
aos seus @AutoValue
modelos anotados:
@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 no arquivo de compilação 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}"
}
O PaperParcel é um processador de anotação que gera automaticamente o código padrão do Parcelable seguro para tipos para Kotlin e Java. O PaperParcel suporta Classes de dados Kotlin, o AutoValue do Google por meio de uma extensão de AutoValue ou apenas objetos comuns de bean Java.
Exemplo de uso de documentos .
Anote sua classe de dados com @PaperParcel
, implemente PaperParcelable
e inclua uma instância estática da JVM, PaperParcelable.Creator
por exemplo:
@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;
}
}
Para usuários do Kotlin, consulte Uso do Kotlin ; Para usuários do AutoValue, consulte Uso do AutoValue .
ParcelableGenerator (o README está escrito em chinês e eu não o entendo. Contribuições para esta resposta de desenvolvedores que falam inglês-chinês são bem-vindas)
Exemplo de uso do 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;
}
}
O plug - in android-apt auxilia no trabalho com processadores de anotação em combinação com o Android Studio.
É muito fácil, você pode usar um plugin no android studio para fazer objetos 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];
}
};}
Agora você pode usar a biblioteca Parceler para converter qualquer classe personalizada em parcelável. Apenas anote sua classe POJO com @Parcel . por exemplo
@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; }
}
você pode criar um objeto da classe Example e agrupar por meio de encomendas e enviar como um pacote por meio de intenção. por exemplo
Bundle bundle = new Bundle();
bundle.putParcelable("example", Parcels.wrap(example));
Agora, para obter o objeto Classe Personalizada, basta usar
Example example = Parcels.unwrap(getIntent().getParcelableExtra("example"));
Pacote Android tem algumas coisas únicas. Estes são dados abaixo:
Exemplo: Para tornar uma classe Parceble, é necessário implementar a Parceble. Percable tem 2 métodos:
int describeContents();
void writeToParcel(Parcel var1, int var2);
Suponha que você tenha uma classe Person e ela possua 3 campos, firstName, lastName e age. Após implementar a interface Parceble. esta interface é apresentada abaixo:
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);
}
}
Aqui writeToParcel
método, estamos escrevendo / adicionando dados no Parcel em um pedido. Depois disso, temos que adicionar o código abaixo para ler os dados do pacote:
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];
}
};
Aqui, a classe Person está pegando um pacote e obtendo os dados na mesma ordem durante a gravação.
Agora, durante a intenção getExtra
eputExtra
código, é fornecido abaixo:
Colocar no 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);
Obter extra:
Person person=getIntent().getParcelableExtra("person");
A classe Full Person é dada abaixo :
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 :)
Criar classe Parcelable sem plug-in no Android Studio
implementa Parcelable em sua classe e, em seguida, coloque o cursor em "implementa Parcelable" e pressione Alt+Enter
e selecione Add Parcelable implementation
(veja a imagem). é isso aí.
Colocar:
bundle.putSerializable("key",(Serializable) object);
Para obter:
List<Object> obj = (List<Object>)((Serializable)bundle.getSerializable("key"));
ClassCastException
se o objeto não for implementado Serializable
.