Criando uma ListActivity

Hoje aprenderemos a usar uma ListActivity para mostrar ao usuario uma lista com as anotações que ele inseriu em nossa aplicação QuickNotes.

ListActivity? O que é isso?

A ListActivity é uma classe filha da Activity cujo objetivo é mostrar ao usuário uma Lista (uma ListView). Em suma, é uma Activity com alguns métodos para gerenciamento de listas, criada com o intuito de facilitar a criação de telas com essa configuração, muito comuns nas aplicações android.

O primeiro passo para criar uma Activity desse tipo é assegurar que o layout XML a ser usado por ela possui um elemento ListView (afinal, estamos criando uma ListActivity!). Além disso, é preciso que seu id seja “@id/android:list”.

Adequando o layout da nossa aplicação, temos:




    
	    
    	
    	
	
    
    

Depois disso, o próximo é fazer a nossa classe MainActivity ser uma classe filha da ListActivity:

public class MainActivity extends ListActivity

E então, inicializar a ListView no método onCreate. Mas para isso precisaremos de um Adapter.

Adapters

Adapters são classes responsáveis por fazer o que é chamado de “bind“: Receber os dados de um Cursor (ou de alguma outra fonte de dados) e colocá-los nos seus respectivos lugares no layout da Activity.

Para Activity’s complexas, tipicamente são criadas subclasses da classe CursorAdapter (Adapter dedicado a tratar cursores). No nosso caso, em que temos um layout bastante simples, é suficiente o uso do SimpleCursorAdapter.

No código abaixo eu mostro como usar este adapter, com uma explicação sobre seus parâmetros:

        ListAdapter adapter = new SimpleCursorAdapter(
        		              // O primeiro parametro eh o context.
        		              this,
        		              // O segundo, o layout de cada item.
        		              R.layout.list_item,
        		              // O terceiro parametro eh o cursor que contem os dados
        		              // a serem mostrados
        		              mCursor,
        		              // o quarto parametro eh um array com as colunas do
        		              // cursor que serao mostradas
        		              new String[] {QuickNotesProvider.Notes.TEXT},
        		              // o quinto parametro eh um array (com o mesmo
        		              // tamanho do anterior) com os elementos que
        		              // receberao os dados.
        		              new int[] {R.id.text});

        setListAdapter(adapter);

Um dos parâmetros recebidos pelo contrutor da SimpleCursorAdapter é o layout dos itens da lista, que definimos da seguinte forma:





     

E por fim, a nossa Activity principal fica assim:


package br.com.felipesilveira.quicknotes;

import android.app.ListActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;

public class MainActivity extends ListActivity {

	private static final String TAG = "QuickNotesMainActivity";
	private Cursor mCursor;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.d(TAG, "Criando a MainActivity");

        setContentView(R.layout.main);

        Intent i = new Intent(this, WelcomeActivity.class);
        startActivity(i);

        Button insertButton = (Button)findViewById(R.id.insert_button);
        insertButton.setOnClickListener(mInsertListener);

        // adicionando um 'Hint' ao Editbox.
        EditText editBox = (EditText)findViewById(R.id.edit_box);
        editBox.setHint("Nova nota...");

        mCursor = this.getContentResolver().
                  query(QuickNotesProvider.Notes.CONTENT_URI, null, null, null, null);

        ListAdapter adapter = new SimpleCursorAdapter(
        		              // O primeiro parametro eh o context.
        		              this,
        		              // O segundo, o layout de cada item.
        		              R.layout.list_item,
        		              // O terceiro parametro eh o cursor que contem os dados
        		              // a serem mostrados
        		              mCursor,
        		              // o quarto parametro eh um array com as colunas do
        		              // cursor que serao mostradas
        		              new String[] {QuickNotesProvider.Notes.TEXT},
        		              // o quinto parametro eh um array (com o mesmo
        		              // tamanho do anterior) com os elementos que
        		              // receberao os dados.
        		              new int[] {R.id.text});

        setListAdapter(adapter);
     }

     /*
      *  Definindo um OnClickListener para o botão "Inserir"
      */
     private OnClickListener mInsertListener = new OnClickListener() {
          public void onClick(View v) {
        	  EditText editBox = (EditText)findViewById(R.id.edit_box);
              addNote(editBox.getText().toString());
              editBox.setText("");
          }
     };

     /*
      * Método responsável por inserir um registro no content provider
      */
	 protected void addNote(String text) {
		 ContentValues values = new ContentValues();
		 values.put(QuickNotesProvider.Notes.TEXT, text);  

		 getContentResolver().insert(
		      QuickNotesProvider.Notes.CONTENT_URI, values);
	 }
}

Executando a Activity, temos a seguinte tela, com a lista das notas que o usuário digitou!

Exemplo ListActivity

DICA: Tenha muito cuidado ao projetar uma lista. Lembre-se que um usuário pode inserir mil, dez mil registros! O qeu aconteceria nessa situação? A performance nesses casos é um fator a ser muito trabalhado e testado. Mas isso fica para um próximo artigo. Até lá!

Desenvolvendo para Android


Posts Relacionados

  1. Criando uma Activity secundária
  2. Criando um projeto Android (Helloworld!)
  3. Como usar banco de dados em uma aplicação android
  4. Acessando um Content Provider

30 respostas to “Criando uma ListActivity”

  1. Hugo Sousa disse:

    Olá Felipe, parabéns pelos Posts, são de grande ajuda e esclarecimentos.
    Gostaria de pedir os arquivos desta app para tirar algumas dúvidas, poderia ser?
    Eu não entendi a parte do layout dos itens da lista, se vc se refere a um arquivo separado ou apenas inclui dentro da listview do layout principal, no caso tudo ser no layout principal a mainactivity reclama no paramentro R.layout.list_item,.
    Bom, se puder ajudar neste sentido…

    Novamente parabéns pelo blog

  2. Oi Hugo!
    Ótima pergunta, realmente não ficou muito claro.

    O trecho de XML que eu citei como o layout dos itens do menu deve ser colocado em um arquivo separado, chamado list_item.xml (pois foi esse o nome que passamos para o adapter.

    E vou colocar para download o código sim!

    Um abraço!

  3. Hugo Sousa disse:

    Beleza Felipe, estou no aguardo.valeu!

  4. Italo disse:

    Oi Felipe, muito bons seus posts! parabéns!!!
    Só me tira uma dúvida:
    Na classe MainActivity, o trecho …QuickNotesProvider.Notes.TEXT…, acessa uma classe “Notes” e uma constante “TEXT”, ok? mas onde estão definidos esses elementos?

    Valeu!

  5. Oi Italo,
    A constante que você citou está definida na classe QuickNotesProvider, que foi criada nesse artigo: Como Usar um banco de dados em uma aplicação android

    Um abraço!

  6. Italo disse:

    Beleza cara!
    Rodou!

    Obrigado pela agilidade em responder os posts!

    Abraço!

  7. Charles disse:

    Felipe, se possível poste os arquivos do projeto, pois no exemplo que criei está dando erro no trcho “Intent i = new Intent(this, WelcomeActivity.class); ” que corresponde a linha 30.
    Att,

  8. Nanda disse:

    Oi Felipe, tem como postar os arquivos? Nao ficou muito claro alguns pontos e ta dando alguns erros…
    obrigada

  9. Pessoal, vou postar o projeto completo (com todos os arquivos fontes) hoje a noite no blog.

    Um abraço!

  10. Hugo Sousa disse:

    5:30 da matina, acordei para beber água e fui ver se vc tinha colocado para download, ahh cara não durmo mesmo agora rsrssr, Valeu Felipe!!!

  11. Ved disse:

    Excelente! Li todos os artigos da série e agora vou implementa-los! Muito obrigado.

  12. Erick disse:

    Muito bacana, a série estava muito boa! Parou de publicar?

  13. Não parei não Erick! estou preparando alguns novos posts.
    obrigado!

  14. Rita disse:

    Olá, Felipe!
    Parabéns pela iniciativa!
    Fiquei particularmente curiosa em relação à parte final, i.e., quando por motivos de performance não se deseja carregar a lista inteira mas apenas partes dela.
    Sempre pensa em dar continuidade a este artigo?
    Cumprimentos,
    Rita

  15. Lindemberg disse:

    Felipe, muito bom os posts, mas eu tenho uma dúvida, eu estou criando uma aplicação pra android que precisa armazenar dois valores. Por exemplo, Nome e Telefone, no seu caso ele só armazena uma String, como eu faria pra armazenar duas ou mais string. Obrigado.

  16. Oi Lindemberg,

    A melhor forma para fazer isso é criar um banco de dados com 2 campos, ao invés de apenas um.

    Boa sorte!

  17. Lindemberg disse:

    Felipe, como eu faço para criar um banco de dados com 2 campos? Onde eu modifico o código? Obrigado!

  18. Sérgio Ferraz disse:

    Sem Comentários…

    Parabéns mesmo Felipe, você vem se tornando referência quando o assunto é desenvolvimento para Android.

    Excelente seu blog, já está nos meus Favoritos.

    Abraços !!

  19. Magno Junior disse:

    Olá,
    primeiro parabéns pelo ótimo blog (foram as melhores dicas que já encontrei sobre android em sites do Brasil – Faz pouco tempo que comecei e ainda nem fiz minha primeira app).

    segundo, queria tirar uma dúvida sobre o código contido na linha 30 e 31 da classe MainActivite:
    Intent i = new Intent(this, WelcomeActivity.class);
    startActivity(i);

    Qual o propósito dessa chamada? Meu onCreate está iniciando uma nova activite que é igual a ela mesma? Isso é mesmo necessário? Não geraria um “loop infinito” com cada nova activite criada gerando ela mesma?
    Poderia detalhar um pouco mais sobre a necessidade desse trecho de código?

  20. Magno Junior disse:

    Hum…
    pensando bem, startActivite não deve criar outra activite, mas chamar o onRestart(?)
    Mas ainda continuo sem entender a necessidade de chamar esse método.

  21. Dario disse:

    Vlw, Felipe…
    ainda n~~ao tive a oportunidade de ter contato com
    JAVA para android… Mas apenas lendo seus tutoriais estou me animando a experimentar! o/
    Vlw!

  22. Dennys disse:

    Olá Filipe Silveira, muito bom o seu tutorial.

    Estou com um probleminha na implementação da ListActivity, pois não vejo a implementação da mesma bem como o método setListAdapter. Agradeço se puder postar esse código…
    Vlw!!!

  23. Oi Dennys,

    A classe ListActivity é nativa de android.

  24. Dennys disse:

    Vlw Felipe, Não tinha percebido.

  25. Ronaldo Ottoni disse:

    Olá Felipe, companheiro você está de parabéns pela material toda…
    Estou com um probleminha aqui…na parte final, quando mudamos a extends da MainActivity de “extends Activity” para “extends ListActivity”, a aplicação não abre no emulador :( ele apresenta uma mensagem de terminou inesperadamente, tente novamente e fecha.

    Por favor, me dê uma luz grande mestre..

    Forte abraço

  26. Oi Ronaldo,

    Você poderia colocar qual é a mensagem que aparece no log? lá deve aparecer alguma exception, e ela vai ajudar a achar o problema.

  27. Derzu disse:

    Uma pequena correção, na descrição do list_item.xml substituir:

    linearlayout -> LinearLayout
    textview -> TextView
    textsize -> textSize
    textstyle -> textStyle
    textcolor -> textColor

  28. Derzu disse:

    Oi Felipe, só uma dica sobre um problema que eu tive, alguém pode passar pelo mesmo. Tava tudo rodando, sem quebrar, mas a lista dos nomes não aparecia. Percebi o seguinte:

    No tópico Trabalhando com layouts XML em Android (II) (http://www.felipesilveira.com.br/2010/04/trabalhando-com-layouts-xml-em-android-ii/), o segundo LinearLayout, tem o parâmetro android:layout_height=”fill_parent”.

    Já o main.xml descrito neste post, tem o segundo LinearLayout com o parâmetro android:layout_height=”wrap_content”.

    Usando o fill_parent não aparece a lista, utilizando o wrap_content funciona blz.

    Abraço.

Deixe um comentário