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

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 4

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

Vinícius Thiengo
(2037)
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 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

 

 

 

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 5Persistência de Dados Com Realm no Android - Parte 5Android

Compartilhar

Comentários Facebook

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