Neste exemplo, vamos utilizar um ListView com a implementação de um BaseAdapter.
O código de layout xml deste exemplo é bem simples, vejamos:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/editText1" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPersonName" > <requestFocus /> </EditText> <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > </ListView> </LinearLayout>
(arquivo: activity_main.xml)
Como vamos utilizar um ListView Customizado (Veja mais sobre), vamos criar nosso próprio item na mão:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/textView1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1"/> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
(arquivo: listview_item.xml)
Agora que temos nosso layout, vamos implementar nosso adapter, ele vai ficar responsável pela filtragem dos itens. (Não vou explicar detalhamente sobre o adapter caso tenham duvidas vejam em ListView Customizado (Veja mais sobre))
public class ListViewAdapter extends BaseAdapter { //Itens de exibição / filtrados private List<ListViewObjetos> itens_exibicao; //Essa lista contem todos os itens. private List<ListViewObjetos> itens; //Utilizado no getView para carregar e construir um item. private LayoutInflater layoutInflater; public ListViewAdapter(Context context, List<ListViewObjetos> itens) { this.itens = itens; this.itens_exibicao = itens; layoutInflater = LayoutInflater.from(context); } @Override public int getCount() { return itens_exibicao.size(); } @Override public Object getItem(int arg0) { return itens_exibicao.get(arg0); } @Override public long getItemId(int arg0) { return itens_exibicao.get(arg0).getId(); } @Override public View getView(int arg0, View arg1, ViewGroup arg2) { ItemHelper itemHelper = new ItemHelper(); ListViewObjetos objeto = itens_exibicao.get(arg0); if (arg1 == null) { arg1 = layoutInflater.inflate(R.layout.listview_item, null); itemHelper.descricao = (TextView) arg1.findViewById(R.id.textView1); itemHelper.valor = (TextView) arg1.findViewById(R.id.textView2); arg1.setTag(itemHelper); } else { itemHelper = (ItemHelper) arg1.getTag(); } itemHelper.descricao.setText("-> " + objeto.getId() + " - " + objeto.getDescricao()); itemHelper.valor.setText(objeto.getValor()); return arg1; } private class ItemHelper { TextView descricao, valor; } /** Método responsável pelo filtro. Utilizaremos em um EditText * * @return */ public Filter getFilter() { Filter filter = new Filter() { @Override protected FilterResults performFiltering(CharSequence filtro) { FilterResults results = new FilterResults(); //se não foi realizado nenhum filtro insere todos os itens. if (filtro == null || filtro.length() == 0) { results.count = itens.size(); results.values = itens; } else { //cria um array para armazenar os objetos filtrados. List<ListViewObjetos> itens_filtrados = new ArrayList<ListViewObjetos>(); //percorre toda lista verificando se contem a palavra do filtro na descricao do objeto. for (int i = 0; i < itens.size(); i++) { ListViewObjetos data = itens.get(i); filtro = filtro.toString().toLowerCase(); String condicao = data.getDescricao().toLowerCase(); if (condicao.contains(filtro)) { //se conter adiciona na lista de itens filtrados. itens_filtrados.add(data); } } // Define o resultado do filtro na variavel FilterResults results.count = itens_filtrados.size(); results.values = itens_filtrados; } return results; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, Filter.FilterResults results) { itens_exibicao = (List<ListViewObjetos>) results.values; // Valores filtrados. notifyDataSetChanged(); // Notifica a lista de alteração } }; return filter; } }
Como vimos acima, o método responsável pelo filtro está bem comentado, não é complicado de entender. Quando utilizado ele vai pegar a palavra passada pelo filtro comparar com o item que queremos filtrar, criar uma lista de exibição e chamar o método do adapter que notifica mudanças na lista. Não vou implementar o “ListViewObjetos” pois é um objeto de dados simples, você pode colocar o que quiser lá, assim como o xml de item.
Abaixo vamos ver como criar o adapter e utilizar o getFilter();
public class MainActivity extends Activity { private ListViewAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Cria uma lista de 100 objetos para usar no exemplo. ArrayList<ListViewObjetos> itens = new ArrayList<ListViewObjetos>(); for (int i = 0; i < 100; i++) { itens.add(new ListViewObjetos(i, "descricao+" + i, "R$" + i + ",00")); } // constroi o adapter passando os itens. adapter = new ListViewAdapter(this, itens); ListView lista = (ListView) findViewById(R.id.listView1); lista.setAdapter(adapter); //Aqui é aonde adicionamos nosso filtro no edittext. EditText editText = (EditText) findViewById(R.id.editText1); editText.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { //quando o texto é alterado chamamos o filtro. adapter.getFilter().filter(s.toString()); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } }); } }
Acima adicionamos um listener no editText que vai nos dizer quando o texto é alterado, quando ele for alterado o método onTextChanged() é chamado, nele vamos chamar o getFilter() do adapter e utilizar o filter() passando a string de filtro. Seu texto será tratado e sua lista FILTRADA!.
Segue o Link do projeto: (DROPBOX)
(Lembre-se de nos ajudar clicando nos anúncios em nossa página.)
Esse método funciona para lista preenchida com dados vindos do SQLite? Precisa adaptar algo?
Funciona normalmente, você tem que tratar seus dados e preencher seus objetos de acordo com o que você quer. Siga o exemplo que não tem erro. Qualquer duvida nos informe.
ótimo código e de fácil intendimento muito bom mesmo valeu
Muito bom!
Sou iniciante e seu post ajudou muito, mais estou com uma duvida, como trato um evento de clique nessa lista?
Por exemplo se fosse uma lista de cliente onde ao clicar abre o cadastro desse cliente.
Se puder ajudar agradeço.
Exemplo:
list.setOnItemClickListener( new OnItemClickListener() {
public void onItemClick(AdapterView> arg0, View arg1, int arg2, long arg3) {
Intent i = new Intent(ClassName.this,CourtDetailActivity.class);
startActivity(i);
});
}
Consegui:
lista.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int position,long id) {
}
});
Caso eu queira fazer uma busca que seja feita pelo searchview da actionbar procurando os dados vindos de uma banco de dados. Com esse seu codigo pode fazer isso ?
Olá! Guilherme. Tem como mandar o link do projeto pro meu e-mail. Pois aquele esta fora do ar.
Desde já obrigado!
chavesmusic@hotmail.com
vou enviar
Olá, estou usando seu exemplo de fitro, e estou enfrentando um problema, quando eu apago o filtro ele não volta a minha lista, ela fica vazia.
Verifique esse exemplo:
https://github.com/helpdeveloper/ExemplosAndroid/tree/master/exListViewFilter/src/com/example/exlistviewfilter
Caso não funcione me envie seu código para eu analisar! contato@helpdev.com.br
Bom dia Guilherme, eu tentei aqui, mas deu outro erro, te mandei para o email que passou acima.