【转载请注明出处】
笔者:DrkCore (http://blog.youkuaiyun.com/DrkCore)
原文链接:(http://blog.youkuaiyun.com/drkcore/article/details/53440392)
场景描述和思路分析
说到撤销和重做想必大家脑海中浮现的一定是 Ctrl+Z、Ctrl+Y 这两个快捷键,平常生产开发的时候也少不了要和这两个按键打交道。作为一个开发者笔者自然对其中的实现方法感到好奇,想必阅读此文的你也是一样的。
如果你稍微懂点数据结构并且有着基础的封装思想的话,大体都能想到一些思路:
将用户操作抽象成一个接口,接口包含 undo() 和 redo() 两个方法,并用栈来记录操作的顺序,通过出入栈和调用两个方法来处理撤销和重做的逻辑。
涉及到撤销和重做的大部分都是需要用户编辑的功能,如果你想在 Android 上基于 EditText 开发出一个文本编辑器的话,那么按照这个思路一步步实现肯定是没有问题的。
我们发现文本的编辑操作其实可以简化为插入、删除。用户选中文本后粘贴的操作,也就是替换,可以分解为删除选中文本后插入粘贴板内容。
接下来只要记录下输入和删除的操作就可以保存用户的操作了,这里我们可以使用 EditText 提供了 TextWatcher
用于监听文本变化。
接下来请看代码实现。
代码实现
首先我们需要实现编辑操作类,代码如下:
class EditOperation implements Parcelable, Serializable {
//原始内容,通常是被删除的部分
private String src;
private int srcStart;
private int srcEnd;
//目标内容,通常是输入的部分
private String dst;
private int dstStart;
private int dstEnd;
EditOperation setSrc(CharSequence src, int srcStart, int srcEnd) {
this.src = src != null ? src.toString() : "";
this.srcStart = srcStart;
this.srcEnd = srcEnd;
return this;
}
EditOperation setDst(CharSequence dst, int dstStart, int dstEnd) {
this.dst = dst != null ? dst.toString() : "";
this.dstStart = dstStart;
this.dstEnd = dstEnd;
return this;
}
void undo(EditText text) {