首页 文章

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

提问于
浏览
16

我在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;

So if the user has not clicked the undo button during the visible period of the snackbar, then I need to permanently delete the data from database.

对此有何解决方案?

4 回答

  • 7

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

    • 用户点击删除按钮后立即删除该项目;

    • 暂时将其存储在类变量中;

    • 如果用户点击撤消,请再次将该项添加到数据库 .

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

    伊恩湖的一个更值得信赖的来源是this g+ post . 在评论中,您可以阅读:

    您希望您的UI立即做出反应(而不是等待零食栏消失) - 大多数系统(特别是同步到外部服务器的系统)具有“软删除”的概念,其中事物被标记为已删除 . 在这些情况下,撤消操作只是将记录取消标记为已删除 . 即使用户在小吃店结束之前离开应用程序,该系统仍然有效(您不能认为小吃店将始终完成其动画!) . 最简单的方法是暂时将记录保存在别处(甚至是局部变量),然后在碰巧按下撤销按钮时重新插入 .

  • 4

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

    例:

    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-200ms?)上添加一点可能是一个好主意,因为定时器在时间上不是很精确,这样它们可能会在快餐栏即将关闭之前被调用,虽然在这种情况下可能性相当小 .

  • 0

    如果您不想立即从数据库中删除记录,请尝试以下操作:

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

相关问题