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

findViewById() retornando NULL

Olá,

Estou com o seguinte problema e não estou sendo capaz de encontrar o porque dele estar acontecendo:

Ao clicar no botão Salvar na actionBar do formulário é lançado um NullPointerException.

Este é o código para o clique no botão

public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == R.id.menu_formulario_ok) {
            Aluno aluno = helper.pegaAluno();
            Toast.makeText(FormularioActivity.this, "Contato" + aluno.getNome() +  "Salvo!", Toast.LENGTH_SHORT).show();
            finish();

        }
        return super.onOptionsItemSelected(item);
    }

Na classe FormularioHelper o que temos é o seguinte:

 private EditText campoNome;
    private EditText campoEndereco;
    private EditText campoTelefone;
    private EditText campoSite;
    private RatingBar campoNota;

       FormularioHelper(FormularioActivity activity){
        campoNome = (EditText) activity.findViewById(R.id.form_nome);
        campoEndereco = (EditText) activity.findViewById(R.id.form_endereco);
        campoTelefone = (EditText) activity.findViewById(R.id.form_telefone);
        campoSite = (EditText) activity.findViewById(R.id.form_site);
        campoNota = (RatingBar) activity.findViewById(R.id.form_nota);
    }
       public Aluno pegaAluno(){
        Aluno aluno = new Aluno();
        if(aluno != null )
        System.out.println("Aluno não é null");
        if(campoNome == null)
            System.out.println("CampoNome é nulo");
        aluno.setNome(campoNome.getText().toString());

       /*aluno.setEndereco(campoEndereco.getText().toString());
        aluno.setTelefone(campoTelefone.getText().toString());
        aluno.setSite(campoSite.getText().toString());
        aluno.setNota(Double.valueOf(campoNota.getProgress()));*/
        return aluno;
    }

Inseri esses logs e confirmei que de fato, o método findViewById está retornando null, consultando a documentação verifiquei que isto ocorre quando ele não encontra a View. O que não entendo é o porque ele não localiza, pois aparentemente os id's correspondem com o XML (usei o refactor para renomear, só para ter certeza).

 <EditText
            android:id="@+id/form_nome"
            android:hint="@string/nome"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <EditText
            android:id="@+id/form_endereco"
            android:hint="@string/endereco"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <EditText
            android:id="@+id/form_telefone"
            android:hint="@string/telefone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <EditText
            android:id="@+id/form_site"
            android:hint="@string/site"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <RatingBar
            android:layout_width="wrap_content"
            android:layout_height="73dp"
            android:numStars="5"
            android:layout_gravity="center"
            android:id="@+id/form_nota" />

Obs: em FormularioActivity a classe FormularioHelper é instanciada a passando como parâmetro para o construtor :

protected void onCreate(Bundle savedInstanceState) {
        helper = new FormularioHelper(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_formulario);}

Por fim, estes são os logs do erro

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: br.com.alura.agendaalura, PID: 16254
                  java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.EditText.getText()' on a null object reference
                      at br.com.alura.agendaalura.FormularioHelper.pegaAluno(FormularioHelper.java:32)
                      at br.com.alura.agendaalura.FormularioActivity.onOptionsItemSelected(FormularioActivity.java:35)
                      at android.app.Activity.onMenuItemSelected(Activity.java:3204)
                      at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:408)
...

Alguma ideia do que possa estar acontecendo? (talvez seja algo bem idiota, mas não estou visualizando, kkkk)

6 respostas

Olá Daniel, tudo bem?

Pelo que analisei no seu código, você está fazendo uma impressão para saber quando o campoNome é nulo. O que acontece é que o trecho:

aluno.setNome(campoNome.getText().toString());

é chamado independetemente dessa verificação do if que você está fazendo, e podemos ter um caso onde o campoNome seja nulo e o programa está tentando chamar o método getText() de um objeto nulo e por isso ocorreria a exception. Tente rever esse trecho do seu código.

Abs

Olá Rafael , obrigado por sua resposta!

Não era bem este o meu problema, acho que acabei deixando a pergunta confusa porque deixei esses testes que eu estava fazendo para entender melhor o que estava acontecendo. O que não estou compreendendo é porque as variaveis CampoNome, CampoEndereco... estão recebendo null do método findViewByID . Abaixo vou deixar o código sem os testes (que eram apenas uma tentativa de debugar e eu acabei esquecendo de apagar antes de postar a duvida) mas que gera o mesmo erro:

public class FormularioHelper {

    private EditText campoNome;
    private EditText campoEndereco;
    private EditText campoTelefone;
    private EditText campoSite;
    private RatingBar campoNota;

    FormularioHelper(FormularioActivity activity){
        campoNome = (EditText) activity.findViewById(R.id.form_nome);
        campoEndereco = (EditText) activity.findViewById(R.id.form_endereco);
        campoTelefone = (EditText) activity.findViewById(R.id.form_telefone);
        campoSite = (EditText) activity.findViewById(R.id.form_site);
        campoNota = (RatingBar) activity.findViewById(R.id.form_nota);
    }


    public Aluno pegaAluno(){
        Aluno aluno = new Aluno();

        aluno.setNome(campoNome.getText().toString());
        aluno.setEndereco(campoEndereco.getText().toString());
        aluno.setTelefone(campoTelefone.getText().toString());
        aluno.setSite(campoSite.getText().toString());
        aluno.setNota(Double.valueOf(campoNota.getProgress()));

        return aluno;
    }
}

Olá Daniel,

Entendi, pelo que analisei o FormularioHelper, ele me parece estar correto. Você conseguiria compartilhar seu projeto no github para que eu possa analisar?

Abs

solução!

Opa Daniel, tudo bem?

Não analisei muito bem, mas pelo que eu vi você cria uma instância do FormularioHelper antes de setar o layout.

No onCreate da sua Activity, coloque o helper = new FormularioHelper(this); depois do setContentView.

Abraços!!

Hey Leonardo, de fato agora funciona!

Fiquei focado entre o código da classe do Helper e no XML e isso acabou passando batido. Ok, então agora apenas para confirmar se entendi o que de fato estava ocasionando o problema:

No curso aprendemos que todas as Views no XML tem seus objetos correspondentes instanciados pelo método setContentView() , então no momento eu que eu chamei o construtor da classe FormularioHelper antes do setContent estes objetos ainda não tinham sido instanciados e por isso o método findViewById não conseguiu localiza-los e retornou null para as variáveis CampoNome, CampoEndereco...

Posteriormente quando eu tentei usar um .getText() (no evento do botão da actionBar)nessas variáveis nulas (que eu pensava que tinha sido populadas corretamente, pois o código estava correto) foi lançada uma NullPointerException.

Estou correto neste pensamento ???

Desde já obrigado ao Rafael e Leonardo, quando confirmar a pergunta acima eu marco como solucionado!

Mandou bem Daniel, isso aí!

Abração!!