Появляются удаленные данные из БД SQL

У меня происходит какая-то магия. Я в адаптере удаляю элемент из БД, вывожу таблицу в Log, элемент удалился. Потом перезапускаю фрагмент, в котором находится адаптер, и каким-то магическим образом удаленный элемент снова появляется в БД(таблицу также вывожу в Log), в коде есть пометки тех мест, в которых я вывожу Бд в Log.

Фрагмент:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);

        imageButton = view.findViewById(R.id.imageButton);
        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getContext(), AddElement.class);
                startActivity(intent);
            }
        });

        dbHelper = new DBHelper(getContext());

        recyclerView = view.findViewById(R.id.recyclerView);
        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);
        RecyclerView.ItemDecoration divider = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
        recyclerView.addItemDecoration(divider);

        return view;
    }

    @Override
    public void onStart() {
        super.onStart();
//Вывожу БД в Log и в ней уже есть запись:( (Беру контекст - getContext)
        adapter = new MultiTypeTaskAdapter(dbHelper.elementsHome(),
                MultiTypeTaskAdapter.PARENT_HOME, getContext());
        recyclerView.setAdapter(adapter);
    }

Адаптер:(удаление элементов в самом низу)

    public MultiTypeTaskAdapter(List<? extends ExpandableGroup> groups,
                                int parent, Context context) {
        super(groups);
        this.groups = groups;
        this.parent = parent;
        this.context = context;
    }

    class TaskViewHolder extends GroupViewHolder {

        private int viewType;
        private CheckBox checkBox;
        private TextView tvTask, date;
        private Button buttonComment;
        private ImageButton imageButton;
        private ImageView arrow;

        public TaskViewHolder(View itemView, int viewType) {
            super(itemView);
            this.viewType = viewType;

            tvTask = itemView.findViewById(R.id.task);

            switch (viewType){
                case MultiTypeTaskAdapter.TYPE_IS_COMMENT_IS_SUBTASKS:
                    checkBox = itemView.findViewById(R.id.checkBox);
                    arrow = itemView.findViewById(R.id.arrow);
                    date = itemView.findViewById(R.id.date);
                    imageButton = itemView.findViewById(R.id.imageButton);
                    buttonComment = itemView.findViewById(R.id.button);
                    break;
                case MultiTypeTaskAdapter.TYPE_IS_COMMENT_ISNT_SUBTASKS:
                    checkBox = itemView.findViewById(R.id.checkBox);
                    date = itemView.findViewById(R.id.date);
                    imageButton = itemView.findViewById(R.id.imageButton);
                    buttonComment = itemView.findViewById(R.id.button);
                case MultiTypeTaskAdapter.TYPE_ISNT_CHECKBOX_IS_COMMENT_ISNT_SUBTASKS:
                    date = itemView.findViewById(R.id.date);
                    imageButton = itemView.findViewById(R.id.imageButton);
                    buttonComment = itemView.findViewById(R.id.button);
                    break;
                case MultiTypeTaskAdapter.TYPE_ISNT_COMMENT_ISNT_SUBTASKS:
                    checkBox = itemView.findViewById(R.id.checkBox);
                    date = itemView.findViewById(R.id.date);
                    imageButton = itemView.findViewById(R.id.imageButton);
                case MultiTypeTaskAdapter.TYPE_ISNT_CHECKBOX_ISNT_COMMENT_ISNT_SUBTASKS:
                    date = itemView.findViewById(R.id.date);
                    imageButton = itemView.findViewById(R.id.imageButton);
                    break;
                case MultiTypeTaskAdapter.TYPE_ISNT_COMMENT_IS_SUBTASKS:
                    checkBox = itemView.findViewById(R.id.checkBox);
                    arrow = itemView.findViewById(R.id.arrow);
                    date = itemView.findViewById(R.id.date);
                    imageButton = itemView.findViewById(R.id.imageButton);
                    break;
                case MultiTypeTaskAdapter.TYPE_ISNT_CHECKBOX_ISNT_COMMENT_IS_SUBTASKS:
                    arrow = itemView.findViewById(R.id.arrow);
                    date = itemView.findViewById(R.id.date);
                    imageButton = itemView.findViewById(R.id.imageButton);
                    break;
            }
        }

        public void bind(final Task task, int viewType, final int parent){
            tvTask.setText(task.task);
            date.setText(task.dateString);

            imageButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    DBHelper dbHelper = new DBHelper(v.getContext());
                    ArrayList<Long> id = new ArrayList<>();
                    for (int i = 0; i < task.subtasks.size(); i++)
                        id.add(task.subtasks.get(i).id);

                    switch (parent){
                        case MultiTypeTaskAdapter.PARENT_HOME:
                            dbHelper.deleteHomeTask(task.id);
                            dbHelper.deleteSubtasks(id);
                            remove(getAdapterPosition());
                            break;
                        case MultiTypeTaskAdapter.PARENT_COMPLETED:
                            dbHelper.deleteCompleteTask(task.id);
                            dbHelper.deleteSubtasks(id);
                            remove(getAdapterPosition());
                            break;
                        case MultiTypeTaskAdapter.PARENT_FAILED:
                            dbHelper.deleteFaildTask(task.id);
                            dbHelper.deleteSubtasks(id);
                            remove(getAdapterPosition());
                            break;
                        case MultiTypeTaskAdapter.PARENT_PLANNED:
                            dbHelper.deletePlannedTask(task.id);
                            dbHelper.deleteSubtasks(id);
                            remove(getAdapterPosition());
                            break;
                    }
// Делаю здесь вывод БД в Log, запись удалилась (Беру контекст - v)
                }
            });

        public void remove(int position){
            groups.remove(position);
            notifyDataSetChanged();
        }

DBHelper:

public class DBHelper extends SQLiteOpenHelper {

    public DBHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table " + TABLE_HOME + "(" + COLUMN_ID + " Long primary key," +
                COLUMN_TASK + " text," + COLUMN_COMMENT + " text," + COLUMN_DATE_STRING + " text," +
                COLUMN_DATE_START + " long," + COLUMN_DATE_FINISH + " long" + ")");

        db.execSQL("create table " + TABLE_COMPLETE + "(" + COLUMN_ID + " Long primary key," +
                COLUMN_TASK + " text," + COLUMN_COMMENT + " text," + COLUMN_DATE_STRING + " text," +
                COLUMN_DATE_START + " long," + COLUMN_DATE_FINISH + " long" + ")");

        db.execSQL("create table " + TABLE_FAILED + "(" + COLUMN_ID + " Long primary key," +
                COLUMN_TASK + " text," + COLUMN_COMMENT + " text," + COLUMN_DATE_STRING + " text," +
                COLUMN_DATE_START + " long," + COLUMN_DATE_FINISH + " long" + ")");

        db.execSQL("create table " + TABLE_PLANNED + "(" + COLUMN_ID + " Long primary key," +
                COLUMN_TASK + " text," + COLUMN_COMMENT + " text," + COLUMN_DATE_STRING + " text," +
                COLUMN_DATE_START + " long," + COLUMN_DATE_FINISH + " long" + ")");

        db.execSQL("create table " + TABLE_SUBTASKS + "(" + COLUMN_ID + " Long primary key," +
                COLUMN_SUBTASKS + " text," + COLUMN_CHECKED + " boolean," +
                COLUMN_KEY + " text" + ")"); // COLUMN_KEY = PARENT TASK NAME
    }

    public ArrayList<Task> elementsHome(){
        String sql = "select * from " + TABLE_HOME;
        SQLiteDatabase db = this.getReadableDatabase();
        ArrayList<Task> tempElements = new ArrayList<>();
        Cursor cursor = db.rawQuery(sql, null);
        if(cursor.moveToFirst()){
            do{
                Long id = cursor.getLong(cursor.getColumnIndex(COLUMN_ID));
                String task = cursor.getString(cursor.getColumnIndex(COLUMN_TASK));
                String comment = cursor.getString(cursor.getColumnIndex(COLUMN_COMMENT));
                String dateString = cursor.getString(cursor.getColumnIndex(COLUMN_DATE_STRING));
                Long dateStart = cursor.getLong(cursor.getColumnIndex(COLUMN_DATE_START));
                Long dateFinish = cursor.getLong(cursor.getColumnIndex(COLUMN_DATE_FINISH));
                ArrayList<Subtask> subtasks = elementsSubtask(task);
                tempElements.add(new Task(id, task, comment, dateString,
                        dateStart, dateFinish, subtasks));
            }while (cursor.moveToNext());
        }
        cursor.close();
        return tempElements;
    }

    public ArrayList<Task> elementsComplete(){
        String sql = "select * from " + TABLE_COMPLETE;
        SQLiteDatabase db = this.getReadableDatabase();
        ArrayList<Task> tempElements = new ArrayList<>();
        Cursor cursor = db.rawQuery(sql, null);
        if(cursor.moveToFirst()){
            do{
                Long id = cursor.getLong(cursor.getColumnIndex(COLUMN_ID));
                String task = cursor.getString(cursor.getColumnIndex(COLUMN_TASK));
                String comment = cursor.getString(cursor.getColumnIndex(COLUMN_COMMENT));
                String dateString = cursor.getString(cursor.getColumnIndex(COLUMN_DATE_STRING));
                Long dateStart = cursor.getLong(cursor.getColumnIndex(COLUMN_DATE_START));
                Long dateFinish = cursor.getLong(cursor.getColumnIndex(COLUMN_DATE_FINISH));
                ArrayList<Subtask> subtasks = elementsSubtask(task);
                tempElements.add(new Task(id, task, comment, dateString,
                        dateStart, dateFinish, subtasks));
            }while (cursor.moveToNext());
        }
        cursor.close();
        return tempElements;
    }

    public ArrayList<Task> elementsFailed(){
        String sql = "select * from " + TABLE_FAILED;
        SQLiteDatabase db = this.getReadableDatabase();
        ArrayList<Task> tempElements = new ArrayList<>();
        Cursor cursor = db.rawQuery(sql, null);
        if(cursor.moveToFirst()){
            do{
                Long id = cursor.getLong(cursor.getColumnIndex(COLUMN_ID));
                String task = cursor.getString(cursor.getColumnIndex(COLUMN_TASK));
                String comment = cursor.getString(cursor.getColumnIndex(COLUMN_COMMENT));
                String dateString = cursor.getString(cursor.getColumnIndex(COLUMN_DATE_STRING));
                Long dateStart = cursor.getLong(cursor.getColumnIndex(COLUMN_DATE_START));
                Long dateFinish = cursor.getLong(cursor.getColumnIndex(COLUMN_DATE_FINISH));
                ArrayList<Subtask> subtasks = elementsSubtask(task);
                tempElements.add(new Task(id, task, comment, dateString,
                        dateStart, dateFinish, subtasks));
            }while (cursor.moveToNext());
        }
        cursor.close();
        return tempElements;
    }

    public ArrayList<Task> elementsPlanned(){
        String sql = "select * from " + TABLE_PLANNED;
        SQLiteDatabase db = this.getReadableDatabase();
        ArrayList<Task> tempElements = new ArrayList<>();
        Cursor cursor = db.rawQuery(sql, null);
        if(cursor.moveToFirst()){
            do{
                Long id = cursor.getLong(cursor.getColumnIndex(COLUMN_ID));
                String task = cursor.getString(cursor.getColumnIndex(COLUMN_TASK));
                String comment = cursor.getString(cursor.getColumnIndex(COLUMN_COMMENT));
                String dateString = cursor.getString(cursor.getColumnIndex(COLUMN_DATE_STRING));
                Long dateStart = cursor.getLong(cursor.getColumnIndex(COLUMN_DATE_START));
                Long dateFinish = cursor.getLong(cursor.getColumnIndex(COLUMN_DATE_FINISH));
                ArrayList<Subtask> subtasks = elementsSubtask(task);
                tempElements.add(new Task(id, task, comment, dateString,
                        dateStart, dateFinish, subtasks));
            }while (cursor.moveToNext());
        }
        cursor.close();
        return tempElements;
    }

    public ArrayList<Subtask> elementsSubtask(String key) {
        ArrayList<Subtask> tempElements = new ArrayList<>();

        SQLiteDatabase db = this.getReadableDatabase();
        String[] selectionArgs = new String[] {key};
        Cursor cursor = db.query(TABLE_SUBTASKS, null,
                "column_key = ?", selectionArgs, null, null, null);

        if (cursor.moveToFirst()) {
            do {
                tempElements.add(new Subtask(cursor.getLong(cursor.getColumnIndex(COLUMN_ID)),
                        cursor.getString(cursor.getColumnIndex(COLUMN_SUBTASKS))));
            } while (cursor.moveToNext());
        }
        cursor.close();
        return tempElements;
    }

    public void deleteHomeTask(Long id){
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_HOME, COLUMN_ID + " = ?", new String[] { String.valueOf(id)});
    }

    public void deleteCompleteTask(Long id){
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_COMPLETE, COLUMN_ID + " = ?", new String[] { String.valueOf(id)});
    }

    public void deleteFaildTask(Long id){
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_FAILED, COLUMN_ID   + " = ?", new String[] { String.valueOf(id)});
    }

    public void deletePlannedTask(Long id){
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_PLANNED, COLUMN_ID  + " = ?", new String[] { String.valueOf(id)});
    }

    public void deleteSubtasks(ArrayList<Long> id){
        SQLiteDatabase db = this.getWritableDatabase();
        for (int i = 0; i < id.size(); i++) {
            db.delete(TABLE_SUBTASKS, COLUMN_ID + " = ?",
                    new String[]{String.valueOf(id.get(i))});
        }
    }
}

Ответы (1 шт):

Автор решения: Barmaley Red Star

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

К сожалению у RecyclerView нет из коробки адаптера над Cursor, но есть сторонние реализации, например этот

Или погуглите с ключевыми словами RecyclerView cursor adapter

→ Ссылка