In a snackbar action, how can I be sure it's safe to permanently delete a soft-deleted record from the database?

梦想与她 提交于 2019-12-03 02:38:45
natario

As far as I know, it is by design. You should:

  • Delete the item as soon as the user taps the delete button;
  • Store it temporarily in a class variable;
  • If the user taps Undo, add the item again to the database.

This approach is safer and more robust; you shouldn't wait for the snackbar to be dismissed, because that action could not even happen. Just think of user force-quitting the app while the snackbar is still on: should the item be deleted or not? It should.

A more trustworthy source is g+ post by Ian Lake (deleted because of G+ deprecation). In the comments you can read:

you want your UI to react immediately (not wait for the snackbar to disappear) - most systems (particularly those that sync to an external server) have the concept of a 'soft delete' where things are marked as deleted. In those cases, an undo action would just be unmarking the record as deleted. This system works even if the user were to leave the app before the snackbar finishes (you can't assume the snackbar will always complete its animation!).

The easiest way to do that is to temporarily save the record elsewhere (even a local variable), then re-insert it if they happen to hit the undo button.

Irritator

Android Support library v23 added Snackbar.Callback which you can use to listen if the snackbar was dismissed by user or timeout.

Example borrowed from astinxs post:

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

Example:

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

It may be a good idea to add a little to the snackbar.getDuration() time (100-200ms?) as timers are not very exact in terms of timing and this way they may get called just before the snackbar is about to close, althought the possibility is rather small in this case.

If you don't want to delete the record from database immediately, try this:

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

My way is to hv "deleted" column that is boolean, just change the stat to be true if deleted then undo to change back stat to be false, also u maybe want trash controller or scheduler to delete all the false values on every week.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!