Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Dúvida no Ex. 13 da Aula 6 - Completando o cadastro

Boa tarde,

Depois de fazer todos os exercícios e testar a minha aplicação, eu não consegui fazer funcionar o menu de contexto (não aparece com o clique longo) e nem atualizar o usuário (um novo é criado após criar em "Alterar"). Inicialmente apareceu um erro indicando que eu não tinha fechado a conexão com o banco, então revisei os códigos e alguns realmente estavam sem o dao.close(), mas mesmo após essa correção os erros continuaram.

FormulárioActivity:

package br.com.caelum.cadastro;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import br.com.caelum.cadastro.dao.AlunoDAO;
import br.com.caelum.cadastro.modelo.Aluno;

public class FormularioActivity extends Activity {

    private FormularioHelper helper;

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

        helper = new FormularioHelper(this);
        Button botao = (Button) findViewById(R.id.botao);

        Aluno alunoParaSerAlterado = (Aluno) getIntent().getSerializableExtra(Extras.ALUNO_SELECIONADO);

        if(alunoParaSerAlterado != null){
            botao.setText("Alterar");

            helper.colocaNoFormulario(alunoParaSerAlterado);
        }

        botao.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                Aluno aluno = helper.pegaAlunoDoFormulario();

                AlunoDAO dao = new AlunoDAO(FormularioActivity.this);

                if(aluno.getId() == null)
                    dao.insere(aluno);
                else
                    dao.alterar(aluno);

                dao.close();

//                Toast.makeText(FormularioActivity.this, "Aluno cadastrado: " + aluno.getNome(), Toast.LENGTH_LONG).show();
                finish();
            }
        });
    }    
}

ListaAlunosActivity:

package br.com.caelum.cadastro;

import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import br.com.caelum.cadastro.dao.AlunoDAO;
import br.com.caelum.cadastro.modelo.Aluno;

public class ListaAlunosActivity extends Activity{
    private ListView listaAlunos;
    private Aluno alunoSelecionado;

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

        AlunoDAO dao = new AlunoDAO(this);

        List<Aluno> alunos = dao.getLista();
        dao.close();
        listaAlunos = (ListView) findViewById(R.id.lista);
        registerForContextMenu(listaAlunos);
        ArrayAdapter<Aluno> adapter = new ArrayAdapter<Aluno>(this, android.R.layout.simple_list_item_1, alunos);

        listaAlunos.setAdapter(adapter);

        listaAlunos.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapter, View view, int posicao, long id) {
//                Toast.makeText(ListaAlunosActivity.this, "Posição selecionada: " + posicao, Toast.LENGTH_LONG).show();
                Intent edicao = new Intent(ListaAlunosActivity.this, FormularioActivity.class);
                alunoSelecionado = (Aluno) listaAlunos.getItemAtPosition(posicao);
                edicao.putExtra(Extras.ALUNO_SELECIONADO, alunoSelecionado);
                startActivity(edicao);
            }
        });

        listaAlunos.setOnItemLongClickListener(new OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> adapter, View view, int posicao, long id) {
                alunoSelecionado = (Aluno) adapter.getItemAtPosition(posicao);
                /*Toast.makeText(ListaAlunosActivity.this, "Nome: " + adapter.getItemAtPosition(posicao), Toast.LENGTH_LONG).show();*/
                return true;
            }
        });
    }

    private void carregaLista(){
        AlunoDAO dao = new AlunoDAO(this);
        List<Aluno> alunos = dao.getLista();
        ArrayAdapter<Aluno> adapter = new ArrayAdapter<Aluno>(this, android.R.layout.simple_list_item_1, alunos);
        listaAlunos.setAdapter(adapter);
        dao.close();
    }

    @Override
    protected void onResume() {
        super.onResume();
        this.carregaLista();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = this.getMenuInflater();
        inflater.inflate(R.menu.menu_principal, menu);

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_novo:
            Intent intent = new Intent(ListaAlunosActivity.this, FormularioActivity.class);
            startActivity(intent);
            return false;

        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        menu.add("Ligar");
        menu.add("Enviar SMS");
        menu.add("Achar no mapa");
        menu.add("Navegar no site");
        menu.add("Enviar email");
        MenuItem deletar = menu.add("Deletar");
        deletar.setOnMenuItemClickListener(new OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                AlunoDAO dao = new AlunoDAO(ListaAlunosActivity.this);
                dao.deletar(alunoSelecionado);
                dao.close();
                return false;
            }
        });
    }
}

AlunoDAO:

package br.com.caelum.cadastro.dao;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import br.com.caelum.cadastro.modelo.Aluno;

public class AlunoDAO extends SQLiteOpenHelper{

    private static final int VERSAO = 1;
    private static final String DATABASE = "CadastroCaelum";
    private static final String TABELA = "Alunos";

    public AlunoDAO(Context context) {
        super(context, DATABASE, null, VERSAO);
    }

    @Override
    public void onCreate(SQLiteDatabase database) {
        String sql = "CREATE TABLE Alunos (id INTEGER PRIMARY KEY, " +
                                          "nome TEXT UNIQUE NOT NULL, " +
                                          "telefone TEXT, " +
                                          "endereco TEXT, " +
                                          "site TEXT, " +
                                          "nota REAL, " +
                                          "caminhoFoto TEXT);";

        database.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
        String sql = "DROP TABLE IF EXISTS " + TABELA + ";";
        database.execSQL(sql);
        onCreate(database);
    }

    public void insere(Aluno aluno){
        ContentValues cv = new ContentValues();

        cv = toValues(aluno);

        getWritableDatabase().insert(TABELA, null, cv);
    }

    private ContentValues toValues(Aluno aluno) {
        ContentValues cv = new ContentValues();

        cv.put("nome", aluno.getNome());
        cv.put("telefone", aluno.getTelefone());
        cv.put("endereco", aluno.getEndereco());
        cv.put("site", aluno.getSite());
        cv.put("nota", aluno.getNota());
        cv.put("caminhoFoto", aluno.getCaminhoFoto());

        return cv;
    }

    public List<Aluno> getLista(){
        List<Aluno> alunos = new ArrayList<Aluno>();
        Aluno aluno;

        String sql = "SELECT * FROM " + TABELA + ";"; 
        Cursor cursor = getReadableDatabase().rawQuery(sql, null);

        while(cursor.moveToNext()){
            aluno = new Aluno();

            aluno.setNome(cursor.getString(cursor.getColumnIndex("nome")));
            aluno.setTelefone(cursor.getString(cursor.getColumnIndex("telefone")));
            aluno.setEndereco(cursor.getString(cursor.getColumnIndex("endereco")));
            aluno.setSite(cursor.getString(cursor.getColumnIndex("site")));
            aluno.setNota(Double.parseDouble(cursor.getString(cursor.getColumnIndex("nota"))));
            aluno.setCaminhoFoto(cursor.getString(cursor.getColumnIndex("caminhoFoto")));

            alunos.add(aluno);
        }

        return alunos;
    }

    public void deletar(Aluno aluno){
        String[] args = {aluno.getId().toString()};
        getWritableDatabase().delete(TABELA, "id=?", args);
    }

    public void alterar(Aluno aluno){
        ContentValues values = new ContentValues();
        values.put("nome", aluno.getNome());
        values.put("telefone", aluno.getTelefone());
        values.put("endereco", aluno.getEndereco());
        values.put("site", aluno.getSite());
        values.put("nota", aluno.getNota());
        values.put("caminhoFoto", aluno.getCaminhoFoto());

        String[] idParaSerAlterado = {aluno.getId().toString()};
        getWritableDatabase().update(TABELA, values, "id=?0", idParaSerAlterado);
    }
}

FormularioHelper:

package br.com.caelum.cadastro;

import android.widget.EditText;
import android.widget.SeekBar;
import br.com.caelum.cadastro.modelo.Aluno;

public class FormularioHelper {

    private EditText nome;
    private EditText telefone;
    private EditText endereco;
    private EditText site;
    private SeekBar nota;
    private Aluno aluno;

    public FormularioHelper(FormularioActivity activity) {
        aluno = new Aluno();

        nome = (EditText) activity.findViewById(R.id.nome);
        telefone = (EditText) activity.findViewById(R.id.telefone);
        endereco = (EditText) activity.findViewById(R.id.endereco);
        site = (EditText) activity.findViewById(R.id.site);
        nota = (SeekBar) activity.findViewById(R.id.nota);

    }

    public Aluno pegaAlunoDoFormulario(){
        aluno.setNome(nome.getEditableText().toString());
        aluno.setEndereco(endereco.getEditableText().toString());
        aluno.setSite(site.getEditableText().toString());
        aluno.setTelefone(telefone.getEditableText().toString());
        aluno.setNota(Double.valueOf(nota.getProgress()));

        return aluno;
    }

    public void colocaNoFormulario(Aluno aluno){
        nome.setText(aluno.getNome());
        telefone.setText(aluno.getTelefone());
        endereco.setText(aluno.getEndereco());
        site.setText(aluno.getSite());
        nota.setProgress(aluno.getNota().intValue());

        this.aluno = aluno;
    }
}
2 respostas
solução!

Olá Ingrid,

Para o problema da alteração, aparentemente os IDs dos alunos não estão sendo lidos no método getLista() da sua classe AlunoDAO. Desse modo, como nenhum aluno possui ID após ser lido do banco, seu formulário irá sempre inserir um novo aluno independente de ser uma inclusão ou alteração. Para corrigir adicione a linha abaixo dentro do while do método em questão:

public List<Aluno> getLista() {
    ...
    while(cursor.moveToNext()){
        ...
        aluno.setID(cursor.getLong(cursor.getColumnIndex("id")));
        ...
    }
    ...
}

Além disso, tem um caractere a mais no seu método alterar() na chamada ao método update() do SQLiteDatabase. Onde está escrito "id=?0" você deveria ter "id=?".

Sobre a questão do menu de contexto, quando você tem um OnItemLongClickListener associado à sua lista, esse listener é executado antes da abertura do menu de contexto. Na implementação desse listener devemos devolver um valor booleano indicando se o evento de clique deve ser propagado adiante ou se deve se encerrado ali mesmo após o término do listener. Se devolvemos true, dizemos ao Android que estamos consumindo este evento e que ele não será propagado para a abertura de um menu de contexto e nem para o listener de clique simples.

Isto significa que para resolver seu problema podemos simplesmente remover o OnItemLongClickListener da listaAlunos ou fazer com que esse listener devolva false.

Abraços!

Muito obrigada pela resposta, muito completa e bem explicada!