大家看过我上两篇博客[画图板一](http://blog.csdn.net/songhengqian/article/details/51792420),[画图板二](http://blog.csdn.net/songhengqian/article/details/51822207)肯定对接下来的内容不陌生了,画图板一开始无非就是我们准备好画笔paint,画在什么上呢? 那就再找个画布canvas,有了笔有了画布那画成啥样,OK我们找来了画笔路径path,三者找齐在触摸方法拿到我们触摸的点,那么最简单的画图板就实现了。我们这么一分析下来发现是不是很简单,其实加上其他的功能也不难,那么我们就来分析下如何实现笔画的恢复和撤销。
我们的画图板里有橡皮,其实可以不加撤销删除,如果加上有点鸡肋的感觉,不过为了给大家分享知识就加上来讲解讲解。对于笔画的撤销与恢复我们很容易就能够想到,撤销我们就把每次的path保存起来,把最上面的移除再把其他的路径重新绘制上去就OK了,恢复更简单,把我们撤销的保存到集合中,从集合中拿出来重新画上就没问题了。
//view的原宽高
private int oldWidth;
private int oldHeight;
/**
* 保存路径的集合
*/
private ArrayList<DrawPath> savePath;
private ArrayList<DrawPath> deletePath;
private DrawPath dp;
/**
* 路径对象
*
*/
class DrawPath {
Path path;
Paint paint;
}
有了保存路径的集合我们可以写撤销和恢复的方法了
/**
* 撤销笔画操作
*/
public void undo() {
if (savePath != null && savePath.size() > 0) {
initCanvas();
// 将路径保存列表中的最后一个元素删除 ,并将其保存在路径删除列表中
DrawPath drawPath = savePath.get(savePath.size() - 1);
deletePath.add(drawPath);
savePath.remove(savePath.size() - 1);
// 将路径保存列表中的路径重绘在画布上
Iterator<DrawPath> iter = savePath.iterator(); // 重复保存
while (iter.hasNext()) {
DrawPath dp = iter.next();
mCanvas.drawPath(dp.path, dp.paint);
}
invalidate();
}
}
/**
* 恢复笔画操作
*/
public void redo() {
if (deletePath != null && deletePath.size() > 0) {
// 将删除的路径列表中的最后一个,也就是最顶端路径取出(栈),并加入路径保存列表中
DrawPath dp = deletePath.get(deletePath.size() - 1);
savePath.add(dp);
// 将取出的路径重绘在画布上
mCanvas.drawPath(dp.path, dp.paint);
// 将该路径从删除的路径列表中去除
deletePath.remove(deletePath.size() - 1);
invalidate();
}
}
// 初始化画布函数以清空画布
private void initCanvas() {
setFocusableInTouchMode(true);
setFocusable(true);
/* 初始化画笔 */
initPaint();
mCanvas = new Canvas();
mPath = new Path();
bitmap_bg=null;
bitmap_fg=null;
onSizeChanged(bitmapWidth, bitmapHeight, oldWidth, oldHeight);
}
/**
* 清屏
*/
public void clearPaint() {
initCanvas();
invalidate();
savePath.clear();
deletePath.clear();
}
然后我们每次开始画的时候创建一个新的path对象,完成之后保存到savePath集合中,
case MotionEvent.ACTION_DOWN:
if (paintState==paint.PEN){
mPath = null;
mPath = new Path();
dp = new DrawPath();
dp.path = mPath;
dp.paint = mPaint;
mPath.reset();
}else if (paintState==paint.ERASER){
mPath = null;
mPath = new Path();
dp = new DrawPath();
dp.path = mPath;
dp.paint = mEraser;
mPath.reset();
}
onTouchDown(event);
invalidate();
break;
case MotionEvent.ACTION_UP:
if(paintState==paint.NONE) {
// 手指离开屏幕时将临时值还原
lastXMove = -1;
lastYMove = -1;
}else {
onTouchUp(event);
savePath.add(dp);
// mPath = null;
invalidate();
MainActivity.activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (MainActivity.activity.getBackBtn().getVisibility()==GONE
&& savePath!=null && savePath.size()!=0){
MainActivity.activity.getBackBtn().setVisibility(VISIBLE);
MainActivity.activity.getBackHoverBtn().setVisibility(GONE);
}
}
});
}
break;
这里基本就是在down中创建新的path,在up中保存到集合,比较简单。相信大家看了一定会想着太简单了,对,只要你愿意去梳理一切就是这么简单,写完这一篇我们的画图板基本写的差不错了,剩下的就是保存和viewpager视图预览了,希望大家继续关注。
下载源码地址:[画图板三](http://download.csdn.net/detail/songhengqian/9573533)