2016-05-26 6 views
0

プロジェクトで作業していますが、RecyclerViewからアイテムを削除したいのですが、そのアイテムを復元するには、「UNDO」をスナックバー。 RecyclerViewアイテムはSQLiteデータベースからデータを取り出しています。ユーザーがアイテムを削除すると、RecyclerViewとそれに対応するデータベースのテーブルの行が削除されます。私の問題は、削除されたデータ(SQLiteデータ)をどのように回復するのか分からないようです。Snackbarを使用してSQLiteデータを削除する方法を取り消します。

DataBaseHelperクラスのメソッドを作成して位置をパラメータとして取得しようとしました。カーソルがアクセスする行を認識してからカーソルを使用して、その行のすべての値をAlarmDataに割り当てました(my setterとgetterクラスのオブジェクトを取得し、アダプタクラスに戻して、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(); 


} 

だけclairifyする、私は私が作ることができる方法を知りたいです私のデータベースの特定の行のコピーを作成して、ユーザーがSnackbarでUNDOをヒットしたときに再作成することができます。また私が間違っていることを私に説明するかもしれません。笑。

私はここで私のnoobishnessをあまり示していないことを願っています。あなたの助けに感謝します。ありがとうございました!

+0

私は、これは通常行われている方法を知っているが、何、それを削除しませ程度ませんか?あなたがテーブルを "0"(非アクティブ)として設定したフィールドを削除したときにテーブルに 'active'カラムを追加し、それを元に戻すと' active 'の値を1に戻します。あなたのrecyclerviewでは、 'active'要素のみを表示します。他の質問は、しばらくしてから非アクティブなアイテムを削除する方法です。 –

+0

snak barを表示してリサイクラビューを更新するだけで、実際にdeleteメソッドを実行することはできません。スナックバーが消えるか、使用が取り消されるまでしばらく時間をおいてください。ヒットの使用を取り消す場合は、アイテムをrecyclerviewに挿入し、アダプターに変更を通知します。スナップバーがユーザーインタラクションなしで消えてしまった場合、新しいスレッドでデータベースを必要に応じて変更します。 –

+0

テーブル名にisDeletedタイプのブール値として列を追加できます。 **ハード削除**適用**ソフト削除**はテーブルから項目を削除しない**更新クエリを作成する**ユーザーが削除した場合はTRUE、元に戻す場合はFALSEを指定します。 UN-Deletedデータのみを表示します。 Falseフラグのデータだけをフェッチするクエリを作成します。 –

答えて

1

私はたぶん、質問する前にもう少し時間を過ごしていたはずです。私はここで完璧なソリューションを見つけました:How can I be notified when a Snackbar has dismissed itself?

どうやらSnackbarsはオーバーライドできる素晴らしいコールバックメソッドを持っています。 https://developer.android.com/reference/android/support/design/widget/Snackbar.Callback.html

私は単純にifステートメントを使用して、Snackbarの解雇の理由を確認します。私のテーブル内の行を削除する場合は、除外がアクションクリック(ユーザーが「UNDO」に当たったとき)の場合以外は何らかの理由で削除されます。

マイコード:

AlarmAdapter

 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); 

       } 
      }); 
+1

これを 'if(dismissType!= DISMISS_EVENT_ACTION)'に単純化することができます。 – Sumit

関連する問題