Reputation: 3479
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
Reputation: 1015
Re-initialize the Adapter instead of notifydatasetchanged():
adapter = new AdapterListaCaracteres(this,c);
listaCaracteres.setAdapter(adapter);
Upvotes: 0
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
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