Android: EditText 기반 취소 및 재 작업 메커니즘 구현

26135 단어 Android
[전재 출처 밝 혀 주세요] 필자: DrkCore (http://blog.csdn.net/DrkCore) 원본 링크: (http://blog.csdn.net/drkcore/article/details/53440392)
장면 묘사 와 사고 분석
취소 와 재 작업 하면 여러분 의 머 릿 속 에 떠 오 르 는 것 은 반드시 Ctrl + Z, Ctrl + Y 라 는 두 개의 단축 키 입 니 다. 평소에 생산 개발 할 때 도 이 두 개의 버튼 과 접촉 하 는 것 이 빠 질 수 없습니다.개발 자로 서 필 자 는 자 연 스 럽 게 그 중의 실현 방법 에 대해 궁금 해 하 며 이 글 을 읽 은 당신 도 마찬가지 일 것 입 니 다.
만약 에 데이터 구 조 를 조금 알 고 기본 적 인 포장 사상 을 가지 고 있다 면 대체적으로 생각 이 떠 오 를 수 있다.
사용자 작업 을 하나의 인터페이스 로 추상 화하 고 인 터 페 이 스 는 undo () 와 redo () 두 가지 방법 을 포함 하 며 스 택 으로 작업 순 서 를 기록 하고 스 택 출입 과 호출 두 가지 방법 으로 취소 와 재 작업 의 논 리 를 처리 합 니 다.
취소 와 재 작업 과 관련 된 대부분 은 사용자 편집 이 필요 한 기능 입 니 다. 안 드 로 이 드 에서 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) {
        Editable editable = text.getText();
        
        int idx = -1;
        if (dstEnd > 0) {//      
            editable.delete(dstStart, dstEnd);
            
            if (src == null) {
                idx = dstStart;
            }
        }
        if (src != null) {//      
            editable.insert(srcStart, src);
            idx = srcStart + src.length();
        }
        if (idx >= 0) {//      
            text.setSelection(idx);
        }
    }
    
    void redo(EditText text) {
        Editable editable = text.getText();
        
        int idx = -1;
        if (srcEnd > 0) {//      
            editable.delete(srcStart, srcEnd);
            if (dst == null) {
                idx = srcStart;
            }
        }
        if (dst != null) {//      
            editable.insert(dstStart, dst);
            idx = dstStart + dst.length();
        }
        if (idx >= 0) {//      
            text.setSelection(idx);
        }
    }
}     

그 다음 에 저 희 는 사용자 가 텍스트 를 편집 할 때 해당 하 는 EditOperation 인 스 턴 스 를 생 성 해 야 합 니 다. 즉, 실현 TextWatcher 입 니 다.
public class OperationManager implements TextWatcher {
    
    private EditOperation opt;
    
    //    ,      /        
    private boolean enable = true;
    
    OperationManager disable() {
        enable = false;
        return this;
    }
    
    OperationManager enable() {
        enable = true;
        return this;
    }
    
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        if (count > 0) {
            int end = start + count;
            if (enable) {
                if (opt == null) {
                    opt = new EditOperation();
                }
                //      
                opt.setSrc(s.subSequence(start, end), start, end);
            }
        }
    }
    
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (count > 0) {
            int end = start + count;
            if (enable) {
                if (opt == null) {
                    opt = new EditOperation();
                }
                //      
                opt.setDst(s.subSequence(start, end), start, end);
            }
        }
    }
    
    @Override
    public void afterTextChanged(Editable s) {
        if (enable && opt != null) {
            if (!redoOpts.isEmpty()) {//              ,       
                redoOpts.clear();
            }
            //     
            undoOpts.push(opt);
        }
        opt = null;
    }
    
    //  LinkedList   
    private final LinkedList<EditOperation> undoOpts = new LinkedList<>();
    private final LinkedList<EditOperation> redoOpts = new LinkedList<>();
    
}

이후 의 취소 와 재 작업 은 매우 간단 하 다.
    public boolean undo() {
        if (canUndo()) {
            EditOperation undoOpt = undoOpts.pop();
            
            //         
            disable();
            undoOpt.undo(editText);
            enable();
            
            //     
            redoOpts.push(undoOpt);
            return true;
        }
        return false;
    }
    
    public boolean redo() {
        if (canRedo()) {
            EditOperation redoOpt = redoOpts.pop();
            
            //         
            disable();
            redoOpt.redo(editText);
            enable();
            
            //    
            undoOpts.push(redoOpt);
            return true;
        }
        return false;
    }

마지막 실현 효 과 는 그림 과 같다. Android:基于 EditText 实现撤销和重做机制_第1张图片
소스 코드 GitHub 로 이동 해 주세요.

좋은 웹페이지 즐겨찾기