В действии "закусочной", как я могу быть уверен, что можно безвозвратно удалить мягко удаленную запись из базы данных?

Я использую Snackbar в android, и я внедрил действие, чтобы пользователь мог отменить действие (действие очищает все элементы в списке). Удаление и добавление элементов обратно в listview уже выполнено и работает хорошо.

Моя проблема в том, что элементы хранятся в базе данных sqlite и как я могу удалить элементы из таблиц? (Как я могу узнать, что пользователь не нажал кнопку отмены, так что я могу полностью удалить данные из базы данных).

Это код внутри OnOptionsItemSelcted()

case R.id.action_clear:
        final List<Word> temp = new ArrayList<Word>(data);
        data.clear();
        adapter.notifyDataSetChanged();
        View view = findViewById(R.id.layoutFavWords);
        Snackbar.make(view,"Deleted Saved Selection.", Snackbar.LENGTH_LONG).
        setAction("Undo", new OnClickListener() {

            @Override
            public void onClick(View v) {
                for(Word word:temp)
                    data.add(word);
                adapter.notifyDataSetChanged(); 
            }

        }).show();
        break;

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

Любые решения для этого?

Ответ 1

Насколько я знаю, это по замыслу. Вы должны:

  • Удалите элемент, как только пользователь нажмет кнопку "Удалить";
  • Временно сохраните его в переменной класса;
  • Если пользователь нажимает Отменить, снова добавьте элемент в базу данных.

Этот подход безопаснее и надежнее; вам не следует ждать, пока закусочная будет закрыта, потому что это действие не может даже произойти. Подумайте о том, чтобы пользователь принудительно вышел из приложения, когда снэк-бар еще включен: элемент должен быть удален или нет? Это должно.

Более заслуживающим доверия источником является сообщение g+ Иэна Лейка (удалено из-за устаревания g+). В комментариях вы можете прочитать:

Вы хотите, чтобы ваш пользовательский интерфейс реагировал немедленно (не ждите, пока исчезают) - большинство систем (особенно те, которые синхронизируются с внешним сервер) иметь понятие "мягкого удаления", где вещи помечены как удален. В этих случаях действие отмены будет просто запись как удаленная Эта система работает, даже если пользователь должен был уйти приложение до того, как закусочная заканчивается всегда завершит анимацию!).

Самый простой способ сделать это - временно сохранить запись в другом месте (даже в местном переменная), затем вставьте его снова, если они случайно нажали кнопку отмены.

Ответ 2

В библиотеку поддержки Android v23 добавлен Snackbar.Callback, который можно использовать для прослушивания, если снэк-бар был отклонен пользователем или истекло время ожидания.

Пример заимствован из сообщения astinx:

Snackbar.make(getView(), "Hi there!", Snackbar.LENGTH_LONG).setCallback( new Snackbar.Callback() {
            @Override
            public void onDismissed(Snackbar snackbar, int event) {
                switch(event) {
                    case Snackbar.Callback.DISMISS_EVENT_ACTION:
                        Toast.makeText(getActivity(), "Clicked the action", Toast.LENGTH_LONG).show();
                        break;
                    case Snackbar.Callback.DISMISS_EVENT_TIMEOUT:
                        Toast.makeText(getActivity(), "Time out", Toast.LENGTH_LONG).show();
                        break;
                }
            }

            @Override
            public void onShown(Snackbar snackbar) {
                Toast.makeText(getActivity(), "This is my annoying step-brother", Toast.LENGTH_LONG).show();
            }
        }).setAction("Go away!", new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        }).show();

Ответ 3

Пример:

final java.util.Timer timer = new Timer();
Snackbar snackbar = Snackbar.make(...).setAction("Undo", new OnClickListener() {
        @Override
        public void onClick(View v) {
            timer.cancel();
            for(Word word:temp)
                data.add(word);
            adapter.notifyDataSetChanged(); 
        }
    }).show();
timer.schedule(new TimerTask() {
    public void run() {
        // delete from db
    }
}, snackbar.getDuration());

Может быть, неплохо добавить немного к snackbar.getDuration() time (100-200ms?), поскольку таймеры не очень точны с точки зрения времени, и таким образом они могут быть вызваны непосредственно перед тем, как закусочная для закрытия, хотя в этом случае вероятность довольно мала.

Ответ 4

Если вы не хотите немедленно удалять запись из базы данных, попробуйте следующее:

// Backup the item for undo
int itemIndex = viewHolder.getAdapterPosition();
Item item = adapter.getItem(itemIndex);

// Delete only from the adapter
adapter.removeItem(itemIndex);

Snackbar.make(getView(), "Item deleted", LENGTH_LONG)
        .addCallback(new BaseCallback<Snackbar>() {
            public void onDismissed(Snackbar transientBottomBar, int event) {
                if (event != DISMISS_EVENT_ACTION) {
                    // Dismiss wasn't because of tapping "UNDO"
                    // so here delete the item from databse
                }
            }
        })
        .setAction("UNDO", v -> adapter.addItem(item, itemIndex))
        .show();

Ответ 5

Мой способ состоит в том, чтобы hv "удален" столбец, который является логическим, просто измените stat на true, если он удален, затем отмените, чтобы изменить обратно stat на false, также вы можете захотеть, чтобы контроллер мусора или планировщик удаляли все ложные значения каждую неделю.