Android 自定义标签 ViewLayout
自定义viewLayout实现标签View,UI的效果图如下:
如图,我们要自己实现带描边的,带花括号的,带三角形,带对勾的这样一个layout ,并且对勾和中间的虚线我们都要用最基础的API绘制出来,
也许你觉得,这不就是一个背景,干嘛要去自定义,哈哈哈 那我告诉你,因为笔者闲的……… 好了开个玩笑,这个背景如果用.9图我不知道会不会失真,.9的基准点如何绘制, 如何保证绿色的三角形,和里面的对勾不拉伸,
还有我其实不会制作.9图,既然遇到问题,就换一种解决方式, 我们自己绘出来这个背景不就行了… 和上一篇自定义动画button一样,也就不到200行代码,我们就能绘制出来这个标签Layout, 链接如下:自定义登陆动画button
国际惯例,先看下效果,我们自定义有一个什么好处,就是我们自定义的属性,可以根据比例还绘制,这样我们绘制的三角和对勾以及虚线和中间的半圆都可以不失真. 效果如下:
好像看着还行哦,我们可以用不同的颜色来绘制三角形当做标签的分类,
我们也可以提供隐藏三角形的方法,
你可能觉得 这和一张.9图有什么区别呢, 那么我们来改变下view的大小 看看效果
当我们的viewlayout变成正方形或者wrap_content或者machparent的时候 圆点和对勾还是根据变化后的尺寸来绘制的..
好的那么就来实现这个viewlayout
- 添加自定义属性
我们在attr里面提供了对外面暴漏的属性,可以方便我们改变一些UI上的值
- 增加默认的style文件属性
这个style意义其实并不是必须的,这个style用到view中,如果我们声明的自定义属性过多,但是我们并不是全部需要特殊的设置,我们提供一个默认的style,那么我们在xml里面只需要写宽高属性就行了,如果有默认的style满足不了你的需求,比如三角你要换成紫色,那么你就另外加一个app:triangleColor="紫色"就行了
- 新建自定义view的类,继承layout
- 在构造函数中获取自定义属性的值
上面基本都是模板代码了,没上面可以说的
- 我们修改下onMeasure方法,让我们的view支持warp_content
在onMeasu中拿到view的不同测量模式,然后进行,判断,如果不是 EXACTLY模式,我们就给view的宽高一个默认的值
- 确定View在当前测量模式下的宽高
我们在这个重载的方法中能获取到我们view的宽和高
- 剩下的就是我们的onDraw方法 从效果图来看我们需要绘制
- 矩形背景
- 矩形描边
- 中间的虚线
- 两边的半圆
- 右上角的三角形
- 三角形中间的对号
由于绘制的东西比较多,我们来看下一些具体的API和知识点
- 学习canvas的绘制文字
- 学习canvas的绘制矩形
- 学习canvas的绘制path
大概就这么多知识点 我们来看下onDraw方法中
这里有个小技巧,描边要比背景大,所以我们先绘制描边的图层,再绘制背景图层,
代码如下 绘制描边的代码
绘制背景代码
这里的绘制的代码特别简单,关键的思维是计算两个矩形的RectF 我们在attrs里面获取了描边的宽度, 那么我们绘制的背景宽度就应该是 View的宽 - 2倍描边的宽度 背景的高度应该是view的高- 2倍描边的宽度
所以我们在onSizeChangeed中计算出来两个矩形的RectF
这样就可以在onDraw中绘制了
接下来我们来绘制中间的虚线,大家都知道 paint画笔有一种虚线的模式
我们给画笔设置了Effecte 然后drawLine的时候在XML布局预览中发现虚线生效了,但是…但是 当你run到手机上发现 虚线和预览的不一样,还是直线,
注意画虚线不要用drawLine方法,当你设置了画笔的effecte后,绘制直线请用drawPath才会生效,才能和预览的XML中显示一致,这里一定要注意 **
绘制虚线用drawPath
**
然后我们绘制两边的透明半圆,这里绘制透明带描边的半圆,我用了一个小技巧, 其实我没有设置画笔的擦除模式来绘制,我选择了里面的小圆颜色和我们所处的item的背景色一个颜色,然后里面的描边大圆用了另外一种颜色,这样一个视觉感官可以给用户造成这种中间是透明的,只有虚线的半圆效果
代码如下 我们拿到虚线所处的 y坐标,然后用 坐标(0,y) 和(view的宽度,y)分别作为两个圆的圆心然后用canvas.drawCircle(),完成圆形的绘制, 也有读者可能疑问,为什么绘制了一个圆 ,能显示半圆呢,注意我们的坐标,这样的坐标圆的另外一部分是超出View的所以不显示,正好留下了我们要显示的半圆,又因为我们设置了圆的颜色和Item背景色一样,ok到此我们的小半圆也完整的绘制出来了
现在大部分工作已经做完了,整下的就是顶部的那个三角形了, 绘制三角形,我们采取path 和用比例的方式来绘制 首先定义三角形两个直角边的宽度和高度比例
然后计算三角形的path坐标
这样我们就计算出来了三角形的path, 然后我们就是绘制了
最后一步就是那个直角的对勾了,对勾也是path,由于计算的不够精确我就大概把对勾的起点放置到了我们刚才绘制的三角形的终点,对勾的绘制我跟UI沟通发现是一个十字架然后旋转,延伸了另外一条边,
ok我们来计算这个path, 绘制这个对勾的path涉及到初中的一些数学知识,太高端我也不会,毕竟只有初中毕业
首先弧度和角度的转换, 然后就是知道斜边和角度求,对边和临边,就是cos和sin的知识 **
注意Android里面的参数是弧度,
**
计算和微调的代码就直接贴出来了,大家自己看看,其实蛮简单的
最后我们绘制对勾的path
OK到此我们的自定义标签view全部定制结束了,由于微信对于代码支持不太友好,所以完整的代码还请大家点击阅读原文,去原作者博客查看和索取,有兴趣的可以导入到AS中看下效果。
有兴趣想要源码工程的同学,可以留言,我会上传到github后,把地址补充到评论中,包括上一篇的自定义动画view的源代码 谢谢各位捧场!!
- 零代码如何打造自己的实时监控预警系统
- 一步一步在Windows中使用MyCat负载均衡 上篇
- 你真的会玩SQL吗?之逻辑查询处理阶段
- javascript中如何正确将日期(Date)字符串转换为日期(Date)对象?
- 全面迎接.Net3.0时代的到来(WCF/WF/WPF/LINQ)
- SQL Server 2005 正则表达式使模式匹配和数据提取变得更容易
- [基础]datagridview绑定数据源的几种常见方式
- c#:winform鼠标拖动窗口大小时,设定窗口最小尺寸
- 在非SqlServer数据库上实现MemberShip和Role功能(自定义MemberShipProvider和RoleProvider)
- 一种实用的表格行鼠标点击高亮效果
- Lucene:QueryParser中操作符的疑惑
- 利用Boost影响Lucene查询结果的排序
- 利用Boost影响Lucene查询结果的排序
- linq to sql取出随机记录/多表查询/将查询出的结果生成xml
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 记一次Fcitx5的安装
- 解决KDE下KDE Wallet重装系统后每次登陆需要输入密码
- KDE下完美的Unity桌面体验,扔掉active window control
- C++核心准则T.5:结合使用泛型和面向对象技术应该增强它们的效果而不是成本
- C++核心准则T.10:为所有的模板参数定义概念
- C语言二级指针用法之模拟句柄用途
- Linux解压缩文件
- C++核心准则T.11:只要可能就使用标准概念
- 给pugjs的stun主题添加canvas时钟
- C++核心准则T.12:声明局部变量类型时,概念比auto更好
- Arch Linux切换rEFInd开机引导程序
- C++核心准则T.13:对于简单的,单类型参数概念,使用缩略记法更好
- VBA编写Ribbon Custom UI编辑器08——实现ZIP的写入
- 用 Python 写个七夕表白神器
- 3分钟短文 | Laravel 用户授权原来内置了这么多方法