2011-03-16 19 views
23

Me gustaría filtrar un ListView basado en SimpleCursorAdapter con un cuadro EditText justo encima de él. Tengo el siguiente código, pero cuando escribo en el cuadro, no pasa nada; la lista completa sigue apareciendo. ¿Qué estoy haciendo mal?ListView, SimpleCursorAdapter, un filtro EditText - ¿por qué no hará nada?

mCursor = getDirectoryList(null); 

    adapter = new SimpleCursorAdapter(this, 
      R.layout.directory_people_item, mCursor, 
      new String[]{ 
       directoryPeople.LAST_NAME, 
       directoryPeople.FIRST_NAME, 
       directoryPeople.MIDDLE_NAME, 
       directoryPeople.JOB_TITLE}, 
      new int[]{ 
       R.id.txtLastName, 
       R.id.txtFirstName, 
       R.id.txtMiddle, 
       R.id.txtTitle} 
    ); 

    ListView av = (ListView)findViewById(R.id.listPeople); 
    av.setAdapter(adapter); 
    av.setFastScrollEnabled(true); 
    av.setTextFilterEnabled(true); 

    EditText etext=(EditText)findViewById(R.id.search_box); 
    etext.addTextChangedListener(new TextWatcher() { 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
     } 

     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
     } 

     public void afterTextChanged(Editable s) { 
      ListView av = (ListView)findViewById(R.id.listPeople); 
      SimpleCursorAdapter filterAdapter = (SimpleCursorAdapter)av.getAdapter(); 
      filterAdapter.getFilter().filter(s.toString()); 
     } 
    }); 

    adapter.setFilterQueryProvider(new FilterQueryProvider() { 
     public Cursor runQuery(CharSequence constraint) { 
      return getDirectoryList(constraint); 
     } 
    }); 

Y aquí es getDirectoryList():

public Cursor getDirectoryList (CharSequence constraint) { 
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); 
    queryBuilder.setTables(
     directoryPeople.PEOPLE_TABLE 
    ); 

    String asColumnsToReturn[] = { 
      directoryPeople.PEOPLE_TABLE + "." 
      + directoryPeople.LAST_NAME + "," + 
      directoryPeople.PEOPLE_TABLE + "." 
      + directoryPeople.FIRST_NAME + "," + 
      directoryPeople.PEOPLE_TABLE + "." 
      + directoryPeople.MIDDLE_NAME + "," + 
      directoryPeople.PEOPLE_TABLE + "." 
      + directoryPeople.JOB_TITLE + "," + 
      directoryPeople.PEOPLE_TABLE + "." 
      + directoryPeople._ID 
    }; 

    if (constraint == null || constraint.length() == 0) { 
     // Return the full list 
     return queryBuilder.query(mDB, asColumnsToReturn, null, null, 
       null, null, directoryPeople.DEFAULT_SORT_ORDER); 
    } else { 
     return mDB.query(directoryPeople.PEOPLE_TABLE, asColumnsToReturn, "LAST_NAME like '%'" + 
      constraint.toString() + "'%'", null, null, null, 
      "CASE WHEN LAST_NAME like '" + constraint.toString() + 
      "%' THEN 0 ELSE 1 END, LAST_NAME"); 
    } 
} 

He probado todos los ejemplos y la respuesta que he encontrado en mis búsquedas, pero fue en vano. Es frustrante, como te puedes imaginar. Gracias de antemano por cualquier persona que pueda ayudar!

Respuesta

14

Trate de esta manera:

} else { 
    String value = "%"+constraint.toString()+"%"; 

    return mDB.query(directoryPeople.PEOPLE_TABLE, asColumnsToReturn, "LAST_NAME like ? ", new String[]{value}, null, null, null); 
} 

me he saltado el último argumento, porque no sé lo que realmente debe hacer:

"CASE WHEN LAST_NAME like '" + constraint.toString() + "%' THEN 0 ELSE 1 END, LAST_NAME" 

¿Has probado esta consulta con cáscara de emulador?

+0

Realmente no sé lo que hace el argumento tampoco. Copié ese bit de un ejemplo que encontré y estaba demasiado cansado en ese momento para descubrir qué hacía esa parte, así que lo dejé. Pero si el filtro funcionó y esa consulta era defectuosa, ¿al menos no debería cambiar el ListView en de alguna manera de todos modos? Probaré tu sugerencia e informaré. – LouieGeetoo

+0

¡Está trabajando con su sugerencia! No tienes idea de lo feliz que estoy. Estuve tan cerca todo este tiempo. Muchas gracias! – LouieGeetoo

+0

¿Qué es mDB aquí? Usar el mismo helper de base de datos que el usado para SimpleCursorAdapter me está dando un "Invalid Statement in fillWindow() error" En mi lista de actividad, he usado una instancia de mDbHelper que es mi DatabaseHelper. Hago una llamada a c = mDbHelper.fetchAllFriends() seguido de un startManagingCursor() en la onCreate de mi listActivity. ¿Debo declarar una nueva instancia de mDbHelper para la llamada en runQuery()? – rohitmishra

Cuestiones relacionadas