A classe DAO:
@NonNull
private ContentValues getContentValues(Aluno aluno) {
//Método que recebe um aluno como argumento e que recupera deste objeto os seus dados
//E então coloca os mesmos em cada linha da tabela.
ContentValues dados = new ContentValues();
dados.put("nome", aluno.getNome());
dados.put("telefone", aluno.getTelefone());
dados.put("endereco", aluno.getEndereco());
dados.put("twitter", aluno.getTwitter());
dados.put("snapchat", aluno.getSnapchat());
dados.put("facebook", aluno.getFacebook());
dados.put("instagram", aluno.getInstagram());
dados.put("nota", aluno.getNota());
return dados;
}
public void insere(Aluno aluno) {
SQLiteDatabase db = getWritableDatabase();
ContentValues dados = getContentValues(aluno);
db.insert("alunos",null,dados);
}
public List<Aluno> buscaAluno(){
String sql = "SELECT * FROM alunos;";
SQLiteDatabase db = getReadableDatabase();
Cursor c = db.rawQuery(sql, null);
List<Aluno> alunos = new ArrayList<>();
while (c.moveToNext()){
Aluno aluno = new Aluno();
aluno.setId(c.getLong(c.getColumnIndex("id")));
aluno.setNome(c.getString(c.getColumnIndex("nome")));
aluno.setTelefone(c.getString(c.getColumnIndex("telefone")));
aluno.setEndereco(c.getString(c.getColumnIndex("endereco")));
aluno.setTwitter(c.getString(c.getColumnIndex("twitter")));
aluno.setSnapchat(c.getString(c.getColumnIndex("snapchat")));
aluno.setFacebook(c.getString(c.getColumnIndex("facebook")));
aluno.setInstagram(c.getString(c.getColumnIndex("instagram")));
aluno.setNota(c.getDouble(c.getColumnIndex("nota")));
alunos.add(aluno);
}
c.close();
return alunos;
}
public void deleta(Aluno aluno) {
SQLiteDatabase db = getWritableDatabase();
String [] params = {aluno.getId().toString()};
db.delete("alunos","id=?",params);
}
public void altera(Aluno aluno) {
SQLiteDatabase db = getWritableDatabase();
//Recuperamos uma instancia do banco de dados, que usaremos para alterar o mesmo.
ContentValues dados = getContentValues(aluno);
//Declaramos uma váriavel do tipo ContentValues, que recebe o retorno do método getContentValues();
String[] params = {aluno.getId().toString()};
//Preparamos nossa String de argumentos, que passaremos como parâmetro para a nossa "query".
db.update("alunos",dados,"id=?",params);
//Chamamos o método update. Passamos: a tabela que será modificada na query, passamos os dados que
//Serão alterados, passamos o ID do registro que será alterado. Passamos a String com os parametros
//Que serão modificados.
A classe Modelo:
public class Aluno implements Serializable {
private long id;
private String nome;
private String telefone;
private String endereco;
private String twitter;
private String snapchat;
private String facebook;
private String instagram;
private Double nota;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getTelefone() {
return telefone;
}
public void setTelefone(String telefone) {
this.telefone = telefone;
}
public String getEndereco() {
return endereco;
}
public void setEndereco(String endereco) {
this.endereco = endereco;
}
public String getTwitter() {
return twitter;
}
public void setTwitter(String twitter) {
this.twitter = twitter;
}
public String getSnapchat() {
return snapchat;
}
public void setSnapchat(String snapchat) {
this.snapchat = snapchat;
}
public String getFacebook() {
return facebook;
}
public void setFacebook(String facebook) {
this.facebook = facebook;
}
public String getInstagram() {
return instagram;
}
public void setInstagram(String instagram) {
this.instagram = instagram;
}
public Double getNota() {
return nota;
}
public void setNota(Double nota) {
this.nota = nota;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public String toString() {
return getId() + " - " + getNome();
}
}
A FormularioHelper:
public class FormHelper {
private EditText nome;
private EditText telefone;
private EditText endereco;
private EditText twitter;
private EditText snapchat;
private EditText facebook;
private EditText instagram;
private RatingBar nota;
private Aluno aluno;
//Aqui usamos agregação, temos um atributo do tipo aluno na classe.
public FormHelper(AppCompatActivity form){
nome = (EditText) form.findViewById(R.id.formulario_nome);
telefone = (EditText) form.findViewById(R.id.formulario_telefone);
endereco = (EditText) form.findViewById(R.id.formulario_endereco);
twitter = (EditText) form.findViewById(R.id.formulario_twitter);
snapchat = (EditText) form.findViewById(R.id.formulario_snapchat);
facebook = (EditText) form.findViewById(R.id.formulario_facebook);
instagram = (EditText) form.findViewById(R.id.formulario_instagram);
nota = (RatingBar) form.findViewById(R.id.formulario_barra_avaliacao);
aluno = new Aluno();
//Instanciamos o nosso objeto aluno no constutor da classe aluno.
}
public Aluno pegaAluno(){
//Note que não precisamos instaciar o nosso objeto aluno para pegar os seus métodos e nem
//Para colocar dados dentro do mesmo, isso porque o nosso objeto Aluno já foi instanciado na
//Criação da classe, no construtor.
aluno.setNome(nome.getText().toString());
aluno.setTelefone(telefone.getText().toString());
aluno.setEndereco(endereco.getText().toString());
aluno.setTwitter(twitter.getText().toString());
aluno.setSnapchat(snapchat.getText().toString());
aluno.setFacebook(facebook.getText().toString());
aluno.setInstagram(instagram.getText().toString());
aluno.setNota(Double.valueOf(nota.getProgress()));
return aluno;
}
public void preencheFormulario(Aluno aluno) {
//Criamos o método que coloca as informações do aluno em ordem. No método pegaAluno, recuperamos as infor
//mações do aluno do formulário, nesse método, colocamos as informações recuperadas no formulário.
nome.setText(aluno.getNome());
telefone.setText(aluno.getTelefone());
endereco.setText(aluno.getEndereco());
twitter.setText(aluno.getTwitter());
snapchat.setText(aluno.getSnapchat());
facebook.setText(aluno.getFacebook());
instagram.setText(aluno.getInstagram());
nota.setProgress(aluno.getNota().intValue());
this.aluno = aluno;
//Nessa ultima linha, recuperamos o Objeto aluno, com todos os dados (Inclusive o ID, que iremos
// precisar para alterar o BD).
}
}
A ListaAlunosActivity:
private ListView listaAlunos;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); //Usa o estado salvo na classe AppComaptActivity
setContentView(R.layout.activity_lista_alunos);//Usa o layout salvo na pasta res,
// na pasta layout e o arquivo nome_activity.xml
listaAlunos = (ListView) findViewById(R.id.lista_alunos);
//Aqui recuperamos a lista e guardamos a mesma em uma váriavel global. Isso porque definimos a lista como
//Atributo da classe. E na criação da classe recuperamos o valor desse atributo.
listaAlunos.setOnItemClickListener(new AdapterView.OnItemClickListener() {
//Coloca um listener na lista, esse pega em qual subElemento ocorreu o click
@Override
public void onItemClick(AdapterView<?> lista, View item, int posicao, long id) {
//Os parametros são, lista (Pai do sub componente), o item que foi clicado (view),
//A posição do elemento na lista, e o seu ID.
Aluno aluno = (Aluno) listaAlunos.getItemAtPosition(posicao);
//Esse método pega o aluno dada a sua posição na lista, o retorno desse método é do tipo
//Object. Por isso o cast para Aluno (Downcast).
//Agora dado um click na lista recuperamos, pela sua posição qual aluno foi clicado.
Intent vaiProFormulario = new Intent(ListaAlunosActivity.this, FormularioActivity.class);
//Criamos uma intenção de irmos para a activity formulario.java. Então dizemos isso ao android
//Criamos um objeto do tipo intent e passamos no construtor onde estamos e para onde queremos ir
vaiProFormulario.putExtra("aluno",aluno);
//Chamamos o método putExtra e passamos o que queremos levar para a formulário activity
//Nesse caso levamos o nosso objeto aluno (Serializado, por isso implementamos a interface
// Serializable). Passamos também uma etiqueta no objeto isso porque é o que vamos chamar na
//FormularioActivity.class.
startActivity(vaiProFormulario);
//Começamos a intenção no clique em um item da lista.
}
});
carregaLista();
Button botao = (Button) findViewById(R.id.lista_alunos_adicionar);
botao.setOnClickListener(new View.OnClickListener() {//Criação da Classe anônima, que implementa interface
@Override
public void onClick(View v) {
Intent ir_Formulario = new Intent(ListaAlunosActivity.this, FormularioActivity.class);
startActivity(ir_Formulario);
}
});
registerForContextMenu(listaAlunos);
}
private void carregaLista() {
AlunoDAO dao = new AlunoDAO(this);
List<Aluno> alunos = dao.buscaAluno();
dao.close();
ArrayAdapter<Aluno> adaptador = new ArrayAdapter(this, R.layout.support_simple_spinner_dropdown_item, alunos);
listaAlunos.setAdapter(adaptador);
}
@Override
protected void onResume() {
super.onRestart();
carregaLista();
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, final ContextMenu.ContextMenuInfo menuInfo) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
//Recuperamos o Item que foi clicado na lista.
final Aluno aluno = (Aluno) listaAlunos.getItemAtPosition(info.position);
//Guardamos o objeto que foi clicado na lista, dentro de um objeto do tipo Aluno. Como essa váriavel foi declarada fora de uma
//classe anônima e está sendo usada dentro de uma, o Android nos obriga a declarar a mesma como final.
//--------------------------------------------------------------------------------------------------------------//
MenuItem itemSite = menu.add("Visitar Instagram");
//Adicionamos mais uma opção no menu de contexto. Logo após um clique longo, aparecerá 2 opções no menu de contexto.
//Visitar instagram e Deletar.
Intent vaiProSite = new Intent(Intent.ACTION_VIEW);
//Aqui passamos uma Intent Ímplicita, isso é, dizemos ao Android: "Quero abrir um site, me dê a Intent mais recomendada
//Pra esse trabalho.
String site = "https://www.instagram.com/" + aluno.getInstagram() + "/";
//Recuperamos o instagram do objeto aluno, Concatenamos com o endereço do instagram e com as duas barras necessárias da URL.
vaiProSite.setData(Uri.parse(site));
//Aqui passamos um dado obrigatório para a Intent. Esse dado é obrigatório por um motivo, caso ele não seja
//passado, não existe Intent. Logo ele precisa ser passado, esse dado é o endereço do Instagram.
itemSite.setIntent(vaiProSite);
//Aqui Associamos o nosso menu de contexto a uma Intent, isso é, dizemos que quando clicarmos em um menu de contexto, essa Intent
//Será automáticamente executada.
//----------------------------------------------------------------------------------------------------------------------//
MenuItem itemMensagem = menu.add("Enviar Mensagem");
//Adiciona uma nova opção no menu de contexto
Intent enviarMensagem = new Intent(Intent.ACTION_VIEW);
//Cria uma nova intent onde dizemos que queremos vizualizar algo, e deixamos o usuário decidir como vai visualizar
enviarMensagem.setData(Uri.parse("sms:" + aluno.getTelefone()));
//Colocamos o protocolo da URI, junto com o telefone do aluno.
itemMensagem.setIntent(enviarMensagem);
//Aqui associamos a nossa opção de menu com a nossa Intent.
//----------------------------------------------------------------------------------------------------------------------//
//"Mesma coisa" dos outros menus, muda apenas o protocolo do URI, e o que aparece no menu de contexto.
MenuItem itemMapa = menu.add("Visualizar a casa do Aluno no Mapa");
Intent verMapa = new Intent(Intent.ACTION_VIEW);
verMapa.setData(Uri.parse("geo:0,0?q=" + aluno.getEndereco()));
itemMapa.setIntent(verMapa);
//---------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------//
MenuItem deletar = menu.add("Deletar");
deletar.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
AlunoDAO alunoDAO = new AlunoDAO(ListaAlunosActivity.this);
alunoDAO.deleta(aluno);
alunoDAO.close();
carregaLista();
return false;
}
});
}
}
E por último a Formulário Activity:
private FormHelper form;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_formulario);
form = new FormHelper(this);
//Intanciamos a nossa classe que abstrai a lógica que usamos no formulário.
Intent intencao = getIntent();
//Recuperamos a intenção que nos trouxe aqui. E guardamos o seu retorno em uma
//Váriavel
Aluno aluno = (Aluno) intencao.getSerializableExtra("aluno");
//Aqui "inflamos" novamente o nosso objeto que veio "pendurado" na nossa intent, pois foi isso que fizemos
//Penduramos um objeto serializado, do tipo Aluno, em nossa intent. Aqui recuperamos o nosso aluno
if(aluno != null){
//Temos dois modos de vir para o formulário, quando queremos cadastrar um novo aluno e quando queremos
//editar um que já existe, logo só vamos colocar dados no nosso formulário quando o objeto aluno não
// estiver vazio. Caso ele esteja, ignoramos o mesmo.
form.preencheFormulario(aluno);
//Chamamos o método que coloca as informações do objeto em ordem.
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) { //Cria um menu na Activity, isso é recebe um objeto menu e
//retorna um objeto do tipo menu.
getMenuInflater().inflate(R.menu.formulario_activity, menu);//O método getMenuInflate,chama o método
//Inflater e recebe como argumento o nome do menu que ele vai inflar, ou seje, transformar de XML
// para Java, e recebe o que ele vai inflar, nesse caso um menu.
return super.onCreateOptionsMenu(menu);//Retorna o objeto menu criado e inflado.
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.menu_formulario_salvar:
AlunoDAO dao = new AlunoDAO(this);
Aluno aluno = form.pegaAluno();
//Instancia o objeto dao, com todos os seus métodos e afins.
if(aluno.getId() == null){
//Caso o id do Aluno que temos no formulário seja DIFERENTE de nulo, ou seja se esse já tiver
//Ido ao formulário e recebido um ID.
dao.insere(aluno);
Toast.makeText(FormularioActivity.this, aluno.getNome() +" cadastrado(a)!",
Toast.LENGTH_SHORT).show();
}else{
dao.altera(aluno);
//Caso o ID seja nulo, ou seja caso o aluno não tenha ido ao banco de dados ainda, chamamos
//O método insere, e não o altera.
Toast.makeText(FormularioActivity.this, aluno.getNome() +" Alterado com sucesso(a)!",
Toast.LENGTH_SHORT).show();
}
dao.close();
//Fechamos a conexão com o banco de dados.
finish();
//Terminamos o método
break;
//Paramos o switch
}
return super.onOptionsItemSelected(item);
}
}
Cara, tá tudo funcionando, só naquela parte que dá aquele bug. Se você conseguir encontrar eu ficarei grato, pois já tentei tudo e já revirei esse código de cabo a rabo.
Att, Obrigado.