我在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;
因此,如果用户在快餐栏的可见时段内没有单击撤消按钮,那么我需要从数据库中永久删除数据。
对此有何解决方案?
据我所知,这是设计的。你应该:
这种方法更安全,更健壮;你不应该等待快餐店被解雇,因为这种行为甚至都不会发生。只需考虑用户强制退出应用程序,同时小吃栏仍然打开:该项目是否应删除?这应该。
一个更值得信赖的来源是Ian Lake的this g+ post。在评论中,您可以阅读:
您希望您的UI立即做出反应(不要等待零食栏消失) - 大多数系统(特别是同步到外部服务器的系统)都具有“软删除”的概念,其中事物被标记为已删除。在这些情况下,撤消操作只是将记录取消标记为已删除。即使用户在小吃店结束之前离开应用程序,该系统仍然有效(您不能认为小吃店将始终完成其动画!)。
最简单的方法是暂时将记录保存在别处(甚至是局部变量),然后在碰巧按下撤销按钮时重新插入。
Android支持库v23添加了Snackbar.Callback,如果小吃栏被用户解雇或超时,您可以使用它来监听。
借用astinxs帖子的例子:
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-200ms?)上添加一点可能是一个好主意,因为定时器在时间上不是很精确,这样它们可能会在快餐栏即将关闭之前被调用,虽然在这种情况下可能性相当小。
如果您不想立即从数据库中删除记录,请尝试以下操作:
// 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,也可能希望垃圾控制器或调度程序删除每周的所有错误值。