2010-12-31 16 views
6

Tengo una lista de países en una base de datos. Creé una actividad de país seleccionada que consiste en un cuadro de edición para filtrar y una lista que muestra el nombre del país y la bandera.Intentando filtrar un ListView con runQueryOnBackgroundThread pero no ocurre nada, ¿qué me estoy perdiendo?

Cuando comienza la actividad, la lista muestra toda la lista de países ordenados alfabéticamente: funciona bien. Cuando el cliente comienza a escribir en el cuadro de búsqueda, quiero que la lista se filtre según su mecanografía. La consulta de mi base de datos estaba trabajando previamente en AutoCompleteView (solo quiero cambiar a un cuadro de texto y una lista por separado), así sé que mi consulta completa y mi consulta de restricción están funcionando. Lo que hice fue agregar un TextWatcher a la vista EditText y cada vez que se cambia el texto invoco el SimpleCursorAdapter runQueryOnBackgroundThread de la lista con el texto de los cuadros de edición como la restricción. El problema es que la lista nunca se actualiza. He establecido puntos de interrupción en el depurador y TextWatcher realiza la llamada a runQueryOnBackgroundThread y se llama a mi FilterQueryProvider con la restricción esperada. La consulta de la base de datos va bien y se devuelve el cursor.

El adaptador cursor tiene un conjunto proveedor de consulta de filtro (y una vista de aglutinante para mostrar la bandera):

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

El FitlerQueryProvider:

private final class CountryFilterProvider implements FilterQueryProvider { 

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

Y el EditarTexto tiene 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 consulta de la base de datos tiene este aspecto:

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

Parece que falta un enlace en alguna parte. Cualquier ayuda sería apreciada.

Gracias,

Ian

+0

¿Por qué querías usar TextWatcher con EditText en lugar de AutoCompleteTextView? –

+0

¿Qué sucede si desea dar una opción para permitir a los usuarios desplazarse a través de un ListView y filtrar el ListView? A mi entender, AutoCompleteTextView no le permitirá tener un listView por separado. – rohitmishra

Respuesta

3

Parece como si estuvieras haciendo un montón de trabajo por algo que ya está integrado en Android. Eche un vistazo al diálogo de búsqueda de Android al http://developer.android.com/guide/topics/search/search-dialog.html, y debería ser muy fácil para usted.

+0

Excelente: mi problema original todavía es un misterio, pero su sugerencia de utilizar la función de búsqueda integrada es realmente el camino correcto. Agregué la implementación a mi aplicación y funciona muy bien. Ahora estoy buscando proveedores de contenido para poder ofrecer sugerencias durante las búsquedas e integrarme en el sistema aún mejor. ¡Gracias! –

+0

¡Me alegro de poder ayudar! –

15

Vi que lograste resolver tu problema de otra manera, pero pensé que debería agregar la respuesta para que otras personas tropiecen con esta pregunta.

runQueryOnBackgroundThread() solo es responsable de ejecutar una consulta para una restricción y devolver un Cursor. Para ser capaz de filtrar el adaptador basado en el cursor que tiene que hacer algo como

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

Un CursorAdapter siempre implementa Filtrable por defecto, y cualquier cosa que implementa filtrable se puede filtrar utilizando

getFilter().filter(constraint)

La forma en que el CursorAdapters built in filter works es que si anulas runQueryOnBackgroundThread() o si usas setFilterQueryProvider() entonces ejecuta ese código en una cadena de fondo, obtiene un nuevo cursor y lo establece como el cursor del CursorAdapter.

+0

Gracias por esa información, la aprecio y estoy seguro de que la usaré en algún momento. –

+1

Esta debería ser la respuesta aceptada. – alaeri

Cuestiones relacionadas