Android自定义标签LabelView详细思路及过程

发布时间:2021-08-05 04:45:01

自定义LabelTextView

项目需要,实现一个圆角矩形加上标签的自定义View。大概的效果是这样的



难点
标签页的范围需要贴合圆角矩形的范围标签内的字体需要和和线*行以及各种坑
遇到问题和解决方式
标签文字
问题

按照需求,标签的文字需要斜着展示,而默认的方式只有水*展示


解决方式

标签文字的显示之前走了不少弯路,开始想到使用画布的旋转以及计算角度来实现文字的斜着显示.。
但是效果都不好。
后来发现一个更简单的方法,通过下面方法轻松实现


canvas.drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,
float vOffset, @NonNull Paint paint)

圆角矩形和三角形混合绘制
问题

绘制不规则图形,像是一个圆角矩形和一个三角形的超集在减去三角形不相交的那部分


解决方式

而圆角矩形的绘制,我采取了混合模式。


先通过path绘制一个三角形,再通过混合模式将三角形和圆角矩形重合区域之外给遮盖。
我称之为混合模式其实就是使用了方法。


path.op(Path path, Path.Op op)

借用一张图展示混合模式



以及小结


android.graphics.PorterDuff.Mode.SRC:只绘制源图像
android.graphics.PorterDuff.Mode.DST:只绘制目标图像
android.graphics.PorterDuff.Mode.DST_OVER:在源图像的顶部绘制目标图像
android.graphics.PorterDuff.Mode.DST_IN:只在源图像和目标图像相交的地方绘制目标图像
android.graphics.PorterDuff.Mode.DST_OUT:只在源图像和目标图像不相交的地方绘制目标图像
android.graphics.PorterDuff.Mode.DST_ATOP:在源图像和目标图像相交的地方绘制目标图像,在不相交的地方绘制源图像
android.graphics.PorterDuff.Mode.SRC_OVER:在目标图像的顶部绘制源图像
android.graphics.PorterDuff.Mode.SRC_IN:只在源图像和目标图像相交的地方绘制源图像
android.graphics.PorterDuff.Mode.SRC_OUT:只在源图像和目标图像不相交的地方绘制源图像
android.graphics.PorterDuff.Mode.SRC_ATOP:在源图像和目标图像相交的地方绘制源图像,在不相交的地方绘制目标图像
android.graphics.PorterDuff.Mode.XOR:在源图像和目标图像重叠之外的任何地方绘制他们,而在不重叠的地方不绘制任何内容
android.graphics.PorterDuff.Mode.LIGHTEN:获得每个位置上两幅图像中最亮的像素并显示
android.graphics.PorterDuff.Mode.DARKEN:获得每个位置上两幅图像中最暗的像素并显示
android.graphics.PorterDuff.Mode.MULTIPLY:将每个位置的两个像素相乘,除以255,然后使用该值创建一个新的像素进行显示。结果颜色=顶部颜色*底部颜色/255
android.graphics.PorterDuff.Mode.SCREEN:反转每个颜色,执行相同的操作(将他们相乘并除以255),然后再次反转。结果颜色=255-(((255-顶部颜色)*(255-底部颜色))/255)

但是很可惜的是, ==这个方法必须在API>19的时候才行== ,换言之需要采取别的方式来兼容下面的版本。
这个时候我选择了画布裁剪


public boolean clipPath(@NonNull Path path, @NonNull Region.Op op)

使用裁剪可以解决这个问题。


but,如果这样写会发现这样有一个很严重的bug,无论采取哪种Op模式,全部都不起作用。
这里涉及到在4.1以及一下版本有一个bug,Path相关的绘制会出现问题,包括不限于drawTextOnPath,
clipPath。


解决方法是:解决方法是在自定义View的构造函数里增加这一句话:


this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

这里也是参考前人的遇到的坑,之前搜到这个bug心里留了点心眼,没想到第二天就用上了(窃喜)。


不能使用drawable资源

这是一个很严重的需求问题。


现在的需求:是当我要点击item的时候,内部的字体和外面的边框颜色需要改变。
这些都是定义在drawable当中。


所以我现在的设计(继承View)都是不明智的。
当使用者使用会出现这种抉择:我需要使用select或者要通过shape绘制图以及press,这样就需要引用drawable资源
可是需要实现这样的话就需要传递引用,自定义View中还要添加额外的方法。


稳妥起见,只有忍痛割爱,重写整个类,让他继承与TextView。使用一个稳定的系统View总比自己写一个不稳定的好。


然后为了边界显示不冲突,将之前绘制圆角矩形的画笔设为透明


Label文字显示太粗糙
问题

这个时候的显示如下



Label文字默认是在中间的,即两点中线的位置。对于一个经常是宽度大于高度的Item来说不太友善。
稍微完善它


解决方式

没有什么比转化成视觉展示更加直观的方式了



(请自动脑补顺时针90度旋转上图)



所以就转化成为了一个初中三角函数的题目


解:省略N步


最后的公式是:


ps: w = width h = height

公式为:
if(w > h) {
(w^2 - h^2)/[2 * √(w^2 + h^2)]
} else if(w < h) {
(h^2 - w^2)/[2 * √(w^2 + h^2)]
}

用一个方法计算它


//允许负值
private float calculationOffset(double width, double height) {
if (width == height) {
return 0;
}

double molecule = Math.pow(width, 2) - Math.pow(height, 2);

double denominator = 2 * Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));

return double2Float(molecule / denominator);
}


具体代码和Demo见GitHub


https://github.com/aroundone/LabelTextView


欢迎提issue和star ^_^


参考

http://blog.csdn.net/jiangwei0910410003/article/details/50935468


https://ghui.me/post/2015/10/android-graphics-path/


http://whuhan2013.github.io/blog/2016/05/14/android-canvas-summary/


http://blog.csdn.net/yanzi1225627/article/details/8583066

相关文档

  • 天道有常,告诫自己,一定要上进
  • 后厨员工辞职报告怎么写-设计院员工辞职报告
  • 描写夜景的小学生作文
  • 二人合伙经营协议书通用范本
  • Selenide初步入门--打开google/baidu
  • 假如生活欺骗了你读书笔记范文
  • 老生常谈的java垃圾回收机制
  • 电商创业风险规避
  • 小学数学调研报告
  • 鱼丸怎样做好吃
  • 邛崃天台山自驾游攻略
  • 烧烤店开业经典广告词大全
  • 天人和梦雨心情日记
  • 梦见自己换衣服是好事吗
  • java并发面试题vol.1
  • 最长不上升子序列的优化(nlogn)
  • 吊梢眉的女人面相代表什么
  • 补码(为什么按位取反再加一):告诉你一个其实很简单的问题
  • Web前端初学者必学的6个知识点!
  • 冬天罗锡文的阅读理解题及答案
  • 给普通初中朋友空间的毕业留言
  • 如何通过dos命令修改系统时间
  • “如膜妄心应褪尽夜来无梦过邯郸“出处及含义
  • WPF异步MVVM等待窗体
  • 次世代3D游戏建模好学吗?工资怎么样?前景怎么样?
  • 京东三面面经
  • 春天的水果教案
  • java之UML状态机图
  • 社区书记换届选举述职报告五篇
  • 与数学实验第二版艾冬梅_2021届各省市11月最新(含期中)高三数学模拟试卷(14套)...
  • 猜你喜欢

  • 国家部委对4G调研:未定给中电信联通发放牌照
  • 2019年小学六年级数学京口区实验小学《倍的认识》课堂讲义_图文.ppt.ppt
  • 浅谈重点工程建设中的职务犯罪原因和预防对策
  • 在车床上加工畸形工件垂直轴承孔
  • 2020年教师新年祝福语
  • 有魔力的黑板
  • 论激励机制在当代国企人力资源管理中的运用
  • 科技部:与盖茨基金会签署战略合作备忘录
  • 两学一做学习教育活动总结
  • 山楂提取物对亚急性酒精性肝损伤辅助保护作用的研究
  • 励志感恩散文精选
  • 二年级课堂教学家长开放周活动安排
  • 滨河绿地景观规划设计论文
  • 2019高考备考数学选择填空狂练之 二十七 模拟训练七(文)-Word版含解析
  • 珠海华民贸易有限公司企业信用报告-天眼查
  • 计算机网络应用技术大作业
  • 淄博博山鲁哲耐火材料有限公司(企业信用报告)- 天眼查
  • 北师大版一年级数学上册期末试卷【A4打印版】
  • 天津市概况导游词
  • 我的妈妈不是伟人_小学作文
  • 出血性脑卒中继发癫痫的护理体会
  • 计算机实验中对虚拟机技术的运用
  • 浅谈setInterval(aa,1000)与setInterval(aa(),1000)的区别
  • 合肥方荣轻钢建材有限公司宿州分公司企业信用报告-天眼查
  • 家庭制作葡萄酒的方法 用冰糖自制葡萄酒做法
  • 2014防暑降温费多少
  • 断章 高中作文【1200字】_1
  • 2019年最新幼师辞职报告范文3篇-易修改word版 (2页)
  • 固安县水资源税改革的实践与探索
  • 2019-2020学年度六年级上数学期末考试试题(人教版)【2019版】
  • “班主任计划1”班主任工作计划
  • 浅议基层政府公信力不足的原因和策略
  • 2019-2020年北京市资格从业考试《社会工作综合能力(初级)》考前复*题含答案解析(第三十八篇)
  • 2018年运动员致辞讲话稿范文
  • Mellanox IB交换机SM HA
  • 2019精选教育年秋人教版中考英语复习课件:1人物介绍(共22张PPT).ppt
  • 【报告总结】2020最新大一学生学期工作总结
  • 那些容易被忽略的Python编程方式
  • 基于应用型人才培养目标的医学检验专业病理学教学改革探索
  • Bootloader 设计蓝图 和 ARM 的启动流程
  • APQP先期品质规划程序-文档资料
  • 医学心理学 心身疾病
  • 电脑版