android 获取画布,Android触摸事件如何实现笔触画布详解
前言
任何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);
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
android 获取画布,Android触摸事件如何实现笔触画布详解相关推荐
- android画布原理,Android触摸事件如何实现笔触画布详解
前言 任何View都有触摸事件,经常在自定义控件时重写setOnTouchListener 本篇通过手绘图片来讲述这个知识点,下面话不多说了,来一起看看详细的介绍吧 本篇分为三个等级:一览图: 直线 ...
- Android基础入门教程——2.3.1 TextView(文本框)详解
Android基础入门教程--2.3.1 TextView(文本框)详解 标签(空格分隔): Android基础入门教程 本节引言: 学习完Android中的六大布局,从本节开始我们来一个个讲解And ...
- Android Studio CPU profiler性能分析工具介绍和使用详解
Android Studio CPU profiler性能分析工具介绍和使用详解 CPU profiler介绍 Android Studio CPU 性能剖析器可实时检查应用的 CPU 使用率和线程活 ...
- Android studio 多渠道(多环境)打包grade配置详解
Android studio 多渠道(多环境)打包grade配置详解 场景:开发app,我们需要两套环境或者两套环境以上的apk,每套环境的apk分两个版本debug版和release版. 公司有套平 ...
- Android四大组件之——Activity的生命周期(图文详解)
转载请在文章开头处注明本博客网址:http://www.cnblogs.com/JohnTsai 联系方式:JohnTsai.Work@gmail.com [Andro ...
- android相册和拍照并裁剪图片大小,Android 拍照并对照片进行裁剪和压缩实例详解...
Android 拍照并对照片进行裁剪和压缩实例详解 本文主要介绍 Android 调用摄像头拍照并对照片进行裁剪和压缩,文中给出了主要步骤和关键代码. 调用摄像头拍照,对拍摄照片进行裁剪,代码如下. ...
- android自定义圆角进度条,Android自定义进度条的圆角横向进度条实例详解
1.本文将向你介绍自定义进度条的写法,比较简单,但还是有些知识点是需要注意的: invalidate()方法 RectF方法的应用 onMeasure方法的应用 2.原理 画3层圆角矩形,底层为黑色, ...
- Android Studio打不开虚拟机,两种情况详解
Android Studio打不开虚拟机,两种情况详解 文章目录 Android Studio打不开虚拟机,两种情况详解 1.VT-x is disabled in BIOS 2.Emulator文件 ...
- js 条码枪扫描_使用JavaScript获取扫码枪扫描得到的条形码的思路代码详解
下面通过实例代码给大家介绍js扫码枪扫描条形码的实现方法,具体代码如下所示: var keycode = ""; var lastTime=null,nextTime; var l ...
最新文章
- Android初始化过程
- centos 调整home分区xfs_Linux中对lvm逻辑卷分区大小的调整教程(针对xfs与ext4不同文件系统)...
- VMware 虚拟机 linux执行 ifconfig 命令 eth0没有IP地址
- Response.Write()方法响应导致页面内容变形的问题
- Git新建临时分支进行开发后合并至master
- nodejs+express整合kindEditor实现图片上传 - 木子丰咪咕晶 - 开源中国
- Windows上搭建EMQTT服务器
- 为什么jsp的form表单不能跳转_手把手教你实现SEM投放监控转化--表单类
- 惠普企业(HPE)是否免不了最终被关停的命?
- 一种基于说话人识别和数字语音识别的身份认证方法与流程
- weblogic部署启动时报错(weblogic.application.ModuleException)
- buuctf-misc部分wp(更新一下)
- ubuntu浏览器突然使用不了搜狗拼音法
- html京东下拉菜单设置,实现京东导航栏的下拉框
- springboot jpa 一对一级联查询
- Neo4j登录报错Neo4j Server shutdown initiated by request解决
- Unity 场景练习02 仿风之旅人
- 艾司博讯:拼多多客单价怎么提高
- 电脑C盘满了清理方法,电脑内存不足怎么解决
- 【正则化;岭回归、lasso回归】(转载)
热门文章
- python兔子编程_少儿编程分享:手把手教你用PYTHON编写兔獾大作战(一)
- docker-redis
- 输出字母在字符串中位置索引 python
- 3-3 uniapp、HTML5+、Native.js 功能代码汇总
- android开发--mp3播放器项目源代码(xml文件解析,.lrc,.mp3文件下载,同时显示歌词)
- 全文标明引文报告html,知网查重报告之全文(标明引文)报告单参数详解
- .net 5+ 知新:【2】 .Net Framework 、.Net 、 .NET Standard的概念与区别
- 救世之树服务端架设开服需要哪些东西
- Could not find or load main class org.apache.hadoop.mapreduce.v2.app.MRAppMaster
- 鸿蒙系统盲测,小米5S重磅领衔:一图看懂小米2016秋季新品发布会!