Pelanes
Pelanes

Reputation: 3479

Refresh a ListView with a cursor with new data from DB

I have a problem refreshing a ListView. I call my ListView Activity, I get the data from DB with a SQL statment with a cursor, I draw the ListView with a custom adapter (extends BaseAdapter), all works fine.

I want to put an EditText on the top to search items on my ListView, filter the actual view, same Activity, with the typed text. I getText() from EditText, and make a new SQL statment filtering the results with this text. I have checked that the cursor has the correct filtered results, but I use adapter.notifyDataSetChanged() trying to update the ListView but nothing happens (no errors or force closes).

Can anyone help me or tell me some tips to obtain this simple search function working with a database? I have found many similar questions with ArrayLists + getFilter() + SimpleCursorAdapter, but it doesn't works with my DB and custom adapter.

Activity 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();
        }
    });
}

My custom adapter, AdapterListaCaracteres extends from 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;
}
}

Upvotes: 0

Views: 1699

Answers (3)

mayank_droid
mayank_droid

Reputation: 1015

Re-initialize the Adapter instead of notifydatasetchanged():

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

Upvotes: 0

Pelanes
Pelanes

Reputation: 3479

Now it's working! A friend of mine (Thanks Muni!) found a better way to filter a listview result dinamically with EditText:

buscador.setOnKeyListener(new OnKeyListener() {

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

instead of:

buscador.addTextChangedListener(new TextWatcher()
{

Thanks all people for your help.

EDIT:

Updating @AlexMuni and my own answer, onKey() method runs perfectly on emulator, but doesn't works fine in real devices.

I finally have done it perfectly with the previous method:

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

Upvotes: 0

Alex Muni
Alex Muni

Reputation: 474

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

Upvotes: 1

Related Questions