您的位置:首页 > 移动开发 > Android开发

android画图并实现撤销功能

2017-02-02 23:15 295 查看
因为在项目后期会用到android的画线画框功能,所以趁着过年在家琢磨了一下,本以为很简单的功能,却用掉了一整天的时间,先将其中的坑说一下:

1.在画线过程中,以down事件的点为起点

2.如果以up事件的点为终点,监听up事件,执行画线操作,那么在手指滑动期间,是不执行画线操作的,只有在手指抬起的瞬间,才会画线,这样画出来的线是不准确的,由于在滑动过程中没有画线,所以线的最终位置可能和我们想要的结果有些偏差

3.如果在move事件中画线,不多说,直接上图:



代码1.0:

public boolean onTouch(View v, MotionEvent event) {

paint.setColor(Color.BLUE);

switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
startX = (int) event.getX();
startY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
endX = (int) event.getX();
endY = (int) event.getY();
//画线
Shape shape = new LineShape(startX,startY,endX,endY);
shape.draw(canvas,paint);
imageView.setImageBitmap(bitmap_view);
break;
case MotionEvent.ACTION_UP:
endX = (int) event.getX();
endY = (int) event.getY();
Shape shape1 = new LineShape(startX,startY,endX,endY);
shape.draw(canvas,paint);
break;
default:
break;
}
return true;
}


由于在move事件中不断的执行画线方法,所以画出来的线有很多。

解决思路:在每次up事件中将画线的结果保存在list,move事件中将画布和背景还原,重新画list中保存的历史记录,再画出当前移动的位置,这样每次move时候,如果手指没有抬起,还在调整线的位置时,list是不会保存这条记录的,待线的位置调整好,手指抬起时,再将本次画的线存入list。

代码2.0:

/*

* 重置画布

*

* */

public void resetCanvas(){

imageView.setImageBitmap(bitmap_view);

canvas = new Canvas(bitmap_view);

}

/*
画出list中保存的操作
*/
public void drawFromList(Canvas canvas,Paint paint,List<Shape> list){
for (Shape shape : list){
shape.draw(canvas,paint);
}
}


public boolean onTouch(View v, MotionEvent event) {

paint.setColor(Color.BLUE);

switch (event.getAction()){

case MotionEvent.ACTION_DOWN:

startX = (int) event.getX();

startY = (int) event.getY();

break;

case MotionEvent.ACTION_MOVE:

endX = (int) event.getX();

endY = (int) event.getY();

//1.重置页面

resetCanvas();

//2.画出list中保存的操作

drawFromList(canvas,paint,shapeList);

//3.画出本次拖动状态的操作

Shape shape = new LineShape(startX,startY,endX,endY);

shape.draw(canvas,paint);

imageView.setImageBitmap(bitmap_view);

break;

case MotionEvent.ACTION_UP:

endX = (int) event.getX();

endY = (int) event.getY();

//1.重置画布

resetCanvas();

//2.将新的操作加入list

Shape shape1 = new LineShape(startX,startY,endX,endY);

shapeList.add(shape1);

//3.画出list中保存的操作

drawFromList(canvas,paint,shapeList);

break;

default:

break;

}

return true;
}


结果如图:



结果竟然还是这样!只好一步步的debug,发现下面方法中的bitmap_view,并没有还原,每次move时画了条线上去,重置画布和背景时,用的还是被画过之后的

bitmap_view,所以实际上并没有效果。

public void resetCanvas(){

imageView.setImageBitmap(bitmap_view);

canvas = new Canvas(bitmap_view);

}

解决思路:在初始化时,复制一份背景图bitmap_tmp,在重置画布和背景时,再把bitmap_tmp复制给bitmap_view,这样就可以了。但是在实际过程中,还遇到了深复制浅复制的问题,如果使用浅复制,那么结果还是和上图一模一样,必须使用深复制才行。

代码n.0:

初始化时先执行下面这句:

bitmap_tmp = bitmap_view.copy(Bitmap.Config.ARGB_8888,true);

/*

* 重置画布

*

* */

public void resetCanvas(){

bitmap_view = bitmap_tmp.copy(Bitmap.Config.ARGB_8888,true);

imageView.setImageBitmap(bitmap_view);

canvas = new Canvas(bitmap_view);

}

其它代码不变。

结果如图:



代码只贴了imageView的onTouch方法,如果要实现撤销功能的话,就从list中删掉最后一次操作即可,代码如下。

/*

*

* 撤销功能

*

* */

public void undo(){

if(shapeList != null && shapeList.size() > 0){

//删除最后一次操作

shapeList.remove(shapeList.size() - 1);

}

}

代码中使用了Shape来提高可扩展性,如果画多种形状,矩形圆形等,在此基础上稍作改动即可。

如有错误,欢迎指正,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android