如何执行在表面观撤销重做 [英] How to perform undo redo on surface view

查看:163
本文介绍了如何执行在表面观撤销重做的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前在表面观努力绘制目的,但我面临着我不是使用命令图案表面视图执行撤消重做操作的问题。如果有任何人知道这件事的话,请帮助。

我的code是XML。

 < LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
的xmlns:工具=htt​​p://schemas.android.com/tool​​s
机器人:layout_width =FILL_PARENT
机器人:layout_height =FILL_PARENT
机器人:方向=垂直><的FrameLayout
     机器人:ID =@ + ID /的FrameLayout
     机器人:layout_width =FILL_PARENT
     机器人:layout_height =430dp/>
    <的LinearLayout
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =50dp
        机器人:重力=CENTER_HORIZONTAL
        机器人:layout_gravity =底
        机器人:背景=#c2300f>
        <按钮
            机器人:ID =@ + ID / buttonUndo
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =WRAP_CONTENT
            机器人:文字=撤消/>
        <按钮
            机器人:ID =@ + ID / buttonRedo
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =WRAP_CONTENT
            机器人:文字=重做/>
        <按钮
            机器人:ID =@ + ID / buttonColor
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =WRAP_CONTENT
            机器人:文字=颜色/>
    < / LinearLayout中>
   < / LinearLayout中>

主要活动是......

 包com.example.surfacetuto; 进口android.app.Activity;
 进口android.graphics.Paint;
 进口android.graphics.Point;
 进口android.os.Bundle;
 进口android.util.Log;
 进口android.view.MotionEvent;
 进口android.view.View;
 进口android.view.View.OnClickListener;
 进口android.widget.Button;
 进口android.widget.FrameLayout;
 进口android.widget.TextView;
 进口android.widget.Toast; 公共类MainActivity扩展活动实现OnClickListener {
DrawingSurface DS;
FRM的FrameLayout;
按钮btnU,btnR,btnC;
INT颜色= 0xfff00000;
@覆盖
公共无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    DS =新DrawingSurface(本);
    的setContentView(R.layout.activity_main);    FRM =(的FrameLayout)findViewById(R.id.frameLayout);
    frm.addView(DS);    btnU =(按钮)findViewById(R.id.buttonUndo);
    btnR =(按钮)findViewById(R.id.buttonRedo);
    btnC =(按钮)findViewById(R.id.buttonColor);    btnU.setOnClickListener(本);
    btnR.setOnClickListener(本);
    btnC.setOnClickListener(本);    btnU.setEnabled(真);
    btnR.setEnabled(真);
}
@覆盖
公共无效的onClick(视图v){
    // TODO自动生成方法存根
    开关(v.getId()){
    案例R.id.buttonUndo:
        ds.undo();
        如果(ds.hasMoreUndo()==假){
            btnU.setEnabled(假);
        }
        btnU.setEnabled(真);
        Toast.makeText(getApplicationContext(),撤消,0).show();
        打破;
    案例R.id.buttonRedo:
        ds.redo();
        如果(ds.hasMoreRedo()==假){
            btnR.setEnabled(假);
        }        btnR.setEnabled(真);
        Toast.makeText(getApplicationContext(),重做,1).show();
        打破;
    案例R.id.buttonColor:
        Toast.makeText(getApplicationContext(),色彩,2).show();
        ds.colorNew();        打破;    默认:
        打破;
    }
}
   }

绘图表面类是.....

 包com.example.surfacetuto;进口android.app.Activity;
进口android.content.Context;
进口android.graphics.Bitmap;
进口android.graphics.BitmapFactory;
进口android.graphics.Canvas;
进口android.graphics.Color;
进口android.graphics.Matrix;
进口android.graphics.Paint;
进口android.graphics.Paint.Cap;
进口android.graphics.Rect;
进口android.util.AttributeSet;
进口android.util.DisplayMetrics;
进口android.util.Log;
进口android.view.MotionEvent;
进口android.view.SurfaceHolder;
进口android.view.SurfaceView;
进口android.view.View;
进口android.view.Window;
进口android.view.WindowManager;
进口android.widget.Toast;公共类DrawingSurface扩展SurfaceView实现SurfaceHolder.Callback {       帆布cacheCanvas;
       位图后备缓冲;
       INT宽度,高度,clientHeight;
       涂料粉刷;
       上下文语境;
        SurfaceHolder mHolder;
        保护DrawThread螺纹;
      私人布尔_run;
      公共布尔isDrawing = TRUE;
      私人位图mBitmap;
      私人命令管理命令管理;公共DrawingSurface(上下文的背景下){
    超级(上下文);
    this.context =背景;
    在里面();
}
公共DrawingSurface(上下文的背景下,ATTRS的AttributeSet){
    超(背景下,ATTRS);
    this.context =背景;
    在里面();
}私人无效的init(){
    mHolder = getHolder();
    mHolder.addCallback(本);
    命令管理=新的CommandManager();
    螺纹=新DrawThread(getHolder());}
类DrawThread继承Thread {
    私人SurfaceHolder mSurfaceHolder;
    公共DrawThread(SurfaceHolder surfaceHolder){
        mSurfaceHolder = surfaceHolder;
    }
    公共无效setRunning(布尔运行){
        _run =运行;
    }
    @覆盖
    公共无效的run(){
        帆布帆布= NULL;
        而(_run){
            如果(isDrawing ==真){
                尝试{
                    帆布= mSurfaceHolder.lockCanvas(NULL);
                    如果(mBitmap == NULL){
                        mBitmap = Bitmap.createBitmap(100,100,Bitmap.Config.ARGB_8888);
                    }
                    最后帆布C =新的Canvas(mBitmap);
                    c.drawColor(Color.WHITE);
                    canvas.drawColor(Color.WHITE);
                    commandManager.executeAll(C);
                    canvas.drawBitmap(mBitmap,0,0,NULL);
                } {最后
                    mSurfaceHolder.unlockCanvasAndPost(画布);
                }
                isDrawing = TRUE;
            }          }        }
    }
 公共无效addDrawingPath(DrawingPath drawingPath){
        commandManager.addCommand(drawingPath);
    }INT lastX,lastY,currX,咖喱;
布尔isDeleting;
@覆盖
公共布尔onTouchEvent(MotionEvent事件){
    super.onTouchEvent(事件);
    INT行动= event.getAction();
    开关(动作&安培; MotionEvent.ACTION_MASK){
    案例MotionEvent.ACTION_DOWN:
        lastX =(int)的event.getX();
        lastY =(int)的event.getY();
        打破;
    案例MotionEvent.ACTION_MOVE:
        如果(isDeleting)破;        currX =(int)的event.getX();
        咖喱=(INT)event.getY();
        cacheCanvas.drawLine(lastX,lastY,currX,咖喱,油漆);
        lastX = currX;
        lastY =咖喱;        打破;
    案例MotionEvent.ACTION_UP:
        如果(isDeleting)isDeleting = FALSE;
        打破;
    案例MotionEvent.ACTION_POINTER_DOWN:
        cacheCanvas.drawColor(Color.WHITE);
        isDeleting = TRUE;
        打破;
    案例MotionEvent.ACTION_POINTER_UP:
        打破;
    }
    画();
    返回true;
}保护无效的draw(){    如果(clientHeight == 0){
        clientHeight = getClientHeight();
        高度= clientHeight;
        后备缓冲= Bitmap.createBitmap(宽度,高度,Bitmap.Config.ARGB_8888);
        cacheCanvas.setBitmap(后备缓冲);
        cacheCanvas.drawColor(Color.WHITE);
    }
    帆布帆布= NULL;
    尝试{
        帆布= mHolder.lockCanvas(NULL);        canvas.drawBitmap(后备缓冲,0,0,油漆);
    }赶上(例外前){
        ex.printStackTrace();
    }最后{
        如果(mHolder!= NULL)mHolder.unlockCanvasAndPost(画布);
    }
}私人诠释getClientHeight(){
    RECT RECT =新的矩形();
    窗口窗口=((活动)上下文).getWindow();
    。window.getDecorView()getWindowVisibleDisplayFrame(RECT);
    INT statusBarHeight = rect.top;
    INT contentViewTop = window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
    INT titleBarHeight = contentViewTop - statusBarHeight;
    回报((活动)上下文).getWindowManager()。getDefaultDisplay()。
            的getHeight() - statusBarHeight - titleBarHeight;
}
公共无效surfaceChanged(SurfaceHolder架,INT格式,宽度INT,
        INT高度){
}公共无效surfaceCreated(SurfaceHolder持有人){
        thread.setRunning(真);
        thread.start();    宽度=的getWidth();
    高度=的getHeight();
    cacheCanvas =新的Canvas();
    后备缓冲= Bitmap.createBitmap(宽度,高度,Bitmap.Config.ARGB_8888);
    cacheCanvas.setBitmap(后备缓冲);
    cacheCanvas.drawColor(Color.WHITE);
    油漆=新的油漆();
    paint.setColor(Color.BLUE);
    paint.setStrokeWidth(10);
    paint.setStrokeCap​​(Paint.Cap.ROUND);
    paint.setStrokeJoin(Paint.Join.ROUND);
    画();}公共无效surfaceDestroyed(SurfaceHolder持有人){
     布尔重试= TRUE;
        thread.setRunning(假);
        而(重试){
            尝试{
                的Thread.join();
                重试= FALSE;
            }赶上(InterruptedException的E){
                //我们会一次又一次地尝试...
            }
        }
}公共无效colorNew(){
    // TODO自动生成方法存根
    paint.setColor(Color.GRAY);
}
公共无效撤消(){
    // TODO自动生成方法存根
     isDrawing = TRUE;
    commandManager.undo();
}
公共无效重做(){
    // TODO自动生成方法存根
     isDrawing = TRUE;
    commandManager.redo();
}
公共布尔hasMoreUndo(){
    // TODO自动生成方法存根
    返回commandManager.hasMoreUndo();
}
公共布尔hasMoreRedo(){
    // TODO自动生成方法存根
     返回commandManager.hasMoreRedo();
}
  }


解决方案

我尝试很多实施撤销,并在你的code重做,但我不是成功。

我把这里完成项目,撤消和重做操作。

https://github.com/niravranpara/CanvasDrawings

I am currently work on surface view for drawing purpose, but am facing a problem that am not performing the undo redo operation on surface view using command pattern. If any one knows about it's then please help.

My code is XML..

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">

<FrameLayout
     android:id="@+id/frameLayout"
     android:layout_width="fill_parent"
     android:layout_height="430dp"/>
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:gravity="center_horizontal"
        android:layout_gravity="bottom"
        android:background="#c2300f">
        <Button
            android:id="@+id/buttonUndo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Undo" />
        <Button
            android:id="@+id/buttonRedo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Redo" />
        <Button
            android:id="@+id/buttonColor"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Color" />
    </LinearLayout>       
   </LinearLayout>

Main Activity is ......

package com.example.surfacetuto;

 import android.app.Activity;
 import android.graphics.Paint;
 import android.graphics.Point;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
 import android.widget.FrameLayout;
 import android.widget.TextView;
 import android.widget.Toast;

 public class MainActivity extends Activity implements OnClickListener{
DrawingSurface ds;
FrameLayout frm;
Button btnU,btnR,btnC;
int color=0xfff00000;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ds=new DrawingSurface(this);
    setContentView(R.layout.activity_main);

    frm=(FrameLayout)findViewById(R.id.frameLayout);
    frm.addView(ds);

    btnU=(Button)findViewById(R.id.buttonUndo);
    btnR=(Button)findViewById(R.id.buttonRedo);
    btnC=(Button)findViewById(R.id.buttonColor);

    btnU.setOnClickListener(this);
    btnR.setOnClickListener(this);
    btnC.setOnClickListener(this);

    btnU.setEnabled(true);
    btnR.setEnabled(true);
}
@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    switch (v.getId()) {
    case R.id.buttonUndo:
        ds.undo();
        if( ds.hasMoreUndo() == false ){
            btnU.setEnabled( false );
        }
        btnU.setEnabled( true );
        Toast.makeText(getApplicationContext(), "Undo", 0).show();
        break;
    case R.id.buttonRedo:
        ds.redo();
        if( ds.hasMoreRedo() == false ){
            btnR.setEnabled( false );
        }

        btnR.setEnabled( true );
        Toast.makeText(getApplicationContext(), "Redo", 1).show();
        break;
    case R.id.buttonColor:
        Toast.makeText(getApplicationContext(), "Color", 2).show();
        ds.colorNew();

        break;

    default:
        break;
    }
}   
   }

Drawing Surface class is.....

package com.example.surfacetuto;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback {

       Canvas cacheCanvas;
       Bitmap backBuffer;
       int width, height, clientHeight;
       Paint paint;
       Context context;
        SurfaceHolder mHolder;
        protected DrawThread thread;
      private Boolean _run;
      public boolean isDrawing = true;
      private Bitmap mBitmap;
      private CommandManager commandManager;

public DrawingSurface(Context context) {
    super(context);
    this.context = context;
    init();
}
public DrawingSurface(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;      
    init();
}

private void init() {
    mHolder = getHolder();
    mHolder.addCallback(this);
    commandManager = new CommandManager();
    thread = new DrawThread(getHolder());

}
class DrawThread extends  Thread{
    private SurfaceHolder mSurfaceHolder;
    public DrawThread(SurfaceHolder surfaceHolder){
        mSurfaceHolder = surfaceHolder;
    }
    public void setRunning(boolean run) {
        _run = run;
    }
    @Override
    public void run() {
        Canvas canvas = null;
        while (_run){
            if(isDrawing == true){
                try{
                    canvas = mSurfaceHolder.lockCanvas(null);
                    if(mBitmap == null){
                        mBitmap =  Bitmap.createBitmap (100, 100, Bitmap.Config.ARGB_8888);
                    }
                    final Canvas c = new Canvas (mBitmap);
                    c.drawColor(Color.WHITE);
                    canvas.drawColor(Color.WHITE);
                    commandManager.executeAll(c);
                    canvas.drawBitmap (mBitmap, 0,  0,null);
                } finally {
                    mSurfaceHolder.unlockCanvasAndPost(canvas);
                }
                isDrawing = true;
            }

          }

        }
    }
 public void addDrawingPath (DrawingPath drawingPath){
        commandManager.addCommand(drawingPath);
    }

int lastX, lastY, currX, currY;
boolean isDeleting;
@Override
public boolean onTouchEvent(MotionEvent event) {
    super.onTouchEvent(event);
    int action = event.getAction();
    switch(action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
        lastX = (int) event.getX();
        lastY = (int) event.getY();
        break;
    case MotionEvent.ACTION_MOVE:
        if(isDeleting) break;

        currX = (int) event.getX();
        currY = (int) event.getY();
        cacheCanvas.drawLine(lastX, lastY, currX, currY, paint);
        lastX = currX;
        lastY = currY;

        break;
    case MotionEvent.ACTION_UP:
        if(isDeleting) isDeleting = false;
        break;
    case MotionEvent.ACTION_POINTER_DOWN:
        cacheCanvas.drawColor(Color.WHITE);
        isDeleting = true;
        break;
    case MotionEvent.ACTION_POINTER_UP:
        break;
    }
    draw(); 
    return true;
}

protected void draw() {

    if(clientHeight==0) {
        clientHeight = getClientHeight();
        height = clientHeight;
        backBuffer = Bitmap.createBitmap( width, height, Bitmap.Config.ARGB_8888);
        cacheCanvas.setBitmap(backBuffer);
        cacheCanvas.drawColor(Color.WHITE);
    }
    Canvas canvas = null;
    try{
        canvas = mHolder.lockCanvas(null);

        canvas.drawBitmap(backBuffer, 0,0, paint);
    }catch(Exception ex){
        ex.printStackTrace();
    }finally{
        if(mHolder!=null)  mHolder.unlockCanvasAndPost(canvas);
    }
}

private int getClientHeight() {
    Rect rect= new Rect();    
    Window window = ((Activity)context).getWindow();     
    window.getDecorView().getWindowVisibleDisplayFrame(rect);     
    int statusBarHeight= rect.top;    
    int contentViewTop= window.findViewById(Window.ID_ANDROID_CONTENT).getTop();     
    int titleBarHeight= contentViewTop - statusBarHeight;
    return ((Activity)context).getWindowManager().getDefaultDisplay().
            getHeight() - statusBarHeight - titleBarHeight;
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
}

public void surfaceCreated(SurfaceHolder holder) {


        thread.setRunning(true);
        thread.start();

    width = getWidth();
    height = getHeight();
    cacheCanvas = new Canvas();
    backBuffer = Bitmap.createBitmap( width, height, Bitmap.Config.ARGB_8888); 
    cacheCanvas.setBitmap(backBuffer);
    cacheCanvas.drawColor(Color.WHITE);
    paint = new Paint();
    paint.setColor(Color.BLUE);
    paint.setStrokeWidth(10);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setStrokeJoin(Paint.Join.ROUND);
    draw();

}

public void surfaceDestroyed(SurfaceHolder holder) {
     boolean retry = true;
        thread.setRunning(false);
        while (retry) {
            try {
                thread.join();
                retry = false;
            } catch (InterruptedException e) {
                // we will try it again and again...
            }
        }
}

public void colorNew() {
    // TODO Auto-generated method stub
    paint.setColor(Color.GRAY);
}
public void undo() {
    // TODO Auto-generated method stub
     isDrawing = true;
    commandManager.undo();
}
public void redo() {
    // TODO Auto-generated method stub
     isDrawing = true;
    commandManager.redo();
}
public boolean hasMoreUndo() {
    // TODO Auto-generated method stub
    return commandManager.hasMoreUndo();
}
public boolean hasMoreRedo() {
    // TODO Auto-generated method stub
     return commandManager.hasMoreRedo();
}
  }

解决方案

I have try lot to implement undo and redo in your code but I am not success.

I put here complete project with Undo and Redo operation.

https://github.com/niravranpara/CanvasDrawings

这篇关于如何执行在表面观撤销重做的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆