Обновить ListView с курсором новыми данными из БД - PullRequest
0 голосов
/ 02 апреля 2012

У меня проблема с обновлением ListView. Я называю свой ListView Activity, я получаю данные из БД с SQL-инструкцией с курсором, я рисую ListView с помощью специального адаптера (расширяет BaseAdapter), все работает нормально.

Я хочу поставить EditText сверху для поиска элементов на моем ListView, отфильтровать фактический вид, то же действие, с набранным текстом. Я getText() из EditText и создаю новый SQL-запрос, фильтруя результаты с помощью этого текста. Я проверил, что курсор имеет правильные отфильтрованные результаты, но я использую adapter.notifyDataSetChanged(), пытаясь обновить ListView, но ничего не происходит (без ошибок или принудительного закрытия).

Может кто-нибудь помочь мне или подсказать несколько советов, как получить эту простую функцию поиска для работы с базой данных? Я нашел много подобных вопросов с 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();
        }
    });
}

Мой пользовательский адаптер , AdapterListaCaracteres расширяется от 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;
}
}

Ответы [ 3 ]

1 голос
/ 06 апреля 2012

Попробуйте это:

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

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

Удачи;)

ALEX

0 голосов
/ 05 апреля 2012

Теперь это работает!Мой друг (спасибо, Муни!) Нашел лучший способ динамически фильтровать результаты просмотра списка с помощью EditText:

buscador.setOnKeyListener(new OnKeyListener() {

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

вместо:

buscador.addTextChangedListener(new TextWatcher()
{

Спасибо всем за помощь.

РЕДАКТИРОВАТЬ:

Обновление @AlexMuni и мой собственный ответ, onKey() метод отлично работает на эмуляторе, но не работает в реальных устройствах.

Я наконец-то отлично справился с предыдущим методом:

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)
        {
        }
    });     
0 голосов
/ 02 апреля 2012

Повторно инициализируйте адаптер вместо notifydatasetchanged():

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