如何执行在表面观撤销重做 [英] How to perform undo redo on surface view
本文介绍了如何执行在表面观撤销重做的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我目前在表面观努力绘制目的,但我面临着我不是使用命令图案表面视图执行撤消重做操作的问题。如果有任何人知道这件事的话,请帮助。
我的code是XML。
< LinearLayout中的xmlns:机器人=http://schemas.android.com/apk/res/android
的xmlns:工具=http://schemas.android.com/tools
机器人: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屋!
查看全文