2014-02-09 13 views
1

사용자 지정 드로잉보기 응용 프로그램에서 undo, redo 옵션을 만들려고합니다. 하지만 내가 원하는대로 작동하지 않습니다.사용자 지정 드로잉 뷰에서 실행 취소 및 다시 실행 옵션이 작동하지 않습니다.

영어가 좋지 않습니다. 그림을 통해 undo, redo 기능을 보여 주려고합니다. 희망, 그래서이 그림은 내 문제를 설명합니다. enter image description here

첫 번째 줄에서 첫 번째 줄을 제거하고 두 번째 줄에서 두 번째 줄을 지우고 싶을 때 등등 ... 마찬가지로 다시 실행을 클릭하면 마지막 줄을 첫 번째 클릭에서 그리기, 두 번째로 두 번째 클릭에서 끝내기 등등 ..

내 사용자 정의보기 클래스입니다. 이미지를 변경하지 않는 목록에서 그것을 복용, 즉 - 당신은 때 "실행 취소"캔버스에 "다시 그립니다"되지

public class DrawingView extends View{ 

    ArrayList<Path> undoPath = new ArrayList<Path>(); 
    ArrayList<Path> paths = new ArrayList<Path>(); 
    private static int pathSize =0; 
    //draw path 
    private Path drawPath; 
    //drawing and canvas point 
    private Paint drawPaint, canvasPaint; 
    //initial color 
    private int paintColor=0xFF660000; 
    //canvas 
    private Canvas drawCanvas; 
    //canvas bitmap 
    private Bitmap canvasBitmap; 

    private float brushSize, lastBrushSize; 

    public DrawingView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setupDrawing(); 
    } 
    public void setPattern(String newPattern){ 
     invalidate(); 
     int patternID = getResources().getIdentifier(newPattern, "drawable", "com.faisalahsan.paintingapp"); 
     Bitmap patternBMP = BitmapFactory.decodeResource(getResources(), patternID); 
     BitmapShader patternBMPShader = new BitmapShader(patternBMP, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); 
     drawPaint.setColor(0xFFFFFFFF); 
     drawPaint.setShader(patternBMPShader); 

    } 
    private void setupDrawing(){ 
     //get drawing area setup for interaction 
     drawPath = new Path(); 
     drawPaint= new Paint(); 

     paths.add(drawPath); 

     brushSize = getResources().getInteger(R.integer.medium_size); 
     lastBrushSize = brushSize; 

     drawPaint.setColor(paintColor); 
     drawPaint.setAntiAlias(true); 
     drawPaint.setStrokeWidth(brushSize); 
     drawPaint.setStyle(Paint.Style.STROKE); 
     drawPaint.setStrokeJoin(Paint.Join.ROUND); 
     drawPaint.setStrokeCap(Paint.Cap.ROUND); 

     canvasPaint = new Paint(Paint.DITHER_FLAG);  
    } 

    @Override 
    protected void onDraw(Canvas canvas) {   
     for(Path p: paths){   
      canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint); 
      canvas.drawPath(p, drawPaint);   
     } 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
     super.onSizeChanged(w, h, oldw, oldh); 
     canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     drawCanvas = new Canvas(canvasBitmap); 

    } 

    public void onClickUndo() { 
     if (paths.size()>0) { 
     undoPath.add(paths.remove(paths.size()-1));   
     invalidate(); 
     }   
     } 

     public void onClickRedo(){ 
     if (undoPath.size()>0) { 
     paths.add(undoPath.remove(undoPath.size()-1));   
     invalidate(); 
     } 
     } 


    @Override 
    public boolean onTouchEvent(MotionEvent event) { 

     float touchX = event.getX(); 
     float touchY = event.getY(); 

     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      drawPath.moveTo(touchX, touchY); 
      break;   
     case MotionEvent.ACTION_MOVE: 
      drawPath.lineTo(touchX, touchY);    
      break; 
     case MotionEvent.ACTION_UP: 
      drawCanvas.drawPath(drawPath, drawPaint); 
      drawPath.reset(); 
      drawPath = new Path(); 
      paths.add(drawPath); 
      break; 
     default: 
      return false; 
     } 
     invalidate(); 
     return true;   
    } 
} 

답변

0

는 ArrayList를 "경로"에서 작업을 제거합니다. 작업을 "실행 취소"하기 위해 그리기 전에 캔버스에 있던 것을 다시 그려야합니다.

"onDraw"가 시작될 때 캔버스의 상태를 저장하고 실행 취소가 호출 될 때 해당 캔버스를 다시 그립니다. 일련의 "실행 취소"및 "다시 실행"호출을 수행하려면 캔버스 상태의 동기화 된 스택을 유지해야합니다.

+0

예를 들어 어떤 종류의 코드 나 코드를 도와 주시겠습니까 ?? – FAISAL

+0

이것에 읽는 : http://stackoverflow.com/questions/3973557/how-to-implement-undo-redo-operation-without-major-changes-in-program?rq=1 당신은 "스택" (당신은 "명령"을 추적하고 있지만 동작 스택은 아닙니다 ... 메모리상의 이유로 각 비트 맵의 ​​캐시 된 버전이 필요할 것입니다. 그래서 ArrayList bitmaps = new ArrayList (); 각 변경합니다.하지만 당신은 단지 몇 가지 "실행 취소"옵션 이상에 대한 캐싱이 필요합니다. 그럼 "재실행"에 대한 또 다른 ArrayList가 필요해 redoBitmaps – Jim