2012-04-02 4 views
0

Ich habe ein Problem beim Aktualisieren einer ListView. Ich rufe meine ListViewActivity, ich bekomme die Daten aus der DB mit einer SQL-Anweisung mit einem Cursor, ich zeichne die ListView mit einem benutzerdefinierten Adapter (erweitert BaseAdapter), alles funktioniert gut.Aktualisieren Sie eine ListView mit einem Cursor mit neuen Daten aus DB

Ich möchte EditText auf die Oberseite setzen, um Einzelteile auf meinem ListView zu suchen, die tatsächliche Ansicht, gleiche Tätigkeit, mit dem getippten Text filtern. I getText() von EditText, und machen Sie eine neue SQL-Statement-Filterung der Ergebnisse mit diesem Text. Ich habe überprüft, dass der Cursor die richtigen gefilterten Ergebnisse hat, aber ich adapter.notifyDataSetChanged() versuche, die ListView zu aktualisieren, aber nichts passiert (keine Fehler oder Kraft schließt).

Kann jemand mir helfen oder mir einige Tipps geben, um diese einfache Suchfunktion zu erhalten, die mit einer Datenbank arbeitet? Ich habe viele ähnliche Fragen mit gefunden, aber es funktioniert nicht mit meinem DB und benutzerdefinierten Adapter.

Aktivität ListaCaracteres:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(es.hsk.ap.R.layout.lista_caracteres); 

    try{ 
     hanyuDBHelper = new HanyuSQLHelper(this); 
     hanyuDB = hanyuDBHelper.getReadableDatabase(); 
     c = hanyuDB.rawQuery(" SELECT * FROM Caracteres ", null); 
    } 
    catch(SQLiteException ex) 
    { 
     Toast mensajeError=Toast.makeText(getApplicationContext(), "Error accediendo a los datos", Toast.LENGTH_SHORT); 
     mensajeError.show(); 
     Log.e("LogLugares", "Error en getReadableDatabase()", ex); 
    } 


    adapter = new AdapterListaCaracteres(this,c); 
    listaCaracteres = (ListView)findViewById(es.hsk.ap.R.id.listaCaracteres); 
    listaCaracteres.setAdapter(adapter); 

    buscador = (EditText)findViewById(R.id.buscador); 
    buscador.addTextChangedListener(new TextWatcher() 
    { 
     @Override 
     public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) 
     { 
     } 

     @Override 
     public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) 
     { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void afterTextChanged(Editable arg0) 
     { 
      // TODO Auto-generated method stub 

      String texto=""; 
      texto=buscador.getText().toString(); 

      c = hanyuDB.rawQuery(" SELECT * FROM Caracteres WHERE significado LIKE '%"+texto+"%'", null); 
      adapter.notifyDataSetChanged(); 
     } 
    }); 
} 

Mein benutzerdefinierte Adapter erstreckt sich AdapterListaCaracteres von BaseAdapter:

public class AdapterListaCaracteres extends BaseAdapter implements ListAdapter{ 

private Context mContext; 
private Cursor datos; 
private LayoutInflater inflater; 

public AdapterListaCaracteres(Context context, Cursor c){ 
    this.mContext = context; 
    this.datos = c; 
} 

@Override 
public int getCount() { 
    // TODO Auto-generated method stub 
    return datos.getCount(); 
} 

@Override 
public Object getItem(int position) { 
    // TODO Auto-generated method stub 
    return datos.getString(position); 
} 

@Override 
public long getItemId(int position) { 
    // TODO Auto-generated method stub 
    return 0; 
} 

public View getView(int position, View convertView, ViewGroup parent) { 
    // TODO Auto-generated method stub 

    View item = convertView; 
    ViewHolder holder; 

    inflater = (LayoutInflater) mContext.getSystemService(Context .LAYOUT_INFLATER_SERVICE); 
    datos.moveToPosition(position); 

    if(item==null){ 
     try{ 
      item = inflater.inflate(es.hsk.ap.R.layout.caracter, null); 
     } 
     catch(InflateException ex) 
     { 

     } 


     holder = new ViewHolder(); 
     holder.caracter = (TextView)item.findViewById(es.hsk.ap.R.id.caracter); 
     holder.pinyin = (TextView)item.findViewById(es.hsk.ap.R.id.pinyin); 
     holder.significado = (TextView)item.findViewById(es.hsk.ap.R.id.significado); 

     item.setTag(holder); 
    } 
    else{ 
     holder = (ViewHolder)item.getTag(); 
    }   

    holder.caracter.setText(datos.getString(2));    
    holder.pinyin.setText(datos.getString(3)); 
    holder.significado.setText(datos.getString(4)); 

    return item; 

} 
static class ViewHolder{ 
    TextView caracter; 
    TextView pinyin; 
    TextView significado; 
} 
} 
+0

Ich denke, dieser Link HWLP Sie ... Dank ... – user4232

+0

versuchen Adapter Cursor-Klasse erweitern und benutzen Sie diesen Konstruktor http://developer.android.com/reference/android/support/v4/widget/CursorAdapter.html#CursorAdapter%28android.content.Context ,% 20android.database.Cursor,% 20boolean% 29 –

+0

Ich habe versucht, CursorAdapter zu ändern, ListView funktioniert ok, aber es gibt immer noch keine Aktualisierung. Ich habe versucht requery() Cursor, passiert nichts, adapter.changeCursor (newCursor) löst Ausnahme "versuchen, eine Referenz auf eine nahe SQLiteClosable zu erwerben", aber ich schließe kein SQL-Objekt ... Ich bin überrascht, wie schwierig ist um einen einfachen ListView zu aktualisieren :(Danke – Pelanes

Antwort

1

Try this:

/* 
* Listener que actuará cuando se escriba en el EditText 
*/ 
buscador.setOnKeyListener(new OnKeyListener() { 

    @Override 
    public boolean onKey(View v, int keyCode, KeyEvent event) { 
     // TODO Auto-generated method stub 
     String texto = ""; 
     texto = buscador.getText().toString(); 
     c = hanyuDB.rawQuery(" SELECT * FROM Caracteres WHERE significado LIKE '%"                       + texto + "%'", null); 

     AdapterListaCaracteres adapter2 = new AdapterListaCaracteres(getApplicationContext(), c, false); 
     listaCaracteres.setAdapter(adapter2); 
     return false; 
    } 

}); 
/*********************************************/ 

Good Luck;)

ALEX

0

neu initialisieren Adapter statt notifydatasetchanged():

adapter = new AdapterListaCaracteres(this,c); 
    listaCaracteres.setAdapter(adapter); 
+0

Danke, aber wenn ich das tue, erhalte ich eine Force Close, LogCat: 04-02 10: 19: 53.984 : E/AndroidRuntime (565): Uncaught handler: thread main, das wegen der nicht abgefangenen Ausnahme beendet wird 04-02 10: 19: 54.004: E/AndroidRuntime (565): java.lang.NullPointerException 04-02 10: 19: 54.004: E/AndroidRuntime (565): \t bei es.hsk.ap.caracteres.AdapterListaCaracteres.getView (AdapterListaCaracteres.java:56) 04-02 10: 19: 54.004: E/AndroidRuntime (565): \t bei android.widget.AbsListView.obtainView (AbsListView.java:1274) 04-02 10: 19: 54.004: E/AndroidRuntime (565): \t bei android.widget.ListView.measureHeightOfChildren (ListView.java:1147) – Pelanes

+0

Setzen Sie dann den Adapter einmal auf Null und initialisieren Sie ihn erneut. –

+0

Ich habe versucht, den Adapter auf Null zu setzen, aber wenn ich versuche ,Adapter zu setzen, wird dieselbe NullPointerException ausgelöst. Ich habe auch versucht, ListView.setAdapter (null) und dannAdapter (Adapter) setzen, aber das gleiche :( – Pelanes

0

Jetzt funktioniert es! Ein Freund von mir (! Dank Muni) fand einen besseren Weg zu einem Listview Ergebnis dinamically mit EditText zu filtern:

buscador.setOnKeyListener(new OnKeyListener() { 

     @Override 
     public boolean onKey(View v, int keyCode, KeyEvent event) { 

statt:

buscador.addTextChangedListener(new TextWatcher() 
{ 

Dank all Menschen für Ihre Hilfe.

EDIT:

aktualisiert @AlexMuni und meine eigene Antwort, onKey() Verfahren läuft perfekt auf Emulator, aber nicht funktioniert nicht gut in realen Geräten.

Ich habe es schließlich perfekt mit dem vorherigen Verfahren durchgeführt:

buscador = (EditText)findViewById(R.id.buscador); 
    buscador.addTextChangedListener(new TextWatcher() 
    { 
     @Override 
     public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) 
     { 
      texto = buscador.getText().toString(); 
      c = hanyuDB.rawQuery(
        " SELECT * FROM Caracteres WHERE significado LIKE '%" 
          + texto + "%'", null); 
      AdapterListaCaracteres adapter2 = new AdapterListaCaracteres(ListaCaracteres.this, c, false); 
      listaCaracteres.setAdapter(adapter2); 
     } 

     @Override 
     public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) 
     { 
     } 

     @Override 
     public void afterTextChanged(Editable arg0) 
     { 
     } 
    });  
Verwandte Themen