Курсор неправильно связывает текст с помощью специального адаптера - PullRequest
2 голосов
/ 18 января 2012

Мой пользовательский адаптер, который расширяет SimpleCursorAdapter для моего ListFragment, неправильно отображает элементы в моей базе данных. он не отображает текст в TextView, что еще мне нужно сделать с курсором, чтобы он отображал правильный текст?

Я думал, что должен переопределить bindView, но это не дало эффекта

Настройка адаптера:

public void populateList(){

        String[] fields = new String[] {BowlersDB.NAME};
        Cursor c = getActivity().getContentResolver().query(BowlersDB.CONTENT_URI,
                new String[] {BowlersDB.ID,BowlersDB.NAME},null,null,BowlersDB.NAME + " COLLATE LOCALIZED ASC");

mAdapter = new CheckAdapter(getActivity(),R.layout.check_listview,c,fields,new int[] {R.id.nameCheckTV});


        setListAdapter(mAdapter);   

        getLoaderManager().initLoader(0,null,this);
    }

Адаптер:

public class CheckAdapter extends SimpleCursorAdapter{

    Context context;
    Cursor c;

    public CheckAdapter(Context context, int layout, Cursor c,String[] from, int[] to) {
        super(context, layout, c, from, to);
        this.context = context;
        this.c = c;
        // TODO Auto-generated constructor stub
    }

    @Override
    public void bindView(View view,Context context,Cursor cursor){
        String st = cursor.getString(cursor.getColumnIndex(BowlersDB.NAME));

        TextView tv = (TextView)view.findViewById(R.id.nameCheckTV);
        tv.setText(st);
    }

    @Override
    public View getView(final int position,View convertView,ViewGroup parent){
        if(convertView == null){
            LayoutInflater inflator = getLayoutInflater();
            convertView = inflator.inflate(R.layout.check_listview,null);
        }

        CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkBox1);   
            cb.setOnClickListener(new OnClickListener(){

                @Override
                public void onClick(View v) {
                    CheckBox check = (CheckBox)v.findViewById(R.id.checkBox1);
                    int pos = position;
                    if(check.isChecked()){
                        mCheckedItems.add(position);
                    }else if(!check.isChecked()){
                        for(int i=0;i< mCheckedItems.size();i++){
                            if(mCheckedItems.get(i) == position){
                                mCheckedItems.remove(i);
                            }
                        }
                    }
                }

            });
        return convertView;
    }

}

1 Ответ

6 голосов
/ 18 января 2012

Я думаю, что понял.Проверьте реализацию для CursorAdapter.getView().Обратите внимание, как bindView() и newView() вызываются в getView().Похоже, переопределяя getView(), вы гарантируете, что ваш CursorAdapter никогда не звонит bindView().Либо поместите все ТОЛЬКО в getView() или ТОЛЬКО в newView() и bindView(), но не в оба.


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

Четыре вещи:

  1. Я прочитал о CursorAdapter с, и похоже, что вы хотите переопределить bindView() вместо getView().Похоже, что getView() вызывается дважды для каждой строки, которая должна отображаться, и это как-то мешает обновлению курсора и, таким образом, всегда указывает на первую строку.Я думаю, именно поэтому ваш ListView отображает только первый ряд.Кроме того, реализация по умолчанию CursorAdapter для ListView перезапустит для вас представления, поэтому переопределение getView() действительно не требуется (проверьте этот ответ для получения дополнительной информации).

  2. При создании mAdapter вы должны передать нуль Cursor в конструктор.Cursor будет доставлен в onLoadFinished (когда Loader завершит запрос) и будет привязан к адаптеру с помощью swapCursor(cursor).

  3. Ваш onCreateLoader()Метод создаст (или запустит) Loader, который будет выполнять начальный запрос.Убедитесь, что это выглядит примерно так:

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        String[] projection = { BowlersDB.ID, BowlersDB.NAME };
    
        CursorLoader cursorLoader = new CursorLoader(getActivity(),
                BowlersDB.CONTENT_URI, projection, null, null, null);
        return cursorLoader;
    }
    
  4. Убедитесь, что вы используете правильный конструктор SimpleCursorAdapter ... тот, который вы используете в данный момент, устарел!(передайте 0 как флаг ... CursorLoader зарегистрирует для вас обозревателя контента, поэтому вам не нужно будет передавать что-то особенное).


EDIT II:

Для пояснения, метод bindView() - это место, где вы заполняете виджеты вашей строки данными из текущей позиции Cursor.Вам вручают Cursor, предварительно расположенную в соответствующем ряду.Вам нужно извлечь данные из Cursor и вылить их в нужные вам виджеты.Другими словами, вам нужно запросить идентификатор строки (вместо использования аргумента "position" в getView()).Попробуйте установить onClickListener в bindView(), например:

final int rowId = cursor.getInt(cursor.getColumnIndex("_id"));

CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkBox1);   
cb.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        int position = rowId;
        /* you now know this row's position. do what you need to do. */
    }
});
...