Android:绘画应用程序中的撤消功能不工作
我正在开发一个绘画应用程序,代码如下: 牵引活动 图纸2Android:绘画应用程序中的撤消功能不工作,android,path,paint,undo,Android,Path,Paint,Undo,我正在开发一个绘画应用程序,代码如下: 牵引活动 图纸2 公共类MyDrawView2扩展了视图 { 私有位图mBitmap; 私人帆布mCanvas; 专用路径mPath; 私人油漆; 语境; 私有ArrayList路径=新ArrayList(); private ArrayList undonePaths=new ArrayList(); 公共MyDrawView2(上下文c、属性集属性) { super(c,attrs); 上下文=c; mPath=新路径(); mBitmapPaint=
公共类MyDrawView2扩展了视图
{
私有位图mBitmap;
私人帆布mCanvas;
专用路径mPath;
私人油漆;
语境;
私有ArrayList路径=新ArrayList();
private ArrayList undonePaths=new ArrayList();
公共MyDrawView2(上下文c、属性集属性)
{
super(c,attrs);
上下文=c;
mPath=新路径();
mBitmapPaint=新油漆(油漆抖动标志);
setLayerType(View.LAYER_TYPE_SOFTWARE,null);//仅用于删除黑色橡皮擦
}
@凌驾
已更改尺寸的受保护空心(整数w、整数h、整数oldw、整数oldh)
{
super.onSizeChanged(w,h,oldw,oldh);
mBitmap=Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
mCanvas=新画布(mBitmap);
}
@凌驾
受保护的void onDraw(画布)
{
super.onDraw(帆布);
drawBitmap(mBitmap,0,0,mbitMapPoint);
drawPath(mPath,Constants.mPaint);
}
公共void onClickUndo()
{
if(path.size()>0)
{
undonePaths.add(path.remove(path.size()-1));
使无效();
}
其他的
{
Toast.makeText(getContext(),“无需撤消”,Toast.LENGTH_SHORT.show();
}
}
公共void onClickRedo()
{
如果(撤消路径大小()>0)
{
add(undonePaths.remove(undonePaths.size()-1));
使无效();
}
其他的
{
Toast.makeText(getContext(),“无需重做”,Toast.LENGTH_SHORT.show();
}
}
私人浮动mX,我的;
专用静态最终浮动接触公差=4;
专用无效触摸启动(浮动x、浮动y)
{
撤销海王星。清除();
mPath.reset();
移动到(x,y)的速度;
mX=x;
mY=y;
}
私有无效触摸移动(浮动x、浮动y)
{
float dx=Math.abs(x-mX);
float dy=Math.abs(y-mY);
如果(dx>=接触公差| | dy>=接触公差)
{
兆帕四分之一秒(mX,mY,(x+mX)/2,(y+mY)/2);
mX=x;
mY=y;
}
}
私人空间修补()
{
mPath.lineTo(mX,mY);
mCanvas.drawPath(mPath,Constants.mPaint);//将路径提交到屏幕外
路径。添加(mPath);
Toast.makeText(getContext(),“path added”+path.size(),Toast.LENGTH\u SHORT.show();
mPath.reset();//杀死它,这样我们就不会重复绘制
Constants.mPaint.setXfermode(新的PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
//mPaint.setMaskFilter(null);
}
@凌驾
公共布尔onTouchEvent(运动事件)
{
float x=event.getX();
float y=event.getY();
开关(event.getAction())
{
case MotionEvent.ACTION\u DOWN:
触摸启动(x,y);
使无效();
打破
case MotionEvent.ACTION\u移动:
触摸移动(x,y);
使无效();
打破
case MotionEvent.ACTION\u UP:
润色;
使无效();
打破
}
返回true;
}
}
问题:
在每个touch\u上
我都添加了一个toast,计算arraylistpaths
中的路径数,并且正确显示。但单击“撤消”后,撤消功能不起作用
这怎么能解决呢?非常感谢 通过对onSizeChanged()、onDraw()和touch_up()进行以下更改,我获得了撤销和重做功能:
公共类MyDrawView2扩展了视图
{
私人帆布mCanvas;
专用路径mPath;
语境;
私有ArrayList路径=新ArrayList();
private ArrayList undonePaths=new ArrayList();
公共MyDrawView2(上下文c、属性集属性)
{
super(c,attrs);
上下文=c;
mPath=新路径();
//增加
mCanvas=新画布();
}
@凌驾
已更改尺寸的受保护空心(整数w、整数h、整数oldw、整数oldh)
{
super.onSizeChanged(w,h,oldw,oldh);
//已删除位图。。。
}
@凌驾
受保护的void onDraw(画布)
{
super.onDraw(帆布);
//增加
用于(路径p:路径){
drawPath(p,Constants.mPaint);
}
drawPath(mPath,Constants.mPaint);
//已删除位图。。。
}
公共void onClickUndo()
{
if(path.size()>0)
{
undonePaths.add(path.remove(path.size()-1));
使无效();
}
其他的
{
Toast.makeText(getContext(),“无需撤消”,Toast.LENGTH_SHORT.show();
}
}
公共void onClickRedo()
{
如果(撤消路径大小()>0)
{
add(undonePaths.remove(undonePaths.size()-1));
使无效();
}
其他的
{
Toast.makeText(getContext(),“无需重做”,Toast.LENGTH_SHORT.show();
}
}
私人浮动mX,我的;
专用静态最终浮动接触公差=4;
专用无效触摸启动(浮动x、浮动y)
{
撤销海王星。清除();
mPath.reset();
移动到(x,y)的速度;
mX=x;
mY=y;
}
私有无效触摸移动(浮动x、浮动y)
{
float dx=Math.abs(x-mX);
float dy=Math.abs(y-mY);
如果(dx>=接触公差| | dy>=接触公差)
{
兆帕四分之一秒(mX,mY,(x+mX)/2,(y+mY)/2);
mX=x;
mY=y;
}
}
私人空间修补()
{
mPath.lineTo(mX,mY);
绘制路径(mPath,Constants.mPaint)//
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.coloring_activity3);
....
mv = (MyDrawView2) findViewById(R.id.drawerView);
mv.setDrawingCacheEnabled(true);
Constants.mPaint = new Paint();
Constants.mPaint.setAntiAlias(true);
Constants.mPaint.setDither(true);
Constants.mPaint.setColor(0xFF000000);
Constants.mPaint.setStyle(Paint.Style.STROKE);
Constants.mPaint.setStrokeJoin(Paint.Join.ROUND);
Constants.mPaint.setStrokeCap(Paint.Cap.ROUND);
Constants.mPaint.setStrokeWidth(Brush_size);
....
case R.id.btn_eraser:
Constants.mPaint.setXfermode(null);
Constants.mPaint.setAlpha(0xFF);
Constants.mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
layout_eraser_size.startAnimation(eraser_move_from_bottom_into_screen);
layout_eraser_size.setVisibility(View.VISIBLE);
btn_eraser.setEnabled(false);
break;
case R.id.btn_brush:
layout_brush_btns.startAnimation(brush_move_from_bottom_into_screen);
layout_brush_btns.setVisibility(View.VISIBLE);
btn_brush.setEnabled(false);
break;
case R.id.btn_undo:
Constants.custom_toast(this, "undo", "clicked");
mv.onClickUndo();
break;
public class MyDrawView2 extends View
{
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
public MyDrawView2(Context c, AttributeSet attrs)
{
super(c, attrs);
context = c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
setLayerType(View.LAYER_TYPE_SOFTWARE, null); // for solely removing the black eraser
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, Constants.mPaint);
}
public void onClickUndo ()
{
if (paths.size()>0)
{
undonePaths.add(paths.remove(paths.size()-1));
invalidate();
}
else
{
Toast.makeText(getContext(), "nothing to undo", Toast.LENGTH_SHORT).show();
}
}
public void onClickRedo ()
{
if (undonePaths.size()>0)
{
paths.add(undonePaths.remove(undonePaths.size()-1)) ;
invalidate();
}
else
{
Toast.makeText(getContext(), "nothing to redo", Toast.LENGTH_SHORT).show();
}
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y)
{
undonePaths.clear();
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y)
{
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
{
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up()
{
mPath.lineTo(mX, mY);
mCanvas.drawPath(mPath, Constants.mPaint); // commit the path to our offscreen
paths.add(mPath);
Toast.makeText(getContext(), "path added" + paths.size(), Toast.LENGTH_SHORT).show();
mPath.reset(); // kill this so we don't double draw
Constants.mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
// mPaint.setMaskFilter(null);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
float x = event.getX();
float y = event.getY();
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
public class MyDrawView2 extends View
{
private Canvas mCanvas;
private Path mPath;
Context context;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
public MyDrawView2(Context c, AttributeSet attrs)
{
super(c, attrs);
context = c;
mPath = new Path();
//added
mCanvas = new Canvas();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
//removed bitmap ...
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
//added
for (Path p : paths){
canvas.drawPath(p, Constants.mPaint);
}
canvas.drawPath(mPath, Constants.mPaint);
//removed bitmap ...
}
public void onClickUndo ()
{
if (paths.size()>0)
{
undonePaths.add(paths.remove(paths.size()-1));
invalidate();
}
else
{
Toast.makeText(getContext(), "nothing to undo", Toast.LENGTH_SHORT).show();
}
}
public void onClickRedo ()
{
if (undonePaths.size()>0)
{
paths.add(undonePaths.remove(undonePaths.size()-1)) ;
invalidate();
}
else
{
Toast.makeText(getContext(), "nothing to redo", Toast.LENGTH_SHORT).show();
}
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y)
{
undonePaths.clear();
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y)
{
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
{
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up()
{
mPath.lineTo(mX, mY);
mCanvas.drawPath(mPath, Constants.mPaint); // commit the path to our offscreen
paths.add(mPath);
Toast.makeText(getContext(), "path added" + paths.size(), Toast.LENGTH_SHORT).show();
//added
mPath = new Path();
//removed reset...
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
float x = event.getX();
float y = event.getY();
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}