一个功能强大的画图板(三)
2016-07-11 09:53
369 查看
大家看过我上两篇博客[画图板一](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)
相关文章推荐
- Bzoj 1336&1337 Alien最小圆覆盖
- 国内物联网平台的发展、技术架构演进暨物联网解决方案发布
- 仿新浪微博加号弹出界面动画
- Spring <tx:advice/>
- Linux access()函数 使用
- leetcode.175. Combine Two Tables
- cf 433 C(思维题)
- 不错的网站
- Android RelativeLayout中实现控件平分屏幕
- [技术管理]如何做到业务迭代和技术积累的平衡?
- IOS build 与version,InfoDictionary version的区别
- 华为机试---LRU算法
- 山东理工OJ 2562 相似三角形
- hdu 5102 The K-th Distance(特殊的搜索技巧)
- Android SDK版本和ADT版本
- android SDK版本 19升级到23的坑
- 三角形
- iOS实现电话状态监听 CoreTelephony
- 关于python urlopen 一个类似radio流的timeout方法
- 使用友盟分享,QQ分享成功却弹出QQ分享取消的toast问题解决