Persistência de Dados Com Realm no Android - Parte 5
(2257) (3)
CategoriasAndroid, Design, Protótipo
AutorVinícius Thiengo
Vídeo aulas186
Tempo15 horas
ExercíciosSim
CertificadoSim
CategoriaEngenharia de Software
Autor(es)Vaughn Vernon
EditoraAlta Books
Edição1ª
Ano2024
Páginas160
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
Comentários Facebook