Не удается обновить пользовательский CursorAdapter, выполняющий запрос внутри getView - PullRequest
0 голосов
/ 28 марта 2012

Я до сих пор не понимаю, как именно должен работать пользовательский CursorAdapter, поэтому после тяжелых попыток вот что:

  1. Я реализую слушатель на кнопке внутри моего getView().
  2. Слушатель запускает событие удаления строки.
  3. Чтобы добраться до него, я использую одноэлементную базу данных, где я могу выполнить запрос от всех классов (фактически, синглтона)
  4. Я обычно обновляю (вставляю и изменяю) класс активности, поэтому мне просто нужно получить новый курсор базы данных и переназначить его на новый CursorAdapter, чтобы я переназначил себя для ListView.
  5. Здесь все по-другому: я нахожусь в классе CursorAdapter в методе ListView, и я не знаю, как обновить мой адаптер изнутри.

Для людей, которые не хотят читать мои скучные объяснения, вот код getView:

    @Override
public View getView(int position, View convertView, ViewGroup parent){
    convertViewParam = convertView;
    ViewHolder viewHolder = new ViewHolder();
    if (convertViewParam == null) {
        int type = getItemViewType(position);
        switch (type) {

        case TYPE_ADD_NOTE_TOP:
            convertViewParam = inflater.inflate(R.layout.add_note_top, null);
            viewHolder.contentNote = (EditText)convertViewParam.findViewById(R.id.add_note_top_id);
            break;
        case TYPE_ITEM:
            convertViewParam = inflater.inflate(R.layout.row_note, null);
            viewHolder.delete = (Button)convertViewParam.findViewById(R.id.delete);
            if (deleteMode){
                viewHolder.delete.setVisibility(View.VISIBLE);
            }else{
                viewHolder.delete.setVisibility(View.GONE);
            }

            viewHolder.contentNote = (TextView)convertViewParam.findViewById(R.id.note);

            getCursor().moveToPosition(position - 1);
            int currentPosition = getCursor().getPosition();
            Cursor c = getCursor();
            c.moveToPosition(currentPosition);

            ((TextView) viewHolder.contentNote).setText(c.getString(c.getColumnIndex("content_note")));
            int rowId = c.getInt(c.getColumnIndex("_id"));

            viewHolder.delete.setTag(new Integer(rowId));
            viewHolder.contentNote.setTag(new Integer(rowId));

            OnClickListener listener = new OnClickListener() {

                @Override
                public void onClick(View v) {
                    int thePosition = (Integer) v.getTag();

                    int posCurs = notesCursorAdapter.getCursor().getPosition();
                    NoteDataSource.getSingletonObject(context).deleteNote(thePosition, context);
                    notesCursorAdapter.changeCursor(NoteDataSource.getSingletonObject(context).getAllNotes());
                    notesCursorAdapter.notifyDataSetChanged();

                }
            };
            viewHolder.delete.setOnClickListener(listener);

            break;

        case TYPE_ADD_NOTE_BOTTOM:
            convertViewParam = inflater.inflate(R.layout.add_note_bottom, null);
            LinearLayout linearLayout = (LinearLayout)convertViewParam.findViewById(R.id.bottomLayout);
            linearLayout.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {

                }
            });
            break;
        }
        convertViewParam.setTag(viewHolder);
    } else {

        viewHolder = (ViewHolder)convertViewParam.getTag();
        if (viewHolder.contentNote!=null){
            if (viewHolder.contentNote.getTag() == convertViewParam.findViewById(R.id.note)){
                int test = (Integer) viewHolder.delete.getTag();
                System.out.println("current tag " + test);
                String txt = getCursor().getString(getCursor().getColumnIndex("content_note"));
                ((TextView) viewHolder.contentNote).setText(txt);
            }
        }


    }

    return convertViewParam;
}

Я получаю следующую ошибку при запуске события удаления:

03-28 17:51:32.996: E/AndroidRuntime(7115): android.database.CursorIndexOutOfBoundsException: Index 2 requested, with a size of 2

Если вам нужна дополнительная информация, спросите.

Я ищу исправление ошибки или просто объяснениеИон, спасибо.

Ответы [ 2 ]

2 голосов
/ 28 марта 2012

Это очень хорошо написанная постановка задачи. У меня была эта проблема, и я сломал ей голову. Попробуйте это.

  • В вашем адаптере сделайте слушатель, что-то вроде
public interface ItemDeletedListener(){
    public void itemDeleted(int position);
}
  • создайте экземпляр ItemDeletedListener в вашем адаптере, m_listener.

  • Написать функцию установки, setItemDeletedListener (слушатель ItemDeletedListener) {}

  • В вашем getView () onClickListener вызовите m_listener и передайте позицию, которую нужно удалить.

Теперь в вашей деятельности выполните следующее.

  1. Реализуйте прослушиватель, который вы создали выше.
  2. В вашей реализации выполните удаление, а затем выполните там changeCursor ().
1 голос
/ 28 марта 2012

Было бы полезно узнать, по какой линии вы получаете исключение.Прежде всего, одна плохая вещь заключается в том, что вы удаляете заметку из базы данных на основе позиции int, и после этого вы снова выбираете все данные и перемещаете позицию на этом курсоре на предыдущую удаленную позицию.

Если у вас есть 3 заметки (и вы показываете их в списке) в базе данных, и вы хотите удалить последнюю, это произойдет:

  • thePosition будет 2
  • вы удаляете заметку
  • снова выбираете все заметки из базы данных (теперь курсор будет иметь 2 строки, потому что вы удалили одну)
  • переместите курсор на thePosition (значение 2)
  • курсор имеет только 2 строки (пронумерованы от 0), и вы запрашиваете строку с номером 2
  • исключение

Если вы хотите удалить заметкузатем передайте в качестве тега _id для этой строки и используйте его для удаления заметки:

Cursor c = getCursor();
c.moveToPosition(position); 
long rowId = c.getLong(c.getColumnIndex("_id"));
viewHolder.delete.setTag(new Long(rowId));

Затем в методе onClick() используйте это, чтобы удалить заметку и прекратить возиться с moveToPosition()на курсоре.

...