Persistência de Dados Com Realm no Android - Parte 5

Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba grátis conteúdos Android sem precedentes! Você receberá um email de confirmação. Somente depois de confirma-lo é que eu poderei lhe enviar os conteúdos semanais exclusivos. Os artigos em PDF são entregues somente para os inscritos na lista.

Email inválido.
Blog /Android /Persistência de Dados Com Realm no Android - Parte 5

Persistência de Dados Com Realm no Android - Parte 5

Vinícius Thiengo
(2146) (3)
Go-ahead
"O método consciente de tentativa e erro é mais bem-sucedido que o planejamento de um gênio isolado."
Peter Skillman
Prototipagem Android
Capa do curso Prototipagem Profissional de Aplicativos
TítuloAndroid: Prototipagem Profissional de Aplicativos
CategoriasAndroid, Design, Protótipo
AutorVinícius Thiengo
Vídeo aulas186
Tempo15 horas
ExercíciosSim
CertificadoSim
Acessar Curso
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Lendo
TítuloManual de DevOps: como obter agilidade, confiabilidade e segurança em organizações tecnológicas
CategoriaEngenharia de Software
Autor(es)Gene Kim, Jez Humble, John Willis, Patrick Debois
EditoraAlta Books
Edição
Ano2018
Páginas464
Conteúdo Exclusivo
Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba gratuitamente conteúdos Android sem precedentes!
Email inválido

Opa. blz?

Nessa parte 5 da série Persistência Local com a Library Realm no Android são apresentados os scripts responsáveis por permitir a correta apresentação das disciplinas no formulário de update student e do contador de estudantes para cada disciplina cadastrada na APP.

As entidades que serão atualizadas: AddUpdateStudentActivity e DisciplineAdapter.

Começando pela Activity AddUpdateStudentActivitym no método onCreate() insira no seguinte trecho de código:

...
if( student.getGrades() != null ){
for( Grade g : student.getGrades() ){
createGradeForView( findViewById(R.id.bt_add), disciplines, g );
}
callRemoveGrade( btRemove );
}
...

 

O que está sendo realizado é verificar se grades de student não é null, caso não seja null então sabemos que é um update, pois no mode insert não inicializamos essa variavel de student, logo ela permanece null. Em caso de update acessamos a lista RealmList<Grade> grades via getGrades() e então utilizando o método createGradeForView() são adicionadas as grades (disciplinas e notas) vinculadas ao student atual em mode update. Essa parte já é suficiente para colocar na tela todos os blocos grades (notas), porém o bloco que é útil quando inserindo um novo estudante não é necessário em mode update, logo utilizamos o button btReomove no método callRemoveGrade() para que esse bloco vazio seja removido. O código mais amplo:

...
Spinner spDiscipline = (Spinner) findViewById(R.id.sp_discipline);
spDiscipline.setAdapter( new DisciplineSpinnerAdapter( this, disciplines ));

View btRemove = findViewById(R.id.bt_remove);
btRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callRemoveGrade( v );
}
});


if( student.getGrades() != null ){
for( Grade g : student.getGrades() ){
createGradeForView( findViewById(R.id.bt_add), disciplines, g );
}
callRemoveGrade( btRemove );
}
...

 

Agora vamos ao código do DisciplineAdapter, o mesmo do vídeo 1 da série. Nele a primeira alteração é adicionar a variavel de instancia realm, junto ao novo parâmetro do construtor, Realm realm. Segue trecho de código:

...
private Realm realm;

public DisciplineAdapter( Context context, Realm realm, RealmResults<Discipline> realmResults, boolean automaticUpdate ){
super(context, realmResults, automaticUpdate);
this.realm = realm;
}
...

 

Logo depois é acessar o número de estudantes para a discilina atual no método getView(). Agora o codigo fica mais interessante se estava buscando como realizar algo similar ao join no padrão SQL, segue trecho de código dentro do método getView() do adapter:

...
final Discipline d = realmResults.get(position);
int amountStudents = realm.where(Student.class).equalTo("grades.discipline.id", d.getId()).findAll().size();
holder.tvName.setText( d.getName()+" ("+amountStudents+")" );
...

 

O método where( Student.class ) nos informa que somente Students serão retornados caso os equals e cia sejam verdadeiros para ao menos uma linha / registro em Realm. Note que em equalTo( "grades.discipline.id" ) está na verdade referenciando aos nomes das variaveis de instancia, grades em Student, discipline em Gradle e id em Discipline. Com isso é possivel dar um size() em findAll() e obter a quantidade de alunos na disciplina.

A principio a tentativa foi colocar uma variavel de instancia amountStudents em DIscipline, porém com o annotation @Ignore, pois não ela seria armazenada na base, não vi a necessidade de armazenar esse dado na base Realm. Porém o valor inserido, depois de ter as disciplinas retornadas da base Realm via realm.where( Discipline.class ).findAll(), por serem objetos vazios que acessam diretamente a base Realm, não persistiam, nem mesmo local no objeto, o valor da varialvel de instancia amountStudent, por isso o script acima foi a escolha, sendo que caso contrário, sem essa limitação de dados locais, seria possível realizar essa vinculação no mesmo trecho de código onde as disciplinas são buscadas da base Realm.

Para saber mais sobre link entre entidade Realm acesse esse link: https://realm.io/docs/java/latest/#relationships

Segue código completo do adapter DisciplineAdapter:

import android.content.Context;
import android.content.Intent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.TextView;

import br.com.thiengo.realmstudents.AddUpdateDisciplineActivity;
import br.com.thiengo.realmstudents.R;
import br.com.thiengo.realmstudents.domain.Discipline;
import br.com.thiengo.realmstudents.domain.Student;
import io.realm.Realm;
import io.realm.RealmBaseAdapter;
import io.realm.RealmResults;

/**
* Created by viniciusthiengo on 11/2/15.
*/
public class DisciplineAdapter extends RealmBaseAdapter<Discipline> implements ListAdapter {

private Realm realm;

public DisciplineAdapter( Context context, Realm realm, RealmResults<Discipline> realmResults, boolean automaticUpdate ){
super(context, realmResults, automaticUpdate);
this.realm = realm;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
CustomViewHolder holder;

if( convertView == null ){
convertView = inflater.inflate(R.layout.item_discipline, parent, false);
holder = new CustomViewHolder();
convertView.setTag( holder );

holder.tvName = (TextView) convertView.findViewById(R.id.tv_name);
holder.btUpdate = (Button) convertView.findViewById(R.id.bt_update);
holder.btRemove = (Button) convertView.findViewById(R.id.bt_remove);
}
else{
holder = (CustomViewHolder) convertView.getTag();
}

final Discipline d = realmResults.get(position);
int amountStudents = realm.where(Student.class).equalTo("grades.discipline.id", d.getId()).findAll().size();
holder.tvName.setText( d.getName()+" ("+amountStudents+")" );

holder.btUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent it = new Intent(context, AddUpdateDisciplineActivity.class);
it.putExtra(Discipline.ID, d.getId());
context.startActivity(it);
}
});

holder.btRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
d.removeFromRealm();
realm.commitTransaction();
realm.close();
}
});

return convertView;
}

private static class CustomViewHolder{
TextView tvName;
Button btUpdate;
Button btRemove;
}
}

 

O código completo do projeto pode ser acessado no GitHub: https://github.com/viniciusthiengo/realm-students

Para acessar o site da library Realm: Documentação Realm Library Android

Segue vídeo de implementação da parte 5:

  

Vlw

 

 

 

 

 

Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba grátis conteúdos Android sem precedentes!
Email inválido

Relacionado

Persistência de Dados Com Realm no Android - Parte 1Persistência de Dados Com Realm no Android - Parte 1Android
Persistência de Dados Com Realm no Android - Parte 2Persistência de Dados Com Realm no Android - Parte 2Android
Persistência de Dados Com Realm no Android - Parte 3Persistência de Dados Com Realm no Android - Parte 3Android
Persistência de Dados Com Realm no Android - Parte 4Persistência de Dados Com Realm no Android - Parte 4Android

Compartilhar

Comentários Facebook

Comentários Blog (3)

Para código / script, coloque entre [code] e [/code] para receber marcação especifica.
Forneça seu nome válido.
Forneça seu email válido.
Forneça o comentário.
Enviando, aguarde...
Luiz Eduardo (1) (0)
08/03/2016
Boa tarde Thiengo. Procurando uma API pra persistência de dados, vi o seu post e achei muuuito bacana, mas surgiu um problema.
Meu cenário é o seguinte... preciso utilizar agrupamento(Group By) em peso no meu app e vi que com Realm não posso utilizar recurso parecido com o Group By do SQL, isso fez com que eu reavaliasse a utilização do Realm no app, olhando assim pro GreenDao. Mas me surgiu uma dúvida... como a diferença do Realm pro GreenDao é gritante, gostaria da sua opinião... Tipo, se eu fizer o "Group By" manual no Realm é possível que ele seja ainda mais rápido que um Group By utilizando "queryRawCreate" do GreenDao, sabe me dizer?. Estou falando de "Group By" com join entre 2~4 Classes/Entidades, no máximo 15K de registros e função agregada "Count". Desde já grato.
Responder
Vinícius Thiengo (0) (0)
09/03/2016
Fala Luiz Eduardo, blz?
Por ser até 15k e tendo que realizar o "group by" na mão, pode ser que o Realm seja menos eficiente que o SQLite, terá de testar. Veja esse script que utiliza o "group by" no Realm (http://stackoverflow.com/a/30449784/2578331 ), pode ser um norte para ti. Abraço
Responder
Luiz Eduardo (1) (0)
09/03/2016
Olá Thiengo, muito obrigado por responder!. Irei fazer testes e assim que obter algum resultado, posto aqui. Abraço!.
Responder