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

Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog. Você receberá um email de confirmação. Somente depois de confirma-lo é que poderei lhe enviar os conteúdos exclusivos.

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

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

Vinícius Thiengo
(1409) (1)
Go-ahead
"Foque em ser produtivo ao invés de ser oculpado."
Tim Ferris
Kotlin Android
Capa do livro Desenvolvedor Kotlin Android - Bibliotecas para o dia a dia
TítuloDesenvolvedor Kotlin Android - Bibliotecas para o dia a dia
CategoriasAndroid, Kotlin
AutorVinícius Thiengo
Edição
Capítulos19
Páginas1035
Acessar Livro
Treinamento Oficial
Android: Prototipagem Profissional de Aplicativos
CursoAndroid: Prototipagem Profissional de Aplicativos
CategoriaAndroid
InstrutorVinícius Thiengo
NívelTodos os níveis
Vídeo aulas186
PlataformaUdemy
Acessar Curso
Receitas Android
Capa do livro Receitas Para Desenvolvedores Android
TítuloReceitas Para Desenvolvedores Android
CategoriaDesenvolvimento Android
AutorVinícius Thiengo
Edição
Ano2017
Capítulos20
Páginas936
Acessar Livro
Código Limpo
Capa do livro Refatorando Para Programas Limpos
TítuloRefatorando Para Programas Limpos
CategoriaEngenharia de Software
AutorVinícius Thiengo
Edição
Ano2017
Capítulos46
Páginas599
Acessar Livro
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Conteúdo Exclusivo
Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog.
Email inválido

Opa, blz?

Nessa parte 4 da série Persistência Local com a Library Realm no Android são apresentados os scripts necessários para a obtenção das disciplinas e notas de cada bloco de nota vinculado ao estudante em formulário e então persistir esses dados na base Real junto ao estudante.

O modelo adotado para trabalho com notas é de sempre adicionar novas notas na base Realm, mesmo quando em modo update. Devido ao índice utilizado ser do tipo long (), essa escolha não foi adotado como problema e sim a mais simples e que responde bem ao que estamos construindo nessa APP. Uma outra opção para inserção de notas (grades) é utilizando também a library criada por Douglas Nassif (https://gist.github.com/douglasjunior/a6ed80a691957208deec). Note que as atualizações de código serão feitas na Activity AddUpdateStudentActivity.

 

O primeiro passo é criarmos um método que vai percorrer todo o layout depois de passarmos como parâmetro a View (button) que aciona o listener de inserção de estudante (além das disciplinas em disciplines), no caso vamos trabalhar o método getGradesFromView() apresentado abaixo:

private List<Grade> getGradesFromView( View view, RealmResults<Discipline> disciplines ){
List<Grade> list = new LinkedList<>();
RelativeLayout rlParent = (RelativeLayout) view.getParent();

for( int i = 0; i < rlParent.getChildCount(); i++ ){

if( rlParent.getChildAt( i ) instanceof ScrollView){
ScrollView scrollView = (ScrollView) rlParent.getChildAt( i );
LinearLayout llChild = (LinearLayout) scrollView.getChildAt( 0 );

for( int j = 0; j < llChild.getChildCount(); j++ ){
if( llChild.getChildAt( j ) instanceof LinearLayout ){

Spinner spDiscipline = (Spinner) llChild.getChildAt( j ).findViewById(R.id.sp_discipline);
EditText etGrade = (EditText) llChild.getChildAt( j ).findViewById(R.id.et_grade);

Grade g = new Grade();
if( realm.where(Grade.class).findAll().size() > 0 ){
g.setId( realm.where(Grade.class).findAll().where().findAllSorted("id", RealmResults.SORT_ORDER_DESCENDING).get(0).getId() + 1 + j );
}
else{
g.setId(1);
}

Discipline d = new Discipline();
d.setId( disciplines.get( spDiscipline.getSelectedItemPosition() ).getId() );
d.setName(disciplines.get(spDiscipline.getSelectedItemPosition()).getName());
g.setDiscipline(d);

g.setGrade(Double.parseDouble(etGrade.getText().toString()));

list.add( g );
}
}
}
}
return( list );
}

 

O RealtiveLayout rlParent é o root do layout activity_add_update_student.xml, temos de acessá-lo primeiro pois a view que é passado como parâmtero é o button bt_add_update (o button ADD na imagem abaixo):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

...

<Button
android:id="@+id/bt_add_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="5dp"
android:onClick="callAddUpdateStudent"
android:text="Add" />
</RelativeLayout>

 

Esse button é filho direto do layout root, com acesso ao root é possível percorrer todas as outras Views que são filhas diretas dele. O código faz essa parte no primeiro loop do trecho abaixo:

...
for( int i = 0; i < rlParent.getChildCount(); i++ ){

if( rlParent.getChildAt( i ) instanceof ScrollView){
ScrollView scrollView = (ScrollView) rlParent.getChildAt( i );
LinearLayout llChild = (LinearLayout) scrollView.getChildAt( 0 );

for( int j = 0; j < llChild.getChildCount(); j++ ){
if( llChild.getChildAt( j ) instanceof LinearLayout ){

Spinner spDiscipline = (Spinner) llChild.getChildAt( j ).findViewById(R.id.sp_discipline);
EditText etGrade = (EditText) llChild.getChildAt( j ).findViewById(R.id.et_grade);

Grade g = new Grade();
if( realm.where(Grade.class).findAll().size() > 0 ){
g.setId( realm.where(Grade.class).findAll().where().findAllSorted("id", RealmResults.SORT_ORDER_DESCENDING).get(0).getId() + 1 + j );
}
else{
g.setId(1);
}

Discipline d = new Discipline();
d.setId( disciplines.get( spDiscipline.getSelectedItemPosition() ).getId() );
d.setName(disciplines.get(spDiscipline.getSelectedItemPosition()).getName());
g.setDiscipline(d);

g.setGrade(Double.parseDouble(etGrade.getText().toString()));

list.add( g );
}
}
}
}
...

 

Então é verificado se é um ScrollView, pois ele é o filho direto que nos permitirá chegar até os LinearLayouts que contém os Spinners e EditTexts com disciplinas e notas respectivamente. Acessando o ScrollView podemos ir diretamente ao acesso ao LinearLayout container dos blocos de notas e button bt_add, pois sabemos ele é o único filho direto do ScrollView, vejo esse trecho do layout activity_add_update_student.xml:

...
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bt_add_update"
android:layout_below="@+id/et_name"
android:fillViewport="true">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<include layout="@layout/box_discipline_grade" />

<Button
android:id="@+id/bt_add"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginRight="5dp"
android:background="#dddddd"
android:gravity="center"
android:onClick="callAddGrade"
android:text="Add"
android:textColor="#000" />

</LinearLayout>
</ScrollView>
...

 

Logo depois é verificar se é um LinearLayout, pois tem a possibilidade de ser um button (bt_add), se sim, é acessar o Spinner e EditText pelos ids. Note que para gerar um novo Grade id é verificado se há alguma Grade na base Realm, se sim então pegamos o de maior id (utilizando os métodos de busca e sort do Realm), acessamos esse maior id + 1 + j. O "j" é necessário, pois ainda não estamos adionando a grade (nota) na base, e sim na lista que será vinculada ao estudante na base, logo para garantir que se tiver mais de uma nota vinculada ao aluno, elas tenham ids distintos e únicos, o "j" será o contador que permitirá essa unicidade.

Com isso vamos para a parte 2 do código é que inserir essas grades na variavel grades do student, isso será realizado no método callAddUpdateStudent():

public void callAddUpdateStudent( View view ){
String label = "atualizado";
if( student.getId() == 0 ){
students.sort( "id", RealmResults.SORT_ORDER_DESCENDING );
long id = students.size() == 0 ? 1 : students.get(0).getId() + 1;
student.setId( id );
label = "adicionado";
}

try{
realm.beginTransaction();
student.setName(etName.getText().toString());
realm.copyToRealmOrUpdate(student);
realm.commitTransaction();

student = realm.where(Student.class).equalTo("id", student.getId()).findFirst();

realm.beginTransaction();
student.getGrades().clear();
student.getGrades().addAll( getGradesFromView( view, disciplines ) );
realm.commitTransaction();

Toast.makeText(AddUpdateStudentActivity.this, "Estudante " + label, Toast.LENGTH_SHORT).show();
finish();
}
catch(Exception e){
e.printStackTrace();
Toast.makeText(AddUpdateStudentActivity.this, "Falhou!", Toast.LENGTH_SHORT).show();
}
}

 

O trecho de código:

...
student = realm.where(Student.class).equalTo("id", student.getId()).findFirst();

realm.beginTransaction();
student.getGrades().clear();
student.getGrades().addAll( getGradesFromView( view, disciplines ) );
realm.commitTransaction();
...

 

É responsável por acessar o estudante recém inserido / atualizado, dessa forma, mesmo que a varivel grades do student esteja null, o retorno de Realm é com ele vazia e não null, ou seja, podemos acessar os métodos de RealmList<Grade> grades sem problemas de ter um NullPointerException, já que obtemos os dados da base Realm. Depois disso é entre begindTransaction() e commitTransaction() limpar todas as grades vinculadas ao user com o trecho student.getGrades().clear(); e então pegar as novas atribuições via trecho student.getGrades().addAll( getGradesFromView( view, disciplines ) );

Assim é salvo / atualizado primeiro o student e depois inseridas as notas a ele. Assim concluímos essa parte 4 da série. Porém ainda persisti um bug, tente acessar a atualização de qualquer um dos esrudantes que adicionou, o que terá é que não serão apresentadas as notas salvas, não porque elas não foram salvas, mas sim porque devemos construir essa parte quando for um mode update. Uma das partes da parte 5. 

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 4:

 

Vlw

 

 

 

Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog.
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 5Persistência de Dados Com Realm no Android - Parte 5Android

Compartilhar

Comentários Facebook (1)

Comentários Blog

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...