Как можно удалить данные из БД по id из RecyclerView

438
07 января 2017, 13:22

Коллеги, спасите, дедлайн уже близко. Работа встала. В ListView проблем в этом не было, так как в onItemClick передавался id. В RecyclerView такого нет, записи удаляются и соответственно id из

1
2
3
4

Превращаются в

1
2
4

Я удаляю строку данных по позиции в списке. В итоге вся логика теряется и после первого удаления удаляется элемент до выбранного. Потом два раза до выбранного и т.д

Адаптер

public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.AdapterHolder> {
    Cursor cursor;
    Context context;
    NotepadActivity activity;
    public class AdapterHolder extends RecyclerView.ViewHolder {
        TextView time, date, text;
        CardView card;
        ImageView edit, delete;
        AdapterHolder(View itemView) {
            super(itemView);
            time = (TextView)itemView.findViewById(R.id.note_item_time);
            date = (TextView)itemView.findViewById(R.id.note_item_date);
            text = (TextView)itemView.findViewById(R.id.note_text);
            card = (CardView)itemView;
            edit = (ImageView)itemView.findViewById(R.id.note_edit);
            delete = (ImageView)itemView.findViewById(R.id.note_delete);
            delete.setOnClickListener(delete_listener);
        }
        OnClickListener delete_listener = new OnClickListener(){
            @Override
            public void onClick(View v) {
                initDeleteDialog(getAdapterPosition()+1);
            }
        };
    }
    NotesAdapter(Cursor cursor, Context context) {
        this.cursor = cursor;
        this.context = context;
        this.activity = (NotepadActivity)context;
    }
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }
    @Override
    public AdapterHolder onCreateViewHolder(ViewGroup viewGroup, int p2) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.note_item, viewGroup, false);
        AdapterHolder pvh = new AdapterHolder(v);
        return pvh;
    }
    @Override
    public void onBindViewHolder(final AdapterHolder holder, int position) {
        cursor.moveToPosition(position);
        String date = cursor.getString(cursor.getColumnIndex(Database.NOTES_DATE));
        String time = cursor.getString(cursor.getColumnIndex(Database.NOTES_TIME));
        String color = cursor.getString(cursor.getColumnIndex(Database.NOTES_COLOR));
        String text = cursor.getString(cursor.getColumnIndex(Database.NOTES_TEXT));
        holder.time.setText(time);
        holder.date.setText(date);
        holder.text.setText(text);
        holder.card.setCardBackgroundColor(Color.parseColor(color));
    }
    @Override
    public int getItemCount() {
        return cursor.getCount();
    }
    public void rebuild() {
        cursor.requery();
        notifyDataSetChanged();
    }
    void initDeleteDialog(final int position) {
        AlertDialog.Builder cansel_add_note = new AlertDialog.Builder(context);
        cansel_add_note.setTitle("Подтверждение");
        cansel_add_note.setMessage("Удалить эту заметку?");
        cansel_add_note.setPositiveButton("ДА", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    activity.delete(position);
                }
        });
        cansel_add_note.setNegativeButton("НЕТ", new DialogInterface.OnClickListener(){
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
        });
        AlertDialog cansel = cansel_add_note.create();
        cansel.show();
    }
}

Метод delete в активности

void delete(int position){
    database.delete(Database.NOTES_TABLE, BaseColumns._ID +"=?", new String[]{Integer.toString(position)});
    notes_adapter.rebuild();
}
Answer 1

ID записей в БД и позиции в списке никак не связаны и работать с базой данных по позициям ни к чему хорошему в итоге не приведет. Вам нужно получать именно ID удаляемой из БД записи и работать с ним (только основные части вашего адаптера и где были изменения):

public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.AdapterHolder> {
    Cursor cursor;
    Context context;
    NotepadActivity activity;
    public class AdapterHolder extends RecyclerView.ViewHolder {
        TextView time, date, text;
        CardView card;
        ImageView edit, delete;
        AdapterHolder(View itemView) {
            super(itemView);
            time = (TextView)itemView.findViewById(R.id.note_item_time);
            date = (TextView)itemView.findViewById(R.id.note_item_date);
            text = (TextView)itemView.findViewById(R.id.note_text);
            card = (CardView)itemView;
            edit = (ImageView)itemView.findViewById(R.id.note_edit);
            delete = (ImageView)itemView.findViewById(R.id.note_delete);
        }
    }
    NotesAdapter(Cursor cursor, Context context) {
        this.cursor = cursor;
        this.context = context;
        this.activity = (NotepadActivity)context;
    }
    @Override
    public void onBindViewHolder(final AdapterHolder holder, int position) {
        cursor.moveToPosition(position);
        Long id = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
        String date = cursor.getString(cursor.getColumnIndex(Database.NOTES_DATE));
        String time = cursor.getString(cursor.getColumnIndex(Database.NOTES_TIME));
        String color = cursor.getString(cursor.getColumnIndex(Database.NOTES_COLOR));
        String text = cursor.getString(cursor.getColumnIndex(Database.NOTES_TEXT));
        holder.time.setText(time);
        holder.date.setText(date);
        holder.text.setText(text);
        holder.card.setCardBackgroundColor(Color.parseColor(color));
        holder.delete.setOnClickListener(new OnClickListener(){
          @Override
          public void onClick(View v) {
            initDeleteDialog(id);
          }
        });
    }
}

Я бы вообще передавал полученный ID через колбэк в активити и там уже выводил диалог удаления, вносил изменения в БД и обновлял адаптер.

Answer 2

Включил мозги и сделал так

1) Создал метод, который создаёт/пересоздает лист из id-шников 2) В качестве id удаляемой записи передаю id из этого листа по позиции 3) После удаления пересоздаю этот лист

READ ALSO
Ошибка в PreparedStatement

Ошибка в PreparedStatement

Использую ajax, для поискаВвожу несколько символов

295
JOGL OpenGL java Поворот матриц и glPushMatrix

JOGL OpenGL java Поворот матриц и glPushMatrix

собственно код вот такой

416
Изменение watermark itext7 java

Изменение watermark itext7 java

Необходимо с помощью библиотеки для JAVA iText 7 изменить Watemark (водный знак) на первой странице pdf файла, то есть имеется готовый pdf и в нем есть...

364
передать данные из Realm в RecyclerView

передать данные из Realm в RecyclerView

Получаю данные из json и записываю их в БД Realm, как мне их потом передать в RecyclerView ?

555