2010-06-12 15 views
11

Tengo un Cursor que devuelve filas que uso con un SimpleCursorAdapter para rellenar un ListView. Me gustaría filtrar algunas de las filas para que no se muestren en mi ListView. Uso los datos de las filas en otra parte de mi Actividad, por lo que no quiero cambiar mi SQL para filtrarlos con una cláusula WHERE.Filtrar filas del Cursor para que no aparezcan en ListView

¿Cuál es la mejor manera de evitar que una fila se muestre en mi ListView? Idealmente, verificaría una columna en mi fila y luego solo agregaría filas al ListView que satisfaga una condición.

+0

posible duplicado de [Android: Cómo filtrar por texto una lista de la lista basada en un simplecursoradapter?] (Http://stackoverflow.com/questions/2002607/android-how-to-text-filter-a-listview-based- on-a-simplecursoradapter) –

+0

Esta respuesta tiene un código que puede copiar: http://stackoverflow.com/questions/3766688/filtering-a-cursor-the-right-way – satur9nine

Respuesta

18

Crear una CursorWrapper y anular los métodos move...() para convertir posiciones en el conjunto filtrado (que es lo que el ListView veremos) y posiciones en el actual Cursor. Luego, use su CursorWrapper en el SimpleCursorAdapter.

15

Gracias, esto me ayuda mucho! Utilizarlo si es necesario:

private class FilterCursorWrapper extends CursorWrapper {  
    private String filter; 
    private int column; 
    private int[] index; 
    private int count=0; 
    private int pos=0; 

    public FilterCursorWrapper(Cursor cursor,String filter,int column) { 
     super(cursor); 
     this.filter = filter.toLowerCase(); 
     this.column = column; 
     if (this.filter != "") { 
      this.count = super.getCount(); 
      this.index = new int[this.count]; 
      for (int i=0;i<this.count;i++) { 
       super.moveToPosition(i); 
       if (this.getString(this.column).toLowerCase().contains(this.filter)) 
        this.index[this.pos++] = i; 
      } 
      this.count = this.pos; 
      this.pos = 0; 
      super.moveToFirst(); 
     } else { 
      this.count = super.getCount(); 
      this.index = new int[this.count]; 
      for (int i=0;i<this.count;i++) { 
       this.index[i] = i; 
      } 
     } 
    } 

    @Override 
    public boolean move(int offset) { 
     return this.moveToPosition(this.pos+offset); 
    } 

    @Override 
    public boolean moveToNext() { 
     return this.moveToPosition(this.pos+1); 
    } 

    @Override 
    public boolean moveToPrevious() { 
     return this.moveToPosition(this.pos-1); 
    } 

    @Override 
    public boolean moveToFirst() { 
     return this.moveToPosition(0); 
    } 

    @Override 
    public boolean moveToLast() { 
     return this.moveToPosition(this.count-1); 
    } 

    @Override 
    public boolean moveToPosition(int position) { 
     if (position >= this.count || position < 0) 
      return false; 
     this.pos = position; 
     return super.moveToPosition(this.index[position]); 
    } 

    @Override 
    public int getCount() { 
     return this.count; 
    } 

    @Override 
    public int getPosition() { 
     return this.pos; 
    } 

} 

https://gist.github.com/ramzes642/5400792

+0

¿Puede explicar cómo usarlo? favor – AndrewS

+1

Sólo una cosa que añadir: almacenar el cursor de base en el constructor de una anulación del cierre(): @ Override void close pública() {si (baseCursor! = null) baseCursor.close(); super.close(); } –

+0

2 otras cosas: (this.filter! = "") Es incorrecta y this.pos nunca se actualiza, por lo que getPosition() ya devolverá 0. Aparte de eso, esto funciona muy bien. – 3c71

2

en solución de Romanos añadir

this.pos = position; 

en el método

@Override 
public boolean moveToPosition(int position) { 
    if (position >= this.count || position < 0) 
     return false; 
    return super.moveToPosition(this.index[position]); 
} 

De lo contrario obtendrá algunos problemas al usar .moveToNext() y .moveToPrevious().

Cuestiones relacionadas