Android 使用来自DB的新数据的光标刷新ListView

Android 使用来自DB的新数据的光标刷新ListView,android,database,listview,refresh,adapter,Android,Database,Listview,Refresh,Adapter,刷新列表视图时出现问题。我调用我的列表视图活动,我使用带有光标的SQL语句从数据库获取数据,我使用自定义适配器(扩展基本适配器)绘制列表视图),一切正常 我想在顶部放置一个编辑文本,以搜索我的列表视图上的项目,用键入的文本过滤实际视图,相同的活动。我从EditText中选择getText(),并创建一个新的SQL语句,用此文本过滤结果。我已检查光标是否具有正确的筛选结果,但我使用了适配器.notifyDataSetChanged()尝试更新列表视图,但没有发生任何事情(没有错误或强制关闭) 有谁

刷新列表视图时出现问题。我调用我的
列表视图
活动
,我使用带有光标的SQL语句从数据库获取数据,我使用自定义适配器(扩展
基本适配器
)绘制
列表视图
),一切正常

我想在顶部放置一个
编辑文本
,以搜索我的
列表视图
上的项目,用键入的文本过滤实际视图,相同的活动。我从
EditText
中选择
getText()
,并创建一个新的SQL语句,用此文本过滤结果。我已检查光标是否具有正确的筛选结果,但我使用了适配器.notifyDataSetChanged()尝试更新
列表视图,但没有发生任何事情(没有错误或强制关闭)

有谁能帮助我或告诉我一些技巧,以获得这个简单的搜索功能与数据库一起工作?我在
ArrayLists+getFilter()+SimpleCursorAdapter
中发现了许多类似的问题,但它不适用于我的数据库和自定义适配器

活动列表分类:

@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自定义适配器,AdapterListCharacters从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;
}
}

重新初始化适配器,而不是
notifydatasetchanged():


现在它开始工作了!我的一位朋友(谢谢Muni!)找到了一种更好的方法,可以通过EditText以友好方式过滤listview结果:

buscador.setOnKeyListener(new OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
而不是:

buscador.addTextChangedListener(new TextWatcher()
{
谢谢大家的帮助

编辑:

更新@AlexMuni和我自己的答案时,
onKey()
方法在emulator上运行得很好,但在实际设备上运行得不好

我终于用前面的方法完美地完成了:

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)
        {
        }
    });     
试试这个:

/*
 * 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;
    }

});
/*********************************************/
祝你好运;)


亚历克斯

我想这个链接会帮助你。。。谢谢…尝试扩展CursorAdapter类并使用这个构造函数。我已经尝试更改为CursorAdapter,ListView工作正常,但仍然没有刷新。我已经尝试了requery()游标,但什么都没有发生,adapter.changeCursor(newCursor)抛出异常“尝试获取关闭SQLiteClosable上的引用”,但我没有关闭任何SQL对象。。。我很惊讶更新一个简单的ListView有多么困难:(谢谢你也尝试了AsyncTask,但是我没有看到调用adapter.notifyDataSetChanged()会发生任何事情,同样的,我也在Android 2.1、2.2和4.0上运行了这个程序,因为可能有一个bug(关于这个问题有很多问题,没有明确的答案)。谢谢,但如果我这样做,我将获得一个强制关闭,LogCat:04-02 10:19:53.984:E/AndroidRuntime(565):未捕获处理程序:线程主线程由于未捕获异常而退出04-02 10:19:54.004:E/AndroidRuntime(565):java.lang.NullPointerException 04-02 10:19:54.004:E/AndroidRuntime(565):在es.hsk.ap.caracteres.AdapterListCaracteres.getView(AdapterListCaracters.java:56)04-02 10:19:54.004:E/AndroidRuntime(565):在android.widget.AbsListView.ActainView(AbsListView.java:1274)04-02 10:19:54.004:E/AndroidRuntime(565):在android.widget.ListView.MeasureHeightOChildren(ListView.java:1147)然后将适配器设置为null,然后重新初始化itI我已尝试将适配器设置为null,但当我尝试设置适配器时,它会引发相同的NullPointerException。我还尝试将ListView.setAdapter(null)设置为空,然后将setAdapter(adapter)设置为空,但相同:(
/*
 * 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;
    }

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