在小吃栏操作中,如何确保永久删除数据库中的软删除记录是安全的?

cha*_*ura 20 java android android-support-library snackbar android-design-library

我在android中使用Snackbar并且我已经实现了一个动作,以便用户可以撤消动作(动作是清除列表视图中的所有项目).将项目恢复并添加回列表视图已经完成并且工作正常.

我的问题是,项目存储在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;
Run Code Online (Sandbox Code Playgroud)

因此,如果用户在快餐栏的可见时段内没有单击撤消按钮,那么我需要从数据库中永久删除数据.

对此有何解决方案?

nat*_*rio 29

据我所知,它是设计的.你应该:

  • 用户点击删除按钮后立即删除该项目;
  • 暂时将其存储在类变量中;
  • 如果用户点击"撤消",请再次将该项添加到数据库中.

这种方法更安全,更健壮; 你不应该等待快餐店被解雇,因为这种行为甚至都不会发生.只需考虑用户强制退出应用程序,同时小吃栏仍然打开:该项目是否应删除?这应该.

一个更值得信赖的消息来源是伊恩湖的这篇文章.在评论中,您可以阅读:

您希望您的UI立即做出反应(不要等待零食栏消失) - 大多数系统(特别是同步到外部服务器的系统)都具有"软删除"的概念,其中事物被标记为已删除.在这些情况下,撤消操作只是将记录取消标记为已删除.即使用户在小吃店结束之前离开应用程序,该系统仍然有效(您不能认为小吃店将始终完成其动画!).

最简单的方法是暂时将记录保存在别处(甚至是局部变量),然后在碰巧按下撤销按钮时重新插入.

  • 在强制退出的情况下,如果用户想要撤消该怎么办?最好在发生故障的情况下获得数据,因为用户再次删除只是轻微的删除,但是再次创建数据将不会相对容易,并且在某些情况下例如在数据具有一些传感器读数的情况下是不可能的.当然UI应该立即做出反应,就像在我的情况下,我有两个集合,一个用于项目,一个用于垃圾.所以该项目被移动到垃圾箱.数据库更新将在以后进行,与每次更改的数据库操作相比,UI的工作速度很快. (4认同)

小智 10

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();
Run Code Online (Sandbox Code Playgroud)


wfr*_*zyk 6

例子:

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());
Run Code Online (Sandbox Code Playgroud)

添加一点到snackbar.getDuration() 时间(100-200ms?)可能是个好主意,因为计时器在时间方面不是很精确,这样它们可能会在snackbar 即将关闭之前被调用,虽然在这种情况下可能性很小。