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

Dúvida no Ex. 1 da Aula 5 - Editando alunos [Carregar lista]

Pessoal, a minha aplicação não está carregando, só sobe se eu chamar o método de carregarLista() antes de registar a lista no menu de contexto, já declarei minha lista como um atributo da Activity, isso está correto?

4 respostas

Mostra o código da sua ListaAlunosActivity, pra eu dar uma olhada?

package com.example.gabriel.agenda;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.example.gabriel.agenda.dao.AlunoDAO;
import com.example.gabriel.agenda.modelo.Aluno;

import java.util.List;

public class ListaAlunosActivity extends AppCompatActivity {

    private ListView listaAlunos;

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

        Button button = (Button) findViewById(R.id.lista_alunos_novo);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(ListaAlunosActivity.this, FormularioActivity.class);
                startActivity(intent);
            }
        });
        registerForContextMenu(listaAlunos);
        carregarLista();
    }

    @Override
    protected void onResume() {
        super.onResume();
        //carregarLista();
        //registerForContextMenu(listaAlunos);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        MenuItem deletar = menu.add("Deletar");

        deletar.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                Toast.makeText(ListaAlunosActivity.this, "Clique", Toast.LENGTH_SHORT).show();
                return false;
            }
        });
    }

    private void carregarLista() {
        AlunoDAO alunoDAO = new AlunoDAO(this);
        List<Aluno> alunos = alunoDAO.listar(this);
        alunoDAO.close();

        listaAlunos = (ListView) findViewById(R.id.lista_alunos);
        ArrayAdapter<Aluno> adapter = new ArrayAdapter<Aluno>(this, android.R.layout.simple_list_item_1, alunos);
        listaAlunos.setAdapter(adapter);
    }
}

Para funcionar o carregaLista() tem que executar antes de registrar a listaAlunos para Menu de Contexto, por quê? Eu declarei a minha lista com um atributo.

solução!

Coloquei em evidência os principais trechos do código que causam esse bug:

public class ListaAlunosActivity extends AppCompatActivity {

    private ListView listaAlunos;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //...
        registerForContextMenu(listaAlunos);
        carregarLista();
    }
}

Quando você chama o registerForContextMenu, a listaAlunos está nula. Veja que até a chamada do registerForContextMenu, você não fez um findViewById pra atribuir algo pro seu listaAlunos.

No entanto, quando você chama o carregarLista antes, funciona pois o carregaLista faz o findViewById que estava faltando, olha só:

    private void carregarLista() {
        //...
        listaAlunos = (ListView) findViewById(R.id.lista_alunos);
        //....
    }

Então, ao fazer esse código, o registerForContextMenu recebe uma referência diferente de null e seu código funciona.

public class ListaAlunosActivity extends AppCompatActivity {

    private ListView listaAlunos;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //...
        carregarLista();
        registerForContextMenu(listaAlunos);
    }
}

Minha sugestão seria deixar sempre o findViewById no onCreate, para evitar esses comportamentos inesperados.

Felipe muito obrigado!