如何撤消/重做最后一次触摸动作

时间:2011-03-01 15:52:44

标签: android undo-redo

我有一个正在处理的图像,我有两个按钮,撤消和重做。如果单击这两个按钮中的任何一个,我需要代码撤消/重做上一个触摸操作。我知道我必须使用堆栈。我该如何实施呢?

3 个答案:

答案 0 :(得分:7)

实现撤消/重做有两种主要模式:

  1. “纪念品”模式。
  2. “命令”模式。
  3. 1。 Memento Pattern

    memento模式的想法是你可以保存一个对象的整个内部状态的副本(不违反封装)以便以后恢复。

    它会像(例如)这样使用:

    // Create your object that can be "undone"
    ImageObject myImage = new ImageObject()
    
    // Save an "undo" point.
    var memento = myImage.CreateMemento();
    
    // do a bunch of crazy stuff to the image...
    // ...
    
    // Restore to a previous state.
    myImage.SetMemento(memento);
    

    2。 Command Pattern

    命令模式的想法是封装实际对对象执行的操作。每个“动作”(或“命令”)可以选择性地知道如何回滚。或者,当需要进行回滚时,可以再次执行整个命令链。

    它会像(例如)这样使用:

    // Create your object that can be "undone"
    ImageObject myImage = new ImageObject()
    
    // Create a "select all" command
    var command = new SelectAllCommand(myImage);  // This does not actually execute the action.
    
    // Apply the "select all" command to the image
    selectAll.Execute();  // In this example, the selectAll command would "take note" of the selection that it is overwriting.
    
    // When needed, rollback:
    selectAll.Rollback();  // This would have the effect of restoring the previous selection.
    

答案 1 :(得分:4)

这一切都取决于您的触摸事件首先在做什么。你必须抽象你的应用程序做什么来响应你可以填充堆栈的类的触摸。然后,堆栈实现很容易。

如果是图像处理,可能会占用太多内存来保留一堆Bitmaps。将两个或三个项目推入堆栈后,您可能会得到臭名昭着的OutOfMemoryException。您可能最好做的是抽象应用程序中可用的操作并在撤消/重做时重建。你基本上是在创建一堆指令集。这使得堆栈越大越慢,但如果内存中的图像很大,则可能是唯一的方法。

答案 2 :(得分:0)

在较新的Android版本(22+)中,您可以使用Snackbar。这是侦听器的小代码片段:

public class MyUndoListener implements View.OnClickListener{

    &Override
    public void onClick(View v) {

        // Code to undo the user's last action
    }
}

并在屏幕底部创建一条消息,以便"撤消"动作:

Snackbar mySnackbar = Snackbar.make(findViewById(R.id.myCoordinatorLayout),
                                R.string.email_archived, Snackbar.LENGTH_SHORT);
mySnackbar.setAction(R.string.undo_string, new MyUndoListener());
mySnackbar.show();