В действии "закусочной", как я могу быть уверен, что можно безопасно удалить мягко удаленную запись из базы данных?
Я использую Snackbar в Android, и я реализовал действие, чтобы пользователь мог отменить действие (действие очищает все элементы в просмотре списка). Удаление и добавление элементов обратно в просмотр списка уже было сделано и работает нормально.
Моя проблема в том, что элементы хранятся в базе данных 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;
Так что, если пользователь не нажал кнопку отмены в течение видимого периода снэк-бара, то мне нужно окончательно удалить данные из базы данных.
Какие-нибудь решения для этого?
3 ответа
Насколько я знаю, это по замыслу. Вам следует:
- Удалить элемент, как только пользователь нажмет кнопку "Удалить";
- Сохраните его временно в переменной класса;
- Если пользователь нажимает Отменить, снова добавьте элемент в базу данных.
Этот подход безопаснее и надежнее; Вы не должны ждать, пока закусочная будет закрыта, потому что это действие не может даже произойти. Подумайте о том, чтобы пользователь принудительно вышел из приложения, когда снэк-бар еще включен: элемент должен быть удален или нет? Должно.
Более достоверным источником является этот пост G + Ian Lake. В комментариях вы можете прочитать:
вы хотите, чтобы ваш пользовательский интерфейс реагировал немедленно (не дожидаясь исчезновения снэк-бара) - большинство систем (особенно те, которые синхронизируются с внешним сервером) имеют концепцию "мягкого удаления", когда объекты помечаются как удаленные. В этих случаях действие отмены будет просто пометить запись как удаленную. Эта система работает, даже если пользователь должен был покинуть приложение до того, как закусочная закончила работу (вы не можете предполагать, что закусочная всегда будет завершать анимацию!).
Самый простой способ сделать это - временно сохранить запись в другом месте (даже в локальной переменной), а затем снова вставить ее, если они случайно нажмут кнопку отмены.
В библиотеку поддержки 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();
Пример:
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() (100-200 мс?), Так как таймеры не очень точны с точки зрения времени и, таким образом, они могут быть вызваны непосредственно перед тем, как закусочная собирается закрыться, Хотя в этом случае вероятность довольно мала.
Если вы не хотите немедленно удалять запись из базы данных, попробуйте это:
// 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();
Мой способ состоит в том, чтобы hv "удален" столбец, который является логическим, просто измените stat на true, если он удален, затем отмените, чтобы изменить обратно stat на false, также вы можете захотеть, чтобы контроллер мусора или планировщик удаляли все ложные значения каждую неделю.