2010-12-31 11 views
6

Ho una lista di paesi in un database. Ho creato un'attività di campagna selezionata che consiste in una casella di modifica per il filtraggio e un elenco che mostra il nome della bandiera e del paese.Cercando di filtrare un ListView con runQueryOnBackgroundThread ma non accade nulla - cosa mi manca?

All'avvio dell'attività, l'elenco mostra l'intero elenco di Paesi in ordine alfabetico - funziona correttamente. Quando il cliente inizia a digitare nella casella di ricerca, desidero filtrare l'elenco in base alla digitazione. La mia query di database funzionava in precedenza in un AutoCompleteView (voglio solo passare a una casella di testo e un elenco separati), quindi so che la mia query completa e la mia query sui vincoli funzionano. Quello che ho fatto è stato aggiungere un TextWatcher alla vista EditText e ogni volta che il testo è cambiato, invoco SimpleCursorAdapter della lista runQueryOnBackgroundThread con il testo delle caselle di testo come vincolo. Il problema è che la lista non viene mai aggiornata. Ho impostato i breakpoint nel debugger e TextWatcher effettua la chiamata per eseguireQueryOnBackgroundThread e il mio FilterQueryProvider viene chiamato con il vincolo atteso. La query del database va bene e il cursore viene restituito.

L'adattatore cursore ha un set di filtri erogatori query (e un legante visualizzazione per visualizzare la bandiera):

SimpleCursorAdapter adapter = new SimpleCursorAdapter (this, 
      R.layout.country_list_row, countryCursor, from, to); 
    adapter.setFilterQueryProvider (new CountryFilterProvider()); 
    adapter.setViewBinder (new FlagViewBinder()); 

Il FitlerQueryProvider:

private final class CountryFilterProvider implements FilterQueryProvider { 

    @Override 
    public Cursor runQuery (CharSequence constraint) { 
     Cursor countryCursor = myDbHelper.getCountryList (constraint); 
     startManagingCursor (countryCursor); 
     return countryCursor; 
    } 
} 

E l'EditText ha un TextWatcher:

myCountrySearchText = (EditText)findViewById (R.id.entry); 
    myCountrySearchText.setHint (R.string.country_hint); 
    myCountrySearchText.addTextChangedListener (new TextWatcher() { 
     @Override 
     public void afterTextChanged (Editable s) { 
      SimpleCursorAdapter filterAdapter = (SimpleCursorAdapter)myCountryList.getAdapter(); 
      filterAdapter.runQueryOnBackgroundThread (s.toString()); 
     } 


     @Override 
     public void onTextChanged (CharSequence s, int start, int before, int count) { 
      // no work to do 
     } 


     @Override 
     public void beforeTextChanged (CharSequence s, int start, int count, int after) { 
      // no work to do 
     } 
    }); 

La query per il database è simile a questa:

public Cursor getCountryList (CharSequence constraint) { 
    if (constraint == null || constraint.length() == 0) { 
     // Return the full list of countries 
     return myDataBase.query (DATABASE_COUNTRY_TABLE, 
       new String[] { KEY_ROWID, KEY_COUNTRYNAME, KEY_COUNTRYCODE }, null, null, null, 
       null, KEY_COUNTRYNAME); 
    } else { 
     // Return a list of countries who's name contains the passed in constraint 
     return myDataBase.query (DATABASE_COUNTRY_TABLE, 
       new String[] { KEY_ROWID, KEY_COUNTRYNAME, KEY_COUNTRYCODE }, 
       "Country like '%" + constraint.toString() + "%'", null, null, null, 
       "CASE WHEN Country like '" + constraint.toString() + 
       "%' THEN 0 ELSE 1 END, Country"); 
    } 
} 

Sembra proprio che ci sia un collegamento mancante da qualche parte. Qualsiasi aiuto sarebbe apprezzato.

Grazie,

Ian

+0

Perché si desidera utilizzare TextWatcher con EditText anziché con AutoCompleteTextView? –

+0

Cosa fare se si desidera fornire un'opzione per consentire agli utenti di scorrere un ListView e filtrare il ListView. A mio avviso, AutoCompleteTextView non ti permetterà di avere un listView separato. – rohitmishra

risposta

3

Sembra che si sta facendo un sacco di lavoro per qualcosa che è già integrato in Android. Dai un'occhiata alla finestra di dialogo di ricerca di Android al numero http://developer.android.com/guide/topics/search/search-dialog.html e dovrebbe essere molto facile per te.

+0

Eccellente: il mio problema originale è ancora un po 'un mistero, ma il tuo suggerimento di utilizzare la funzione di ricerca integrata è davvero la strada giusta da percorrere. Ho aggiunto l'implementazione alla mia app e funziona benissimo. Ora guardo i fornitori di contenuti in modo da poter offrire suggerimenti durante le ricerche e integrarmi ancora meglio nel sistema. Grazie! –

+0

Felice di poterti aiutare! –

15

Ho visto che sei riuscito a risolvere il tuo problema in un altro modo, ma ho pensato di aggiungere la risposta per altre persone che inciampano su questa domanda.

runQueryOnBackgroundThread() è responsabile solo dell'esecuzione di una query per un vincolo e della restituzione di un cursore. Per essere in grado di filtrare l'adattatore basato sul cursore è necessario fare qualcosa di simile

filterAdapter.getFilter().filter(s.toString()); 

Un CursorAdapter implementa sempre filtrabili per default, e tutto ciò che implementa filtrabili possono essere filtrati utilizzando

getFilter().filter(constraint)

Il modo in cui il Il filtro CursorAdapter integrato funziona se si esegue l'override di runQueryOnBackgroundThread() o se si utilizza setFilterQueryProvider(), quindi esegue quel codice in un thread in background, ottiene un nuovo cursore e lo imposta come cursore del CursorAdapter.

+0

Grazie per quell'informazione lo apprezzo e sono sicuro che lo userò ad un certo punto. –

+1

Questa dovrebbe essere la risposta accettata imho. – alaeri

Problemi correlati