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

ListaAlunosActivity cannot be cast to android.view.View$OnClickListener

Pessoal, Fiz o curso com a versão 3.2.1 do Android Studio, o que acontece que quando do inicio do curso fui tentar abrir a mesma Activity no processo de criação do projeto ( "Blank Activity"), porém esse recurso não está estava disponível nessa versão do Android e criei o projeto com uma Activity que pensava que era similar "Basic Activity". Fiz o curso exatamente igual às vídeos aulas e chegando na parte onde na parte onde tinha que trocar o botão "Salvar" de lugar subindo o para menu, percebi que minha Activity não tinha esse menu, então eu resolvi continuar os estudos com o botão de salvar onde estava mesmo, e não removi da class "FormularioActivity".

. . .
public class FormularioActivity extends AppCompatActivity {

    private FormularioHelper helper;

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

       /*Inicio do tratamento do botão salvar*/
        Button botaoSalvar = (Button) findViewById(formulario_salvar);
        botaoSalvar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            /*aqui é onde criamos o evento do botão*/
                //Depois de clicar no botão o código abaixo vai recuperar as informações na active lista de alunos
                Aluno aluno = helper.pegaAluno();
                AlunoDAO dao = new AlunoDAO(this);
                dao.insere(aluno);
                dao.close();

                Toast.makeText(FormularioActivity.this, "Aluno " + aluno.getNome() + " Salvo", Toast.LENGTH_SHORT).show();
                finish(); //ao invés de criar um novo tratamento indo pra outra tela, coloca-se apenas o "finish()" para não duplicar a tela

            }
        });
    }
// Aqui estamos criando uma instância que faz o botão salver ir para barra de título
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_formulario, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        /*aqui é onde criamos o evento do botão*/
        switch (item.getItemId()){
            case R.id.menu_formulario_ok:

                //Depois de clicar no botão o código abaixo vai recuperar as informações na active lista de alunos
                Aluno aluno = helper.pegaAluno();
                Toast.makeText(FormularioActivity.this, "Aluno " + aluno.getNome() + " Salvo", Toast.LENGTH_SHORT).show();
            finish(); //ao invés de criar um novo tratamento indo pra outra tela, coloca-se apenas o "finish()" para não duplicar a tela
            break;
        }

        return super.onOptionsItemSelected(item);
    }
}

As outras classes ficaram exatamente iguais. Quando cheguei na aula Ciclo de Vida das Activity no vídeo 4 "Buscando Aluno no banco", comecei ter problemas de compilação na classe "ListaAlunosActivity" durante a chamada da classe AlunoDAO, logo após a retirada da String Array de nomes, o compilador já não aceitava referenciar a classa "AlunoDAO dao = new AlunoDAO(onClickListener this);", não aceitava o contexto, aí o compilador me deu uma outra alternativa que seria referenciar a classe AlunoDAO por meio da chamada "AlunoDAO dao = new AlunoDAO((View.OnClickListener)this);", problemas de "cast" já que o botão Salvar em baixo permanece. Tentei ir ajustando por soluções do compilador "por meio do alt+enter" permitia para continuar acompanhando aula sem retirar o meu botão Salvar, cheguei até conseguir compilar, porém ao simular aplicação para testar o processo de Salvar Aluno para exibir o aluno na tela "Lista de Alunos", o LogCat mostrou o seguinte erro:

"  --------- beginning of crash
01-23 00:19:30.912 2737-2737/br.com.fabianoneves.agenda E/AndroidRuntime: FATAL EXCEPTION: main
    Process: br.com.fabianoneves.agenda, PID: 2737
    java.lang.RuntimeException: Unable to start activity ...
Caused by: java.lang.ClassCastException: br.com.fabianoneves.agenda.ListaAlunosActivity cannot be cast to android.view.View$OnClickListener
        at br.com.fabianoneves.agenda.ListaAlunosActivity.onCreate(ListaAlunosActivity.java:31)
        at android.app.Activity.performCreate(Activity.java:6237) "

Não permitiu mais simular por problemas na Activity, o correto tratamento de evento no botão Salvar, não reconhece o Cast por ser Activity diferente. Como resolver o problema?

7 respostas
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

import java.util.List;

import br.com.fabianoneves.agenda.DAO.AlunoDAO;
import br.com.fabianoneves.agenda.modelo.Aluno;

public class ListaAlunosActivity extends AppCompatActivity {

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

        //Essa instrução por referências, array, ListView, context, é o gatinho de construção que faz
        //aparecer uma relação de nomes em lista para não precisar de criar uma TAG de XML para cada nome.

        //AlunoDAO dao = new AlunoDAO((View.OnClickListener)this);
        AlunoDAO dao = new AlunoDAO(this);
        List<Aluno> alunos = dao.buscaAlunos();
        dao.close();

        //String[] alunos = {"Fabiano Neves", "Brendown Moura", "Bryan Moura", "Elisangela Araújo"};
        ListView listaAlunos = findViewById(R.id.lista_alunos);
        ArrayAdapter <Aluno> adapter = new ArrayAdapter<Aluno>(this, android.R.layout.simple_list_item_1, alunos);
        listaAlunos.setAdapter(adapter);

        //Aqui Estamos dando tratamento para o botão vermelho '+' chamar a tela Formulário
        Button novoAluno = (Button) findViewById(R.id.novo_aluno);
        novoAluno.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) { //É aqui que diz de onde estou e para qual tela devo ir
            Intent intentVaiProFormulario = new Intent(ListaAlunosActivity.this, FormularioActivity.class);
            startActivity(intentVaiProFormulario);
            }
        });
    }
}

Fernando, identifiquei os seguintes pontos

FormularioActivity

Quando esta buscando a referência ao seu botão salvar, você não esta identificando o id do seu Button. Lembre de utilizar R.id.identificador da view

Button botaoSalvar = (Button) findViewById(formulario_salvar);  /* Verificar aqui */

Quando esta tratando o evento de clique do botão salvar, você cria uma instância de AlunoDao, passando this por parâmetro. Mas como está no contexto de uma classe anônima (que no caso é a View.OnClickListener), o this é a referência a classe anônima.

O correto é:

 AlunoDAO dao = new AlunoDAO(FormularioActivity.this);

Caso ainda tenha erros, poste seu código completo, fica mais fácil para identificar o problema

Olá Alessandro, mesmo com sua orientação ainda estou tomando erro.

:23.325 2514-2514/com.android.email E/ActivityThread: Service com.android.email.service.EmailBroadcastProcessorService has leaked ServiceConnection com.android.emailcommon.service.ServiceProxy$ProxyConnection@4412c27 that was originally bound here
    android.app.ServiceConnectionLeaked: Service com.android.email.service.EmailBroadcastProcessorService has leaked ServiceConnection com.android.emailcommon.service.ServiceProxy$ProxyConnection@4412c27 that was originally bound here
        at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1092)
        at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:986)
        at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1303)
        at android.app.ContextImpl.bindService(ContextImpl.java:1286)
        at android.content.ContextWrapper.bindService(ContextWrapper.java:604)
        at com.android.emailcommon.service.ServiceProxy.setTask(ServiceProxy.java:181)
        at com.android.emailcommon.service.ServiceProxy.test(ServiceProxy.java:224)
        at com.android.email.service.EmailServiceUtils.isServiceAvailable(EmailServiceUtils.java:160)
        at com.android.email.provider.AccountReconciler.reconcileAccountsInternal(AccountReconciler.java:171)
        at com.android.email.provider.AccountReconciler.reconcileAccounts(AccountReconciler.java:115)
        at com.android.email.service.EmailBroadcastProcessorService.reconcileAndStartServices(EmailBroadcastProcessorService.java:305)
        at com.android.email.service.EmailBroadcastProcessorService.onBootCompleted(EmailBroadcastProcessorService.java:295)
        at com.android.email.service.EmailBroadcastProcessorService.onHandleIntent(EmailBroadcastProcessorService.java:130)
        at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.os.HandlerThread.run(HandlerThread.java:61)

LogCat

FormularioActivity

package br.com.fabianoneves.agenda;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import br.com.fabianoneves.agenda.DAO.AlunoDAO;
import br.com.fabianoneves.agenda.modelo.Aluno;

import static br.com.fabianoneves.agenda.R.id.*;

public class FormularioActivity extends AppCompatActivity {

    private FormularioHelper helper;

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

       /*Inicio do tratamento do botão salvar*/
        Button botaoSalvar = (Button) findViewById(formulario_salvar);
        botaoSalvar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            /*aqui é onde criamos o evento do botão*/
                //Depois de clicar no botão o código abaixo vai recuperar as informações na active lista de alunos
                Aluno aluno = helper.pegaAluno();
                AlunoDAO dao = new AlunoDAO((View.OnClickListener)FormularioActivity.this);
                dao.insere(aluno);
                dao.close();

                Toast.makeText(FormularioActivity.this, "Aluno " + aluno.getNome() + " Salvo", Toast.LENGTH_SHORT).show();
                finish(); //ao invés de criar um novo tratamento indo pra outra tela, coloca-se apenas o "finish()" para não duplicar a tela

            }
        });
    }
// Aqui estamos criando uma instância que faz o botão salver ir para barra de título
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_formulario, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        /*aqui é onde criamos o evento do botão*/
        switch (item.getItemId()){
            case R.id.menu_formulario_ok:

                //Depois de clicar no botão o código abaixo vai recuperar as informações na active lista de alunos
                Aluno aluno = helper.pegaAluno();
                Toast.makeText(FormularioActivity.this, "Aluno " + aluno.getNome() + " Salvo", Toast.LENGTH_SHORT).show();
            finish(); //ao invés de criar um novo tratamento indo pra outra tela, coloca-se apenas o "finish()" para não duplicar a tela
            break;
        }

        return super.onOptionsItemSelected(item);
    }
}

ListaAlunoActivity

package br.com.fabianoneves.agenda;

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

import java.util.List;

import br.com.fabianoneves.agenda.DAO.AlunoDAO;
import br.com.fabianoneves.agenda.modelo.Aluno;

public class ListaAlunosActivity extends AppCompatActivity {

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

        //Essa instrução por referências, array, ListView, context, é o gatinho de construção que faz
        //aparecer uma relação de nomes em lista para não precisar de criar uma TAG de XML para cada nome.

        //AlunoDAO dao = new AlunoDAO((View.OnClickListener)this);
        AlunoDAO dao = new AlunoDAO((View.OnClickListener)this);
        List<Aluno> alunos = dao.buscaAlunos();
        dao.close();

        //String[] alunos = {"Fabiano Neves", "Brendown Moura", "Bryan Moura", "Elisangela Araújo"};
        ListView listaAlunos = findViewById(R.id.lista_alunos);
        ArrayAdapter <Aluno> adapter = new ArrayAdapter<Aluno>(this, android.R.layout.simple_list_item_1, alunos);
        listaAlunos.setAdapter(adapter);

        //Aqui Estamos dando tratamento para o botão vermelho '+' chamar a tela Formulário
        Button novoAluno = (Button) findViewById(R.id.novo_aluno);
        novoAluno.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) { //É aqui que diz de onde estou e para qual tela devo ir
            Intent intentVaiProFormulario = new Intent(ListaAlunosActivity.this, FormularioActivity.class);
            startActivity(intentVaiProFormulario);
            }
        });
    }
}

AlunoDAO

package br.com.fabianoneves.agenda.DAO;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.support.annotation.Nullable;
import android.view.View;

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

import br.com.fabianoneves.agenda.modelo.Aluno;

public class AlunoDAO extends SQLiteOpenHelper {

 /*   public AlunoDAO(Context context) {
       super((Context) context, "Agenda", null, 1);
    }*/

    public AlunoDAO(View.OnClickListener onClickListener) {
        super((Context) onClickListener, "Agenda", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "CREATE TABLE Alunos (id INTERGER PRIMARY KEY, nome TEXT NOT NULL, endereco TEXT, cidade  TEXT, uf TEXT, telefone TEXT, celular TEXT, email TEXT, site TEXT, nota REAL);";
        db.execSQL(sql);
    }

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

    public void insere(Aluno aluno) {
        //Procedimento abaixo é a forma mais segura de povoar o BD.
        //Ele pega por meio do get o que foi escrito na active formulario e povoa o BD
        SQLiteDatabase db = getWritableDatabase();
        ContentValues dados = new ContentValues();
        dados.put("nome", aluno.getNome());
        dados.put("endereco", aluno.getEndereco());
        dados.put("cidade", aluno.getCidade());
        dados.put("uf", aluno.getUf());
        dados.put("telefone", aluno.getTelefone());
        dados.put("celular", aluno.getCelular());
        dados.put("email", aluno.getEmail());
        dados.put("site", aluno.getSite());
        dados.put("nota", aluno.getNota());
        db.insert("Alunos", null, dados); //a forma android de passar o parametro para povoar o BD motando a querry pelo android
    }

    public List<Aluno> buscaAlunos() {
        String sql = "SELECT * FROM Alunos;";
        SQLiteDatabase db = getReadableDatabase();
        //db.execSQL(sql); // só que ao invés desse comando vamos utilizar o "rawQuerry(sql)";
        //temos que criar um cursos para que o problema rode linha a linha a tabela criada.
        Cursor c = db.rawQuery(sql, null);

        List<Aluno> alunos = new ArrayList<Aluno>();
        while (c.moveToNext()){// o moveToNext(), além de mover o cursos ele nos informa se chegou a última linha mas para isso precisamos de criar o comando while
            Aluno aluno = new Aluno();
            aluno.setId(c.getLong(c.getColumnIndex("id")));
            aluno.setNome(c.getString(c.getColumnIndex("nome")));
            aluno.setEndereco(c.getString(c.getColumnIndex("endereco")));
            aluno.setCidade(c.getString(c.getColumnIndex("cidade")));
            aluno.setUf(c.getString(c.getColumnIndex("uf")));
            aluno.setTelefone(c.getString(c.getColumnIndex("telefone")));
            aluno.setCelular(c.getString(c.getColumnIndex("celular")));
            aluno.setEmail(c.getString(c.getColumnIndex("email")));
            aluno.setSite(c.getString(c.getColumnIndex("site")));
            aluno.setNota(Double.valueOf(c.getString(c.getColumnIndex("nota"))));

            alunos.add(aluno);

        };
        c.close();
        return null;
    }
}
solução!

Na classe FormularioActivity, você precisa alterar esta linha

AlunoDAO dao = new AlunoDAO((View.OnClickListener)FormularioActivity.this);

Por esta linha:

AlunoDAO dao = new AlunoDAO(FormularioActivity.this);

Na classe AlunoDAO, altere o construtor para que ele receba um Context

Esta assim:

public AlunoDAO(View.OnClickListener onClickListener) {
        super((Context) onClickListener, "Agenda", null, 1);
    }

Faça esta alteração:

public AlunoDAO(Context context) {
        super(context, "Agenda", null, 1);
    }