quinta-feira, 29 de março de 2012

Android - ListView Parte 8

Olá, Pessoal

Estou aqui mais uma vez para apresentar mais um tipo de (ListView) Lista de Itens, agora irei mostrar como criar um separador em nossas listas.

Neste projeto terá a opção de incluir dinamicamente mais Itens ou Separadores.

Abaixo seguem todos os fontes utilizados nesse projeto, como já de costume os fontes estão todos com diversos comentários para facilitar no entendimento.

Abaixo temos uma imagem que mostra os arquivos utilizados no projeto:


Arquivo EstadoPojo.java
package br.com.empresa;

public class EstadoPojo {
    private long status;
    private String estado;
    private String capital;
    
    public EstadoPojo()
    {
    }
 
    public EstadoPojo(long pStatus, String pEstado, String pCapital)
    {
        this.status = pStatus;
        this.estado = pEstado;
        this.capital = pCapital;
    }

    public void setStatus(long status) {
        this.status = status;
    }
    public long getStatus() {
        return status;
    }
    public void setEstado(String nome) {
        this.estado = nome;
    }
    public String getEstado() {
        return estado;
    }
    public void setCapital(String endereco) {
        this.capital = endereco;
    }
    public String getCapital() {
        return capital;
    }
}

Arquivo main.java
package br.com.ListSep;

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

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

public class main extends Activity {
    EstadosAdapter adapter;
    private List<Object> lsEstados = new ArrayList<Object>();

    /** Chamado quando a activity é chamada pela primeira vez */ 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        try{
            setContentView(R.layout.main);
            ListView list = (ListView) findViewById(R.id.lvEstados2);
            
            lsEstados.add("Norte");
            lsEstados.add(new EstadoPojo(1, "Amazonas", "Manaus")); 
            lsEstados.add(new EstadoPojo(1, "Roraima", "Boa Vista")); 
            lsEstados.add(new EstadoPojo(1, "Acre", "Rio Branco")); 
            lsEstados.add("Sudeste");
            lsEstados.add(new EstadoPojo(1, "São Paulo", "São Paulo")); 
            lsEstados.add(new EstadoPojo(1, "Minas Gerais", "Belo Horizonte"));
            lsEstados.add(new EstadoPojo(1, "Rio de Janeiro", "Rio de Janeiro"));
            lsEstados.add(new EstadoPojo(1, "Espírito Santo", "Vitória"));
            
            adapter = new EstadosAdapter(this, lsEstados);
            list.setAdapter(adapter);
            
            //aqui apenas um exemplo de que podemos inserir mais itens em nossa
            //lista, mesmo depois que já passamos o adapter para o obeto list
            lsEstados.add("Sul");
            lsEstados.add(new EstadoPojo(1, "Paraná", "Curitiba")); 
            adapter.notifyDataSetChanged();
        }catch (Exception e) {
            showToast("Erro: " + e.getMessage());
        }        
    }
    
    public void btnEstado_click(View v)
    {
        EditText etEstado = (EditText) findViewById(R.id.etEstado);
        EditText etCapital = (EditText) findViewById(R.id.etCapital);
        
        lsEstados.add(new EstadoPojo(1, etEstado.getText().toString(), etCapital.getText().toString()));
        
        /*
        Caso seja necessário incluir o item em uma posição determinada
        basta efetuar como o exemplo abaixo, apenas mudando o valor "1"
        para o valor que você desejar
        */
        //lsEstados.add(1, new EstadoPojo(1, etEstado.getText().toString(), etCapital.getText().toString()));
        
        adapter.notifyDataSetChanged();
    }
    
    public void btnCapital_click(View v)
    {
        //Cria o AlertDialog
        AlertDialog.Builder alert = new AlertDialog.Builder(this);

        alert.setTitle("Região");
        //alert.setMessage("Message");

        //Cria uma caixa de texto para ser inserida dentro do AlertDialog 
        final EditText input = new EditText(this);
        alert.setView(input);

        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                  lsEstados.add(String.valueOf(input.getText()));
                  adapter.notifyDataSetChanged();
            }
        });

        alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                //Cancelado.
            }
        });

        alert.show();    
    }
    
    private void showToast(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //Garantir que quando finalizar o programa seja
        //limpado todos os itens da coleção
        lsEstados = new ArrayList<Object>();
    }  
}

Arquivo EstadosAdapter.java
package br.com.ListSep;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class EstadosAdapter extends BaseAdapter {
    private List<Object> lsEstados;
    Context context;

    int ITEM_VIEW_ESTADO = 0;
    final int ITEM_VIEW_SEPARADOR = 1;
    final int ITEM_VIEW_COUNT = 2;    
    
    //Classe utilizada para instanciar os objetos do XML
    private LayoutInflater inflater;
    
    public EstadosAdapter(Context context, List<Object> pObjects) {
        this.lsEstados = pObjects;
        this.context = context;
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public void addItem(final EstadoPojo item) {
        this.lsEstados.add(item);
        //Atualizar a lista caso seja adicionado algum item
        notifyDataSetChanged();
    }    
    
    @Override
    public int getCount() {
        return lsEstados.size();
    }

    @Override
    public Object getItem(int position) {
        return lsEstados.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getViewTypeCount() {
        return ITEM_VIEW_COUNT;
    }

    //Rotina responsável por identificar se o item da Lista
    //é um Separador ou um item "normal"
    @Override
    public int getItemViewType(int position) {
        return (lsEstados.get(position) instanceof String) ? ITEM_VIEW_SEPARADOR
                : ITEM_VIEW_ESTADO;
    }

    @Override
    public boolean isEnabled(int position) {
        //Caso o item clicado seja o Separador, nesse caso
        //não retornamos nada 
        return getItemViewType(position) != ITEM_VIEW_SEPARADOR;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        try{
            final int type = getItemViewType(position);

            if (convertView == null) {
                convertView = inflater.inflate(type == ITEM_VIEW_SEPARADOR ? 
                        R.layout.separator : R.layout.list_row, null);
            }
    
            if (type == ITEM_VIEW_SEPARADOR) {
                //Informa o texto que será exibido no Separador
                ((TextView) convertView).setText((String) getItem(position));
            } else {
                final EstadoPojo estado = (EstadoPojo) getItem(position);
                
                //Informa os valores que serão exibidos no Estado e Capital
                TextView tvEstado = (TextView) convertView.findViewById(R.id.txtEstado);
                tvEstado.setText(estado.getEstado());

                TextView tvCapital = (TextView) convertView.findViewById(R.id.txtCapital);
                tvCapital.setText(estado.getCapital());
            }
        }catch (Exception e) {
            trace("Erro : " + e.getMessage());
        }
        
        return convertView;
    }
    
    public void toast (String msg)
    {
        Toast.makeText (context, msg, Toast.LENGTH_SHORT).show ();
    } 
    
    private void trace (String msg) 
    {
        toast (msg);
    } 
}

Arquivo list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent">
    <TextView 
        android:text="Estado" 
        android:id="@+id/txtEstado" 
        android:gravity="center_vertical"
        android:layout_width="wrap_content" 
        android:layout_height="30sp">
    </TextView>
    <TextView 
        android:text="Capital" 
        android:id="@+id/txtCapital" 
        android:gravity="center_vertical"
        android:layout_width="wrap_content" 
        android:layout_height="30sp">
    </TextView>
</LinearLayout>

Arquivo main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" 
    android:orientation="vertical">
    
    <EditText 
        android:inputType="text"
        android:id="@+id/etEstado" 
        android:layout_height="wrap_content"
        android:layout_width="fill_parent" 
        android:text="Estado">
    </EditText>
    
    <EditText 
        android:inputType="text"
        android:id="@+id/etCapital" 
        android:layout_height="wrap_content"
        android:layout_width="fill_parent" 
        android:text="Capital">
    </EditText>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content" 
          android:orientation="horizontal">
        
        <Button 
            android:id="@+id/btnEstado"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content" 
            android:onClick="btnEstado_click" 
            android:text="Adicionar Estado" 
            android:layout_weight="0.5">
        </Button>

        <Button 
            android:id="@+id/btnCapital"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content" 
            android:onClick="btnCapital_click" 
            android:text="Adicionar Região" 
            android:layout_weight="0.5">
        </Button>
    
    </LinearLayout>
    
    <ListView
        android:id="@+id/lvEstados2" 
        android:layout_height="wrap_content" 
        android:layout_width="fill_parent">
    </ListView>
    
</LinearLayout>

Arquivo separator.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_header_title"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingTop="2dip"
    android:paddingBottom="2dip"
    android:paddingLeft="5dip"
    style="@style/listSeparatorTextViewStyle"
    android:text="Separador"
    />

Arquivo colors.xml
<?xml version="1.0" encoding="utf-8"?> 
<resources>     
    <color name="white">#fff</color>     
    <color name="black">#000</color>     
    <color name="red">#c6360a</color>     
    <color name="green">#688f2b</color>     
    <color name="orange">#f48905</color>     
    <color name="dark_blue">#003366</color>         
    <color name="grey">#888888</color> 
</resources> 

Arquivo styles.xml
<?xml version="1.0" encoding="UTF-8"?>     
<resources>     
    <style 
        name="listSeparatorTextViewStyle" parent="@android:attr/listSeparatorTextViewStyle">         
        <item name="android:layout_height">wrap_content</item>         
        <item name="android:layout_width">fill_parent</item>         
        <item name="android:textSize">15dip</item>         
        <item name="android:paddingTop">2dip</item>         
        <item name="android:paddingBottom">3dip</item>         
        <item name="android:paddingLeft">5dip</item>         
        <item name="android:paddingRight">10dip</item>         
        <item name="android:textAppearance">@android:style/TextAppearance.Small</item>         
        <item name="android:shadowColor">#111111</item>         
        <item name="android:shadowRadius">1</item>         
        <item name="android:shadowDy">1</item>         
        <item name="android:textStyle">bold</item>         
        <item name="android:textColor">@android:color/white</item>         
        <item name="android:background">@color/dark_blue</item>     
    </style>     
</resources> 


Funcionamento do programa:
1º - Clicando no botão "Adicionar Região" será exibido um AlertDialog solicitando um texto que no nosso exemplo seria uma região do Brasil, confirmando a operação o sistema irá adicionar no final da lista um Separador com o texto informando.
2º - Clicando no botão "Adicionar Estado" o sistema irá inserir um item no final da lista com os valores informados nas duas caixas de texto.

Como resultado temos a figura abaixo:
ListView






Desenvolvi o jogo Circus Puzzle Free ele é um quebra-cabeça e está publicado no Android Market, agradeço a todos que baixarem, jogarem e comentarem.



Desenv com qualidade!

4 comentários:

Jeferson disse...

Opa,
cara preciso de uma ajuda, segui o teu tutorial e dá tudo certo, só q na hora que eu rodo a aplicação dá esse erro "Unfortunately, ListSep has stopped."
tem que alterar alguma coisa no manifest?

desde já muito obrigado

Marcio de Souza disse...

Jeferson,

Só com essa mensagem não consigo saber oque aconteceu no seu fonte, dá uma conferida com o primeiro print e verifica seu os arquivos de seu projeto estão iguais ao print, depois é preciso saber qual foi o nome package que você utilizou e se está igual ao exemplo do post.

A princípio essas são as dicas que posso deixar.

Caso não consiga corrigir, manda um email que eu te mando o fonte.

Obrigado pela visita.

Márcio disse...

Cara, mto valioso esse seu tutorial.

Estou precisando criar um listView com produtos para venda.
Então vai ter o ícone do produto, o código dele, o nome e o preço.

Queria saber se é possível ao selecionar o produto ele abrir algum tipo de Pop-Up para colocar a quantidade de venda desse produto, é possível isso??
Sendo que essa lista de produtos eu pego do meu banco de dados.

The brothers disse...

Cara muito bom o material, mas estou batendo um pouco a cabeçam preciso fazer uma multipla seleção e não estou conseguindo, consegue passar um exemplo nesse formato