Pegar item de ListView e mostrar em campo de outra tela

30 respostas
F

Boa noite meus amigos,

Estou com o seguinte problema:

Tenho uma classe que se chama BuscaCliente e nela tem uma lista. Quero clicar num item da lista e mandar para outra tela o nome e id. A tela chama CarrosCliente. O código abaixo chama a tela ao clicar, mas manda os dados em branco.

// Clicar em item da lista e mostra nos campos da tela de cadastro
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
    	super.onListItemClick(l, v, position, id);
		Intent intent = new Intent(this, CarrosCliente.class);
		intent.putExtra(DbAdapter.KEY_ID, id);
		startActivity(intent);
//		startActivityForResult(intent, 1);
    }

Obrigado.

30 Respostas

W

Por que você tá chamando startActivity duas vezes? Ou chama o startActivity, ou chama o startActivityForResult.

Você imprimiu os valores do id no método pra garantir que está sendo enviado?

Como está pegando estes valores na activity que os recebe?

F

Ta duplicado, colei errado. Mas como faria isso, não sei como fazer…

O correto seria:

// Clicar em item da lista e mostra nos campos da tela de cadastro
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
    	super.onListItemClick(l, v, position, id);
		Intent intent = new Intent(this, CarrosCliente.class);
		intent.putExtra(DbAdapter.KEY_ID, id);
		startActivityForResult(intent, 1);
    }

E coloquei esse código também:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	super.onActivityResult(requestCode, resultCode, data);
    	if(requestCode == 1 && resultCode == RESULT_OK)
    		carregarLista();
    }

Tenho a tela BuscaCliente e a tela CarrosCliente. Eu clico no item da lista, chama a tela CarrosCliente mas não mostra no campo nome o dado clicado.

W

Use a classe android.util.Log. Ela vai imprimir no LogCat (se você estiver usando eclipse). Um exemplo simples:

@Override
   protected void onListItemClick(ListView l, View v, int position, long id) {
      super.onListItemClick(l, v, position, id);
      Log.d("BuscaCliente", String.valueOf(id)); // fazendo log

      Intent intent = new Intent(this, CarrosCliente.class);
      intent.putExtra(DbAdapter.KEY_ID, id);
      startActivityForResult(intent, 1);
   }

Poste onde você está recebendo estes valores também (e debugue lá tb!).

F

Como testo isso, é só rodar normalmente?

W

Sim. Você tá usando eclipse com o plugin ADT? Os logs serão exibidos numa aba chamada LogCat. Se ela não estiver aparecendo, aperte Ctrl + 3 e digite LogCat.

E poste o código onde você recebe o id na classe CarrosCliente pra nós vermos também!

F

Ta pegando o id, rodei e apareceu no rodapé do eclipse.

W

Se está pegando corretamente, seu problema é na hora de jogar este id na tela. Posta o código pra vermos melhor. E lembre-se que você está passando apenas o id (e não o nome, como vc mencionou no início), talvez este seja o problema.

F

Na outra classe:

private long mId;

mId = getIntent().getLongExtra(DbAdapter.KEY_ID, 0);

if(mId > 0){
			mDb.open();
			Cursor cliente = mDb.getCliente(mId);
			if(cliente.moveToFirst()){
				nome.setText(cliente.getString(cliente.getColumnIndex(DbAdapter.KEY_NOME)));
				endereco.setText(cliente.getString(cliente.getColumnIndex(DbAdapter.KEY_ENDERECO)));
				telefone.setText(cliente.getString(cliente.getColumnIndex(DbAdapter.KEY_TELEFONE)));
				celular.setText(cliente.getString(cliente.getColumnIndex(DbAdapter.KEY_CELULAR)));
				cpf.setText(cliente.getString(cliente.getColumnIndex(DbAdapter.KEY_CPF)));
			}
			mDb.close();
		}
W

Nesta classe aí você imprimiu o mId também pra ver se chegou?

Se ele chegou corretamente, seu erro é na hora de passar este valor para a tela. Qual o código que você usa pra fazer isto?

F

Vou testar agora, um momento e ja posto.

F

Fiz assim na classe CarrosCliente:

public class CarrosCliente extends Activity{

private long mId;


mId = getIntent().getLongExtra(DbAdapter.KEY_ID, 0);
		
IdNome = (TextView) findViewById(R.id.IdNome);

mDb.open();
		
Cursor cliente = mDb.getCliente(mId);
		
  if(mId > 0){
    IdNome.setText(" "+cliente.getString(cliente.getColumnIndex("_id")));
  }  
		
} Aqui fecha a Activity

Agora nem chama mais a tela da erro ao clicar no item da lista na tela anterior.

W

Esse código que você colou está em qual método? Se não for muito grande, coloca a classe inteira.

F

Fiz assim na classe CarrosCliente, onde é pra aparecer os dados da tela anterior.

F

Classe BuscaClientes:

package br.com.oficinavittorazo;

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class BuscaClientes extends ListActivity{
	public ImageButton voltar;
	public DbAdapter db;
	private EditText Procurar;

	
	@Override
	protected void onCreate(Bundle icicle){ // Início do método onCreate
		super.onCreate(icicle);
		setContentView(R.layout.busca_cliente_layout);

		db = new DbAdapter(this);
		db.open();

		Cursor clientes = db.getTodosClientes();
        clientes.moveToFirst();

		Procurar = (EditText) findViewById(R.id.etProcurar);
		Procurar.requestFocus();
		
		
		carregarLista();
		
		Procurar.addTextChangedListener(new TextWatcher() {
			
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				 CarregarEncontrados();
				//Carrega o listview com os itens encontrados
                lv.setAdapter(new ArrayAdapter<String>(CadastrarCarros.this, android.R.layout.simple_list_item_1, agenda_Encontrados)); */
				carregarLista();
			}
			
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub

			}
		});
		
		voltar = (ImageButton) findViewById(R.id.bt_voltar);
		
		voltar.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				//  Evento ao clicar no botão Voltar
				setResult(RESULT_CANCELED);
				// Fecha a tela de Cadastro e Volta para a Principal
				finish();
			}
		});
	}
	
	
    // Clicar em item da lista e mostra nos campos da tela de cadastro
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
    	super.onListItemClick(l, v, position, id);
    	Log.d("BuscaCliente", String.valueOf(id)); // fazendo log
		Intent intent = new Intent(this, CarrosCliente.class);
		intent.putExtra(DbAdapter.KEY_ID, id);
		startActivityForResult(intent, 1);
    }

	private void carregarLista(){
		String nomeString = Procurar.getText().toString();
		db.open();
 //   	Cursor clientes = db.getTodosClientes();
		Cursor clientes = db.getClientePorNome(nomeString);
 
		clientes.moveToFirst();
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.two_line_list_item, clientes, new String[] {DbAdapter.KEY_NOME, DbAdapter.KEY_ID}, new int[] {android.R.id.text1, android.R.id.text2});
		setListAdapter(adapter);
		
        db.close();
		// Setar lista na mão
		//String[] items = new String[] {"Carro", "Trabalho", "Faculdade"};
		//ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, items);
    }
	
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	super.onActivityResult(requestCode, resultCode, data);
    	if(requestCode == 1 && resultCode == RESULT_OK)
    		carregarLista();
    } 
}

Classe CarrosCliente:

package br.com.oficinavittorazo;

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.ListView;
//import android.widget.ImageButton;
import android.widget.TextView;

public class CarrosCliente extends Activity{
	private long mId;
	private TextView IdNome;
//	private EditText nome;
//	private ImageButton salvar, pesquisar, limpar, voltar;

	
	private DbAdapter mDb;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.cadastro_carros_cliente_layout);
		
		mDb = new DbAdapter(this);
		
		mId = getIntent().getLongExtra(DbAdapter.KEY_ID, 0);
		
		IdNome = (TextView) findViewById(R.id.IdNome);
//		nome = (EditText) findViewById(R.id.editText_nome);
		
		mDb.open();
		
		Cursor cliente = mDb.getCliente(mId);
		
		if(mId > 0){
		  IdNome.setText(" "+cliente.getString(cliente.getColumnIndex("_id")));
//		  nome.setText(cliente.getString(cliente.getColumnIndex(DbAdapter.KEY_NOME)));
		}  
		
	}

}
W

Aparentemente este código esta correto. Para termos certeza, imprima o mId nestes dois lugares:

public class CarrosCliente extends Activity{
	private long mId;
	private TextView IdNome;
//	private EditText nome;
//	private ImageButton salvar, pesquisar, limpar, voltar;

	private DbAdapter mDb;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.cadastro_carros_cliente_layout);
		
		mDb = new DbAdapter(this);
		
		mId = getIntent().getLongExtra(DbAdapter.KEY_ID, 0);
                Log.d("CarrosCliente", "mId: " + mId); //aqui
		
		IdNome = (TextView) findViewById(R.id.IdNome);
//		nome = (EditText) findViewById(R.id.editText_nome);
		
		mDb.open();
		
		Cursor cliente = mDb.getCliente(mId);
		
		if(mId > 0){
		  IdNome.setText(" "+cliente.getString(cliente.getColumnIndex("_id")));
                  Log.d("CarrosCliente", "mId: " + mId); // e aqui
//		  nome.setText(cliente.getString(cliente.getColumnIndex(DbAdapter.KEY_NOME)));
		}  
		
	}

}

Você comentou que estava dando algum erro. Quando dá erro aparece a exceção lá no LogCat, dá uma olhada lá pra ver o que tá acontecendo.

F

Acho que o erro é esse: 08-15 01:21:03.032: E/AndroidRuntime(1343): java.lang.RuntimeException: Unable to start activity ComponentInfo{br.com.oficinavittorazo/br.com.oficinavittorazo.CarrosCliente}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1

O id ta pegando, mas ta dando erro quando vai abrir a tela da classe CarrosCliente.

W

Certo, veja que o problema é no cursor. Neste local:

IdNome.setText(" "+cliente.getString(cliente.getColumnIndex("_id")));

Provavelmente cliente.getColumnIndex("_id") está retornando -1. Você tem certeza que este campo ("_id") está no select? Cola o select que é chamado quando você faz mDb.getCliente pra nós vermos.

F

Tá assim:

public Cursor getCliente(long Id){
	return mDb.query(DATABASE_TABLE_CLIENTES, null, KEY_ID + "=" + Id, null, null, null, null);
}
W

No segundo parâmetro do método query você deveria estar passando um array com as colunas que quer trazer do banco. Eu vi lá no seu código inicial que vc tinha DbAdapter.KEY_NOME, DbAdapter.KEY_ENDERECO, etc. Neste parâmetro você deve passar um array com estes campos.

F

Como faz isso? Não entendi… Eu só quero o id e o nome.

W

Hum, passando null ele vai retornar todos os campos do banco, então não precisa alterar conforme eu falei no último post.

Lá na classe CarrosCliente, ao invés disto:

IdNome.setText(" "+cliente.getString(cliente.getColumnIndex("_id")));

Use isto:

IdNome.setText(" "+cliente.getString(cliente.getColumnIndex(DbAdapter.KEY_ID)));

Se isto não resolver, só sabendo quais são as colunas da sua tabela no banco de dados pra resolver.

F

Deu erro ao clicar no item da lista:

08-15 01:41:39.021: E/AndroidRuntime(1426): java.lang.RuntimeException: Unable to start activity ComponentInfo{br.com.oficinavittorazo/br.com.oficinavittorazo.CarrosCliente}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1

Dados da tabela:

private static final String DATABASE_TABLE_CLIENTES = "clientes";
	public static final String KEY_ID = "_id";
	public static final String KEY_NOME = "nome";
	public static final String KEY_ENDERECO = "endereco";
	public static final String KEY_TELEFONE = "telefone";
	public static final String KEY_CELULAR = "celular";
	public static final String KEY_CPF = "cpf";
	
	private static final String DATABASE_CREATE = "create table " + DATABASE_TABLE_CLIENTES + " ("
		+ KEY_ID + " integer primary key autoincrement, "
		+ KEY_NOME + " text, "
		+ KEY_ENDERECO + " text, "
		+ KEY_TELEFONE + " text, "
		+ KEY_CELULAR + " text, "
		+ KEY_CPF + " text);";
F

Não sei se ajuda, mas o IdNome tá declarado assim:

private TextView IdNome;
W

humm, mas vc removeu o moveToFirst do cursor… tente assim:

if(mId > 0 && cliente.moveToFirst()){
   IdNome.setText(" "+cliente.getString(cliente.getColumnIndex(DbAdapter.KEY_ID)));    
}
F

Legal, trouxe o id, agora to precisando do nome. Consegui com o nome, fiz a mesma coisa. Como deixar o EditText sem edição?

W

Ora, se para acessar o id você usou:

cliente.getString(cliente.getColumnIndex(DbAdapter.KEY_ID));

Para acessar o nome basta trocar a chave pelo nome:

cliente.getString(cliente.getColumnIndex(DbAdapter.KEY_NOME));

E aí você decide onde colocar este valor (se vai concatenar com o id ou criar outro TextView.

F

VALEU Wagner,

Funcionou perfeito aqui. O que estava fazendo de errado? Como posso deixar o EditText sem edição, modo leitura?

F

Wagner, se quiser mais uma tabela é só fazer o mesmo da Tabela Clientes?

private static final String DATABASE_TABLE_CLIENTES = "clientes";
	public static final String KEY_ID = "_id";
	public static final String KEY_NOME = "nome";
	public static final String KEY_ENDERECO = "endereco";
	public static final String KEY_TELEFONE = "telefone";
	public static final String KEY_CELULAR = "celular";
	public static final String KEY_CPF = "cpf";
	
	private static final String DATABASE_CREATE = "create table " + DATABASE_TABLE_CLIENTES + " ("
		+ KEY_ID + " integer primary key autoincrement, "
		+ KEY_NOME + " text, "
		+ KEY_ENDERECO + " text, "
		+ KEY_TELEFONE + " text, "
		+ KEY_CELULAR + " text, "
		+ KEY_CPF + " text);";

Para a tabela Carros faria o mesmo do código acima? E no caso do id do cliente, teria que ter na tabela Carros, ou seja os campos seriam esses:

IdCarro
IdCliente
Placa
Modelo

W

Cara, quanto ao campo ser não editável, eu não sei como tá isso nas versões atuais do Android, mas há um tempo atrás era uma droga, por que a propriedade editable não funcionava. Tem várias gambiarras pra fazer isso, eu usava essa:

<EditText ...
        android:clickable="false" 
        android:cursorVisible="false" 
        android:focusable="false" 
        android:focusableInTouchMode="false">
</EditText>

O procedimento para outras tabelas é semelhante. Recomendo que ao invés de ter apenas uma classe chamada DbAdapter, você tenha várias: ClienteDbAdapter, CarroDbAdapter, etc. Aí cada uma tem as suas informações.

F

Beleza, vou setar num TextView, ai não tem como editar. Seria igual o conteúdo somente mudando o nome da tabela? E onde cria o banco?

private static final String DATABASE_NAME = “oficina”;
private static final int DATABASE_VERSION = 1;

Igual pra todas as classes DbAdapter que criar?

Criado 14 de agosto de 2012
Ultima resposta 14 de ago. de 2012
Respostas 30
Participantes 2