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

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 2

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

Vinícius Thiengo
(1622) (2) (1)
Go-ahead
"Concentre todos seus pensamentos no trabalho que tem em mãos. Os raios solares não queimam até que sejam colocados em foco."
Alexander Graham Bell
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 2 da série persistência local no Android com Realm, é apresentado a construção das Activities de Students (Students Activity e AddUpdateStudentActivity) além de algumas atualizações do domínio do problema (Student e Grade) junto a adição de um novo adapter, StudentAdapter, para ser carregado junto ao ListView de Student.

Começamos pelo domínio do problema colocando a classe Student extends RealmObject além da adição do atributo RealmList<Grade> que será responsável por manter as notas do estudante junto ao objeto referente a ele. Note que no caso de lista, apesar de posteriormente ser utilizado um LinkedList para preencher a lista grades de Student, o tipo dela tem de ser RealmList<T>, segue código:

import io.realm.RealmList;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;

public class Student extends RealmObject {
public static final String ID = "br.com.thiengo.realmexample.domain.Student.ID";

@PrimaryKey
private long id;
private String name;
private String email;
private RealmList<Grade> grades;

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public RealmList<Grade> getGrades() {
return grades;
}

public void setGrades(RealmList<Grade> grades) {
this.grades = grades;
}
}

 

Logo depois devemos adicionar a classe Grade que será responsável por ter a disciplina junto a nota do aluno na referente disciplina:

import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;

public class Grade extends RealmObject {
@PrimaryKey
private long id;
private Discipline discipline;
private double grade;


public Discipline getDiscipline() {
return discipline;
}

public void setDiscipline(Discipline discipline) {
this.discipline = discipline;
}

public double getGrade() {
return grade;
}

public void setGrade(double grade) {
this.grade = grade;
}

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}
}

 

Com as configurações das classes do domínio do problema atualizadas, vamos a MainActivity colocar o button de acesso a Activity StudentsActivity para funcionar, segue código:

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

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

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

@Override
protected void onResume() {
super.onResume();

Button btDisciplines = (Button) findViewById(R.id.bt_disciplines);
Button btStudents = (Button) findViewById(R.id.bt_students);

Realm realm = Realm.getDefaultInstance();
RealmResults<Discipline> disciplines = realm.where(Discipline.class).findAll();
RealmResults<Student> students = realm.where(Student.class).findAll();

btDisciplines.setText( "Disciplinas ("+disciplines.size()+")" );
btStudents.setText( "Estudantes ("+students.size()+")" );
realm.close();
}


public void callDisciplines( View view){
Intent it = new Intent(this, DisciplinesActivity.class);
startActivity(it);
}


public void callStudents( View view){
Intent it = new Intent(this, StudentsActivity.class);
startActivity(it);
}
}

 

Ai sim vamos ao código de StudentsActivity, que é bem similar ao código de DisciplinesActivity do vídeo 1 da série, mudando apenas Discipline por Student (como apresentado no vídeo via Ctrl + A e Ctrl + R no AndroidStudio):

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ListView;

import br.com.thiengo.realmstudents.adapter.StudentAdapter;
import br.com.thiengo.realmstudents.domain.Student;
import io.realm.Realm;
import io.realm.RealmChangeListener;
import io.realm.RealmResults;

public class StudentsActivity extends AppCompatActivity {

private Realm realm;
private RealmResults<Student> students;
private RealmChangeListener realmChangeListener;
private ListView lvStudents;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_students);

realm = Realm.getDefaultInstance();

realmChangeListener = new RealmChangeListener() {
@Override
public void onChange() {
((StudentAdapter) lvStudents.getAdapter()).notifyDataSetChanged();
}
};

realm.addChangeListener(realmChangeListener);
students = realm.where( Student.class ).findAll();

lvStudents = (ListView) findViewById(R.id.lv_students);
lvStudents.setAdapter( new StudentAdapter( this, students, false ));
}


@Override
protected void onDestroy() {
realm.removeAllChangeListeners();
realm.close();
super.onDestroy();

}


public void callAddStudent( View view){
Intent it = new Intent( this, AddUpdateStudentActivity.class );
startActivity(it);
}
}

 

Sege layout xml de StudentsActivity (activity_students.xml):

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

<ListView
android:id="@+id/lv_students"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:onClick="callAddStudent"
android:text="Add estudante" />

</LinearLayout>

 

Segue adapter StudentAdapter, para se possível carregar os dados de Student no ListView lv_students:

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.AddUpdateStudentActivity;
import br.com.thiengo.realmstudents.R;
import br.com.thiengo.realmstudents.domain.Student;
import io.realm.Realm;
import io.realm.RealmBaseAdapter;
import io.realm.RealmResults;

public class StudentAdapter extends RealmBaseAdapter<Student> implements ListAdapter {

private Realm realm;

public StudentAdapter(Context context, RealmResults<Student> 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_student, 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 Student s = realmResults.get(position);
holder.tvName.setText( s.getName() );

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

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

return convertView;
}

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

 

Exatamente o mesmo que DisciplineAdapter, exceto que estamos com Student ao invés de Discipline. Segue código do layout dos itens plotads pelo adapter, item_student.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="5dp">

<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:textSize="18sp" />

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

<Button
android:id="@+id/bt_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Atualizar"
android:textSize="12sp" />

<Button
android:id="@+id/bt_remove"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Remover"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>

 

Seguindo a construção das Actities da entidade Student, vamos a Activity AddUpdateActivityStudent e seu respectivo layout, activity_add_update_student.xml:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import br.com.thiengo.realmstudents.domain.Student;
import io.realm.Realm;
import io.realm.RealmResults;

public class AddUpdateStudentActivity extends AppCompatActivity {

private Realm realm;
private RealmResults<Student> students;

private Student student;
private EditText etName;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_update_student);

student = new Student();
etName = (EditText) findViewById(R.id.et_name);
TextView tvTitle = (TextView) findViewById(R.id.tv_title);
Button btAddUpdate = (Button) findViewById(R.id.bt_add_update);


realm = Realm.getDefaultInstance();
students = realm.where( Student.class ).findAll();

if( getIntent() != null && getIntent().getLongExtra( Student.ID, 0 ) > 0 ){
student.setId( getIntent().getLongExtra( Student.ID, 0 ) );

student = students.where().equalTo("id", student.getId()).findAll().get(0);
etName.setText( student.getName() );
tvTitle.setText("Atualizar disciplina");
btAddUpdate.setText( "Update" );
}
}


@Override
protected void onDestroy() {
realm.close();
super.onDestroy();
}


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();

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();
}
}
}

 

Então o layout:

<?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">

<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:gravity="center"
android:padding="5dp"
android:text="Novo estudante"
android:textSize="18sp" />

<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:layout_marginTop="10dp"
android:hint="Nome" />

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

 

Com isso, nessa parte 2 do série ficamos por aqui, nas outras partes vamos começar a colocar as funcionalidades de adição dinêmica de bloco de notas (uma série de Views que serão adicionadas dinâmicamente ao perfil do estudante como blocos de notas para as disciplinas).

O código completo pode ser encontrado no GitHub do projeto (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 2:

 

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 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
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 (2)

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...
23/09/2016
Olá! Na parte 1 diz que vai ser abordado mais detalhes sobre migrations, porém, nessa parte 2 não possui esta abordagem. Estou com a seguinte situação, estou com uma propriedade de uma classe que herda de RealmObject que está com a notação Ignore, mas eu agora não desejo que ela seja ignorada. Teria como ajustar isso com o migration?

Abraços
Responder
Vinícius Thiengo (0) (0)
24/09/2016
Lucas, blz?
Dê uma olhada nos vídeos até o 5º da série (http://www.thiengo.com.br/migracao-de-dados-realm-library-no-android-parte-6 ) - ou vá direto a ele. Lá tem o migration. Mas fique ciente que não há impedimento em remover o Ignore, alias isso é comum, pois seu código está evoluindo. Pode ser que nem mesmo o migration do Realm sejá necessário. Abraço
Responder