Applicare un filtro ad una ListView Android

Android 2.2 Froyo
Android 2.2 Froyo

In questo tutorial vedremo come applicare un filtro ad un oggetto ListView Android. Una ListView è una particolare tipologia di vista scorrevole che permette di visualizzare un elenco verticale di record: questi sono gestiti in modo automatico nella lista utilizzando i ListAdapter (pubblicheremo a breve alcuni tutorial Android tra cui ci troverete quello che descrive la procedura passo-passo per popolare una ListView utilizzando i ListAdapter).

Prerequisiti

Per testare il codice che permette di filtrare la ListView abbiamo bisogno chiaramente di un progetto Android con almeno un layout in cui è stata inserito un oggetto ListView. Per brevità non vedremo tutti i passaggi per la creazione del progetto e del layout: perciò supponiamo di avere a disposizione una ListView popolata con tutti i contatti della rubrica del nostro smartphone e una EditText per l’inserimento del testo sul quale effettuare la ricerca e il filtraggio dei dati.

Implementazione

[code]
private ListView contactList;

Cursor cursor = getContacts();
String[] fields = new String[] { ContactsContract.Data.DISPLAY_NAME };
private SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.contact_entry, cursor, fields, new int[] { R.id.contactEntryText });

contactList.setAdapter(adapter);

EditText editSearchText = (EditText) findViewById(R.id.search_string);
[/code]

La prima cosa che facciamo è creare il riferimento all’oggetto ListView (riga 1) che come indicato nei prerequisiti abbiamo precedentemente inserito nel layout: subito dopo (riga 3) salviamo il cursore che recupera tutti i contatti della rubrica del nostro smartphone (supponiamo di aver precedentemente scritto un metodo getContacts() che effettua una query per recuperare tutti i contatti).

A questo punto impostiamo l’adpter che popolerà la nostra ListView (riga 5) e lo assegniamo a quest’ultima (riga 7). Questo blocco di codice termina con il recupero sempre dal layout dell’EditText in cui inseriamo il testo su cui filtrare la ListView (riga 9). Passiamo ad occuparci dell’EditText.

[code]
editSearchText.addTextChangedListener(new TextWatcher() {

@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {

NomeClasse.this.filterList(editSearchText.getText());

}

@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

}
});
[/code]

Aggiungiamo all’EditText un listener che viene attivato ogni volta che cambia il testo inserito (riga 1). Il listener richiede che siano implementati 3 metodi che ne definiscono il comportamento (cosa fare quando il testo cambia, prima che il testo cambi, dopo che il testo è cambiato): noi ci occupiamo solo del primo caso, ovvero cosa fare quanto il testo cambia. Pertanto all’interno del metodo onTextChanged() inseriamo la chiamata alla funzione filterList() passandogli come parametro il testo inserito (riga 7). Passiamo a vedere la funzione di filtraggio.

[code]
private void filterList(CharSequence constraint) {

adapter.setFilterQueryProvider(new FilterQueryProvider() {

public Cursor runQuery(CharSequence constraint) {

Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] { ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME };
String selection = ContactsContract.Contacts.DISPLAY_NAME + " LIKE ‘"
+ constraint + "%’";
String[] selectionArgs = null;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC";

return managedQuery(uri, projection, selection, selectionArgs,
sortOrder);
}

});
final Cursor oldCursor = adapter.getCursor();
adapter.getFilter().filter(constraint, new FilterListener() {

public void onFilterComplete(int count) {
stopManagingCursor(oldCursor);
final Cursor newCursor = adapter.getCursor();
startManagingCursor(newCursor);
if (oldCursor != null && !oldCursor.isClosed()) {
oldCursor.close();
}
}
});

}
[/code]

La funzione filterList() è il cuore di tutto il meccanismo, e nel nostro esempio è definita all’interno della stessa classe in cui è salvato il codice precedente (nell’esempio la classe che contiente tutto il codice si chiama NomeClasse – w l’originalità).

Tutto quello che dobbiamo fare è di richiamare due metodi dell’adapter,  setFilterQueryProvider()getFilter().filter(). Il primo metodo imposta la query che deve essere applicata per filtrare i dati della ListView: nel nostro caso la stringa di ricerca inserita nell’EditText verrà utilizzata per filtrare i nome dei contatti che saranno a loro volta salvati in un nuovo cursor. Il secondo metodo invece permette di compiere una sorta di swtich tra il vecchio cursor della ListView e il nuovo, in modo da aggiornare i dati visualizzati.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

*