如何使用 Snackbar 撤消操作绕过删除 SQLite 数据

How to Bypass Deleting SQLite Data Using Snackbar Undo Action

所以,我正在处理一个项目,我想从 RecyclerView 中删除一个项目,但我希望用户能够通过在 Snackbar 中按 "UNDO" 来恢复该项目。 RecyclerView 项目从 SQLite 数据库中提取它们的数据,当用户删除一个项目时,它将从 RecyclerView 和数据库中我的 table 的相应行中删除它。我的问题是我似乎无法弄清楚如何恢复已删除的数据(SQLite 数据)。

我试图在我的 DataBaseHelper class 中创建一个方法,该方法将位置作为参数,以便我的游标知道要访问哪一行,然后我使用游标将该行的所有值分配给 AlarmData (我的 setter 和 getter class)对象和 return 回到我的适配器 Class 所以我可以尝试恢复 table 的在我的 Snackbar 的 UNDO 操作方法中排。

代码如下:

DataBaseHelper.java

// Is public AlarmData even legal? that's my setter and getter class
// and the object type I'm trying to return

   public AlarmData recoverAlarms(int position) {

    AlarmData recoverData = new AlarmData();

    String ALARM_RESTORE_QUERY = "SELECT * FROM " + TABLE_ALARMS + " WHERE " + COLUMN_INDEX +
            " = " + position + ";";

    SQLiteDatabase db = getReadableDatabase();
    Cursor cursor = db.rawQuery(ALARM_RESTORE_QUERY, null);

    try {
        if (cursor.moveToFirst()) {
            do {

                recoverData.set_dispLabel(cursor.getString(cursor.getColumnIndex(COLUMN_LABEL)));
                recoverData.set_dispTime(cursor.getString(cursor.getColumnIndex(COLUMN_TIME)));
                recoverData.set_alarmId(cursor.getInt(cursor.getColumnIndex(COLUMN_INDEX)));

            } while (cursor.moveToNext());
        }
    } catch (Exception e) {
        throw e;
    } finally {
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
            db.close();
        }

    }

    return recoverData;
}

AlarmAdapter.java

   public void deleteAlarm(final int position, final View view) {

    final AlarmData recoverAlarmData = new DataBaseHelper(context, null, null, 1).recoverAlarms(position); //INITIALIZES VARIABLE TO THE OBJECT THAT'S RETURNED
    final AlarmData recoverItem = alarmData.get(position); //Recovers RecyclerView item (this works)
    final DataBaseHelper dataBaseHelper = new DataBaseHelper(context, null, null, 1);


    alarmData.remove(position);
    notifyItemRemoved(position);
    dataBaseHelper.deleteAlarms(position); //DELETES TABLE'S ROW

    Snackbar snackbar = Snackbar.make(view, "Alarm Removed", Snackbar.LENGTH_LONG)
            .setAction("UNDO", new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    alarmData.add(position, recoverItem);
                    notifyItemInserted(position); //RESTORES RECYCLERVIEW ITEM

                    dataBaseHelper.addAlarm(recoverAlarmData); //TRIES TO RECOVER TABLE

                }
            });

    snackbar.show();


}

澄清一下,我想知道如何在我的数据库中制作特定行的副本,以便在用户点击 Snackbar 上的 UNDO 时重新创建它。也可能向我解释我做错了什么。哈哈..

我希望我没有在这里表现得太多。非常感谢您的帮助。谢谢!

在问之前我可能应该多花点时间看看。我在这里找到了完美的解决方案:

显然 Snackbars 有很棒的回调方法,您可以覆盖。这是文档:https://developer.android.com/reference/android/support/design/widget/Snackbar.Callback.html

我只是使用 if 语句来检查 Snackbar 被解雇的原因是什么。我将出于任何原因删除我的 table 中的行,除非它的取消是对操作点击(当用户点击 "UNDO" 时)进行的。

我的代码:

报警适配器

        Snackbar snackbar = Snackbar.make(view, "Alarm Removed", Snackbar.LENGTH_LONG)
            .setAction("UNDO", new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    alarmData.add(position, recoverItem);
                    notifyItemInserted(position);

                }

            }).setCallback(new Snackbar.Callback() {
                @Override
                public void onDismissed(Snackbar snackbar, int dismissType) {
                    super.onDismissed(snackbar, dismissType);

                    if(dismissType == DISMISS_EVENT_TIMEOUT || dismissType == DISMISS_EVENT_SWIPE
                            || dismissType == DISMISS_EVENT_CONSECUTIVE || dismissType == DISMISS_EVENT_MANUAL)
                    dataBaseHelper.deleteAlarms(position);

                }
            });