2010-12-31 2 views
6

Ich habe eine Liste von Ländern in einer Datenbank. Ich habe eine ausgewählte Länderaktivität erstellt, die aus einem Bearbeitungsfeld zum Filtern und einer Liste besteht, in der die Flagge und der Name des Landes angezeigt werden.Versuch, eine ListView mit runQueryOnBackgroundThread zu filtern, aber nichts passiert - was fehlt mir?

Wenn die Aktivität der Liste beginnt zeigt die gesamte Liste der Länder alphabetisch sortiert - funktioniert einwandfrei. Wenn der Kunde beginnt, in das Suchfeld einzutippen, möchte ich, dass die Liste anhand ihrer Eingabe gefiltert wird. Meine Datenbankabfrage funktionierte bisher in einer AutoCompleteView (ich möchte nur zu einem separaten Textfeld und einer Liste wechseln), so dass ich weiß, dass meine vollständige Abfrage und meine Constraint-Abfrage funktionieren. Was ich tat, war eine TextWatcher zum EditText Ansicht hinzufügen und jedes Mal, wenn der Text geändert wird, ich die SimpleCursorAdapter runQueryOnBackgroundThread mit dem Editboxen Text als Einschränkung der Liste aufzurufen. Das Problem ist, die Liste wird nie aktualisiert. Ich habe Breakpoints im Debugger gesetzt und der TextWatcher macht den Aufruf von runQueryOnBackgroundThread und mein FilterQueryProvider wird mit der erwarteten Constraint aufgerufen. Die Datenbankabfrage funktioniert einwandfrei und der Cursor wird zurückgegeben.

Der Cursor Adapter hat einen Filter query Provider Satz (und eine Ansicht Bindemittel das Flag anzuzeigen):

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

Die FitlerQueryProvider:

private final class CountryFilterProvider implements FilterQueryProvider { 

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

Und die EditText hat eine 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 
     } 
    }); 

Die Abfrage für die Datenbank sieht wie folgt aus:

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"); 
    } 
} 

Es scheint nur, als gäbe es irgendwo einen fehlenden Link. Jede Hilfe wäre willkommen.

Danke,

Ian

+0

Warum haben Sie wollen statt eines AutoCompleteTextView ein TextWatcher w/EditText benutzen? –

+0

Was ist, wenn Sie eine Option geben möchten, um die Benutzer durch eine ListView zu scrollen sowie die ListView zu filtern. Zu meinem Verständnis wird AutoCompleteTextView Sie nicht eine separate ListView haben. – rohitmishra

Antwort

3

Es scheint, wie Sie eine Menge Arbeit für etwas tun, die bereits in Android integriert ist. Sehen Sie sich den Android Search-Dialog unter http://developer.android.com/guide/topics/search/search-dialog.html an, und es sollte für Sie sehr einfach sein.

+0

Ausgezeichnet - mein ursprüngliches Problem ist immer noch ein Rätsel, aber Ihr Vorschlag, die eingebaute Suchfunktion zu verwenden, ist wirklich der richtige Weg. Ich habe die Implementierung zu meiner App hinzugefügt und es funktioniert großartig. Jetzt schaue ich mir Content-Provider an, damit ich bei Suchanfragen Vorschläge machen und noch besser in das System integrieren kann. Vielen Dank! –

+0

Ich bin froh, dass ich helfen konnte! –

15

ich sah, dass Sie Ihr Problem auf eine andere Weise lösen verwaltet, sondern dachte, dass ich auf diese Frage zu stolpern die Antwort für andere Menschen hinzufügen sollten.

runQueryOnBackgroundThread() ist nur für eine Abfrage für eine Einschränkung läuft und einen Cursor zurück. Um den Adapter zu filtern basierend auf dem Cursor müssen Sie so etwas wie

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

Ein Adapter Cursor tun implementiert immer Filterbare standardmäßig und alles, was filterbar implementiert, kann gefiltert werden

getFilter().filter(constraint)

Die Art und Weise, dass die Cursoradapter in eingebautem Filter funktioniert ist, dass, wenn Sie entweder außer Kraft setzen runQueryOnBackgroundThread() oder wenn Sie setFilterQueryProvider(), dann läuft es, dass Code in einem Hintergrund-Thread, einen neuen Cursor bekommt und setzt sie als Cursor der Cursor.

+0

Danke für diese Informationen Ich schätze es und ich bin mir sicher, dass ich es irgendwann verwenden werde. –

+1

Dies sollte die akzeptierte Antwort imho sein. – alaeri

Verwandte Themen