Android触摸事件如何实现笔触画布详解
程序员文章站
2024-02-07 09:22:58
前言
任何view都有触摸事件,经常在自定义控件时重写setontouchlistener
本篇通过手绘图片来讲述这个知识点,下面话不多说了,来一起看看详细的介绍吧...
前言
任何view都有触摸事件,经常在自定义控件时重写setontouchlistener
本篇通过手绘图片来讲述这个知识点,下面话不多说了,来一起看看详细的介绍吧
本篇分为三个等级:一览图:
直线
曲线
笔触
level1:基础实现
在activity中通过一个全屏的bitmap创建的canvas绘制
为imageview添加触摸事件监听。
1.成员变量
imageview midivshow; float downx = 0; float downy = 0; float upx = 0; float upy = 0; private canvas mcanvas; private paint mpaint;
2.创建画布
//获取屏幕尺寸 point point = new point(); getwindowmanager().getdefaultdisplay().getsize(point); //创建一个和屏幕一样大的bitmap bitmap bitmap = bitmap.createbitmap(point.x, point.y, bitmap.config.argb_8888); //创建canvas对象 mcanvas = new canvas(bitmap); mpaint = new paint(paint.anti_alias_flag); mpaint.setstrokewidth(10); mpaint.setcolor(color.red); //将bitmap用imageview展示 midivshow.setimagebitmap(bitmap);
3.监听事件
midivshow.setontouchlistener((v, event) -> { switch (event.getaction()) { case motionevent.action_down: downx = event.getx(); downy = event.gety(); l.d("按下:(" + downx + "," + downy + ")" + l.l()); break; case motionevent.action_cancel: break; case motionevent.action_move: break; case motionevent.action_up: upx = event.getx(); upy = event.gety(); l.d("抬起:(" + upx + "," + upy + ")" + l.l()); mcanvas.drawline(downx, downy, upx, upy, mpaint); midivshow.invalidate();//更新视图 break; } return true; }); }
升级版:lever2
midivshow.setontouchlistener((v, event) -> { switch (event.getaction()) { case motionevent.action_down: downx = event.getx(); downy = event.gety(); break; case motionevent.action_cancel: break; case motionevent.action_move: upx = event.getx(); upy = event.gety(); mcanvas.drawline(downx, downy, upx, upy, mpaint); midivshow.invalidate(); //更新点位 downy = upy; downx = upx; break; case motionevent.action_up: //抬起点y>1100,清除笔迹 if (upy > 1100) { paint paint = new paint(); paint.setcolor(color.white); mcanvas.drawrect(0, 0, mpoint.x, mpoint.y, paint); } break; } return true; });
再升级版:lever3
笔触根据绘制的速度动态改变画笔粗细
float movingx = 0; float movingy = 0; private long lasttimestamp = 0l;//最后一次的时间戳
midivshow.setontouchlistener((view, event) -> { switch (event.getaction()) { case motionevent.action_down: lasttimestamp = system.currenttimemillis(); downx = event.getx(); downy = event.gety(); break; case motionevent.action_cancel: break; case motionevent.action_move: movingx = event.getx(); movingy = event.gety(); long curtimestamp = system.currenttimemillis(); //计算时间差 long detat = curtimestamp - lasttimestamp; //计算距离差 float detas = logic.dispos2d(movingx, movingy, downx, downy); //由于速度是 px/ms double v = detas / detat; //速度转化为画笔宽度的等式 float width = 14/(float)v; l.d(width + l.l()); //限制极值情况 if ((width > 0) && width < 30) { mpaint.setstrokewidth(width); } mcanvas.drawline(downx, downy, movingx, movingy, mpaint); midivshow.invalidate(); downx = movingx; downy = movingy; lasttimestamp = curtimestamp;//更新时间 movepos.add(new pointf(event.getx(), event.gety())); break; } return true; });
拓展
1.其中可以改变求宽度的等式实现不同的笔触:如
float width = (float) math.log10(v) * 40;
2.在图片上绘画
//图片原型 bitmap bitmap = bitmapfactory.decoderesource(getresources(), r.mipmap.iv_500x400); //图片副本 bitmap mnewbitmap = bitmap.createbitmap(bitmap.getwidth(), bitmap.getheight(), bitmap.getconfig()); //用副本生成canvas mcanvas = new canvas(mnewbitmap); mpaint = new paint(paint.anti_alias_flag); mpaint.setstrokecap(paint.cap.round);//直线圆头 mcanvas.drawbitmap(bitmap, new matrix(), mpaint); mpaint.setstrokewidth(10); mpaint.setcolor(color.parsecolor("#88164be6")); //设置副本图片到imageview midivshow.setimagebitmap(mnewbitmap);
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
上一篇: 深入理解 Koa 框架中间件原理