Persistência de Dados Com Realm no Android - Parte 2
(2380) (2)
CategoriasAndroid, Design, Protótipo
AutorVinÃcius Thiengo
VÃdeo aulas186
Tempo15 horas
ExercÃciosSim
CertificadoSim
CategoriaEngenharia de Software
Autor(es)Kent Beck
EditoraNovatec
Edição1ª
Ano2024
Páginas112
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:
Comentários Facebook