Android自定义有限制区域图例角度自识别涂鸦工具类中篇
作者:似曾相识2022 发布时间:2021-06-16 16:21:46
引言
上文Android:实现一个自定义有限制区域的图例(角度自识别)涂鸦工具类(上)中我们已经实现了自定义View签名的功能,包含撤回、清除方法。但我们最终要实现的功能还不止如此,这篇我们就来说说给限制区域内签名的实现过程。
试想,既然是自定义View了,那么如果要限制用户在指定区域内签名,最好的办法不是在触摸的时候通过坐标点的判断添加一些拦截吗?没错,起初我也是这么想的,但是再看到限制区域的图形后,我陷入了深深的沉思......
没错,就是这样的图,这还是其中的一张,后期指不定还会有多少张这样形状复杂的图。单看组成就不得了,都是些大小不一的圆相交相切,圆心散落在各个位置。但从自定义角度绘制这样的图形相信难度也不小,就更不要说通过坐标点的计算来拦截触摸事件的方式限制签名范围了。
此时绝望的我突然想起之前项目中的一个上传图片功能,当时是利用了ViewGroup作为遮罩来简单实现的,那么,这个功能其实也可如此。我们大可不必大费周章的采用触摸事件判断呀,超出范围如果使用画布遮挡其实也能满足。结合项目需求最后涂鸦完成后,需要生成图片,我们也可通过View自带的Draw方法生成图片,咱们说干就干。
首先,自定义一个ViewGroup(作为遮罩、生成图片使用)
class FaceViewGroup(context: Context, attrs: AttributeSet? = null) :
LinearLayout(context, attrs, 0) {
private var mWith = 0
private var mHight = 0
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
mWith = MeasureSpec.getSize(widthMeasureSpec)
mHight = MeasureSpec.getSize(heightMeasureSpec)
}
override fun dispatchDraw(canvas: Canvas?) {
......
}
}
这里我们需要了解下dispatchDraw方法:
绘制 ViewGroup 中的子 View 时,会调用 dispatchDraw(Canvas canvas),需要注意的是,是在绘制 ViewGroup 自己之后,也就是在 onDraw(Canvas canvas) 之后。
最后才会触发这个方法,所以利用它绘制遮罩再合适不过,我们可以让UI将各种复杂的图形切出来保存再本地,再利用dispatchDraw方法中的画布将图片绘制在中心。切图时需要注意,我们需要绘制的区域需要透明。
//本地区域图
val bitmap = BitmapFactory.decodeResource(resources,R.mipmap.ic_face)
//绘制到ViewGroup中
canvas?.drawBitmap(bitmap, (mWith-bitmap.width)/2f, (mHight-bitmap.height)/2f, Paint().apply {
color = Color.WHITE
isAntiAlias = true
style = Paint.Style.FILL
})
在Xml:
<com.example.FaceViewGroup
android:id="@+id/group"
android:layout_width="414dp"
android:layout_height="280dp">
<com.example.SignatureView
android:id="@+id/linePath"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="2dp" />
</com.example.FaceViewGroup>
SignatureView就是我们上篇讲到的自定义View,运行起来发现效果还不错,确实实现了限制的问题,虽然不是真正意义上的限制,但效果一样,满足需求了。最后生成图片:
val bitmap: Bitmap = Bitmap.createBitmap(
resources.displayMetrics,
binding.group.width,
binding.group.height,
Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
binding.group.setBackgroundColor(ContextCompat.getColor(this, R.color.white))
//解决白底问题
canvas.drawRect(
Rect(
0,
0,
bitmap.width,
bitmap.height
), Paint().apply {
color = Color.WHITE
style = Paint.Style.FILL
})
binding.group.draw(canvas)
这里说下,如果不设置背景色,通过View的draw方式生成的图片是黑底的。另外还有个值得注意的点,如果使用了三方ui适配方案,你会发现无论怎么调整视图和Bitmap最后生成的图片和实际绘制看到的图片存在问题—绘制的内容偏离了限制区域,最终发现需要进行适配,也就是这一步,参考资料:
//这里需要添加resources.displayMetrics才能适配宽高
val bitmap: Bitmap = Bitmap.createBitmap(
resources.displayMetrics,
binding.group.width,
binding.group.height,
Bitmap.Config.ARGB_8888
)
最开始一直以为是横竖屏的切换导致位置偏移,实则是使用了AndroidAutoSize使得尺寸发生变化,所以在创建Bitmap时需要将适配过后的displayMetrics传入。到此,我们就完成了异性区域内涂鸦功能。
来源:https://juejin.cn/post/7202625823668715577


猜你喜欢
- A-PC端:1-页面--multiple是控制单张还是多张图片上传<input id="BusRoute" typ
- @CacheEvict无法解决分页缓存清除当下比较热门的spring缓存就是encache,但是最近在写毕业设计的时候,发现了在缓存分页的时
- 1. Mybatis分页插件1.1 分页插件介绍分页可以将很多条结果进行分页显示。如果当前在第一页,则没有上一页。如果当前在最后一页,则没有
- 1、匿名内部类内部类:在一个类的内部定义了另外的类,称为内部类,匿名内部类指的是没有名字的内部类。为了清楚内部类的主要作用,下面首先观察一个
- 一、Maven项目使用步骤一般包含两步,1)引入依赖 2)特定的 IDE 引入对应的插件1)在POM中引入依赖<!-- https:/
- 整理文档,搜刮出一个java实现向有序数组中插入一个元素,稍微整理精简一下做下分享package cn.jbit.array; import
- 在Java的逻辑运算符中,有这么四类:&&(短路与),&,|,||(短路或)。&&和&都是表
- 1、 WIFI网卡的状态WIFI网卡的状态信息都以整型变量的形式存放在 android.net.wifi.WifiManager 类中,有以
- Spring事务传递机制原理首先,我们通过org.springframework.transaction.annotation.Propag
- 1、字符数组的定义与初始化字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素。char str[10]={ 'I'
- 本文实例为大家分享了java生成随机字符串的具体代码,供大家参考,具体内容如下import java.util.Random;public
- 发现问题肯定有人发现连接mysql失败,然后又找不到问题所在,又出现一大最报错,如下图。解决过程 1.先查询自己的java版本,在
- Spring定时任务无故停止又不报错一开始是使用Spring自带的定时器来配置定时任务的,简单快捷,配置如下:<bean id=&qu
- 如果所有的键都是小整数,我们可以使用一个数组来实现无序的符号表,将键作为数组的索引而数组中键 i 处存储的就是它对应的值。散列表就是用来处理
- 下文笔者讲述StringTokenizer对象的简介说明,如下所示StringTokenizer的简介Java StringTokenize
- 1、什么是序列化与反序列化?序列化:指把堆内存中的 Java 对象数据,通过某种方式把对象存储到磁盘文件中或者传递给其他网络节点(在网络上传
- 本文实例为大家分享了android九宫格可分页加载控件的具体实现代码,供大家参考,具体内容如下github地址基本思路是viewpager+
- 网上android播放器虽然挺多,感觉提供的歌词显示功能比较死板,要么搜索给的条件死死的,要么放置sdcard内部的歌词格式需要统一,应该提
- 前几天在“Android绘图之渐隐动画”一文中通过画线实现了渐隐动画,但里面有个问题,画笔较粗(大于1)时线段之间会有裂隙,我又改进了一下。
- 在平常工作中我们经常会遇到maven引用的jar包冲突的事情,这时候我们就需要找出冲突的包,并将低版本或者缺少某些方法的jar给剔除掉。这个