安卓文字绘制和歌词器的简单实现

文章目录

  • 安卓绘制文本的细节和歌词动画实战
    • 绘制简单文本
      • 绘制API
      • 绘制线
        • 设计多条线的原因
    • 中心绘制
      • x轴居中
        • align居中
        • 宽度居中
      • 正中心绘制
    • 动画绘制
      • 原理
      • 过度绘制
      • 解决过度绘制
    • Demo点赞评论找我要哦

安卓绘制文本的细节和歌词动画实战

绘制文本有许多细节,这篇文章从绘制最简单的文字开始,到绘制的具体细节,再到歌词动画实战进行讲解

绘制简单文本

先绘制一个简单的文本,定义一个继承自AppCompatTextView的类MyTextView,在activity_main中进行使用

绘制API

文字是通过CanvasdrawText方法进行绘制的,在MyTextView中需要重写onDraw调用drawText进行绘制,解析一下drawText的参数

CanvasdrawText在父类里实现

BaseCanvas#drawText

//text 会问的文本
//x,y 在哪开始绘制
//paint 画笔
public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {super.drawText(text, x, y, paint);
}

绘制文字是需要画笔的,我们在MyTextView定义一个画笔,在构造中对画笔进行初始化,可以通过调用setColor, setTextSize之类的方法修改画笔的颜色,绘制文字的大小等等,然后在onDraw中调用

canvas.drawText("hbsd", 0, 0, mPaint);

发现一个问题,文字并没有绘制,这是为什么呢?

其实绘制文本的时候有他自己的规则,drawText的参数有y,是文字基准线的意思,我理解为四线三格的第三条线,传入0 的话,意思就是这个第三条线的纵坐标是0,也就意味着文字都写到屏幕上边去了,如果我们把y值设的大一点就发现文字出现了。

绘制线

既然安卓在设计绘制文字的时候是按照四线三格来做的,那么也就意味着不可能只有一条线,他还有很多线(线其实也不是线,就是距离吧,这里按线理解),ascent,bottom,descent,leading,top,还有基准线,他们这几个单词都是代表距离基准线的距离,往上为负数,往下为正数。

设计多条线的原因

说一下我自己的理解,我们当初为啥有四线三格,就是为了规整字母的大小

文字是多种多样的,四线三格也只是对于英文字母来说的,对于中文来讲就是田字格,每种文字的规范都不同,所以安卓设计出很多线来定义你要绘制的这段文字的规范。

先看图:

img

线的含义:

  • top

    所有文字的最顶端,所有类型的文字都不可能超过top

  • ascent

    大部分文字的顶端,低于top,可能有一些文字会超过ascent

  • base

    基准线,0线

  • descent

    大部分分子的底端,高于bottom,可能会有一些文字超过descent

  • bottom

    所以文字的最低端,所有类型的文字都不可能比bottom还低

  • leading

    图中没有画出来,含义是上一行的descent与下一行的ascent之间的距离

中心绘制

在屏幕中心绘制文本,注意我在activity_main定义的MyTextViewwidthheight都是match

x轴居中

canvas.drawText("hbsd", getWidth()/2, 100, mPaint);

上边代码是不能生效的,它绘制的效果是

因为他的x是宽度的一半,默认在最左边绘制

下面演示正确方式

align居中

给画笔设置TextAlign属性,他默认是left的,也就是上边错误的原因

mPaint.setTextAlign(Paint.Align.CENTER);

宽度居中

根据文字的宽度来设置drawTextx参数

//测量文字的宽度
float fontWidth = mPaint.measureText(mStr);
//往左平移一半宽度
float left = width/2 - fontWidth/2;
//绘制文字
canvas.drawText(mStr, left, 100, mPaint);

正确效果

正中心绘制

中心居中,也就是xy轴全部居中,上边解决了x轴居中,现在解决y轴居中

mPaint.setTextAlign(Paint.Align.CENTER);
mPaint.setTextSize(70);
float baseline = getHeight()/2;
canvas.drawText("河北师大", width/2, baseline, mPaint);

上方代码效果

发现文字的文职在中心线偏上,因为这是根据基准线来的
上面讲述了很多距离,根据距离可以尝试推导居中公式

这里我按照大部分的文字的规范来说,也就是accentdecent分别代表文字的顶端和底端

先找到最底部,也就是 getHeight()/2 - decent

然后往上平移一半高度 getHeight()/2 - decent + (decent - accent)/2

最后推导得出 getHeight()/2 - (decent + accent)/2

修改上面代码:

这里想要拿到descentascent需要通过FontMetrics类,FontMetrics直接调用Paintapi就可以获取

 mFontMetrics = mPaint.getFontMetrics();float baseline = getHeight()/2 - (mFontMetrics.descent + mFontMetrics.ascent)/2;

正确效果图

动画绘制

现在实现歌词器效果,效果如下:

原理

Canvas是可以分层的Canvas提供两个API支持分层saverestore,两个方法中间绘制的就是独立的一层,而且Canvas是支持裁剪的,这样的话,我们可以给下面的图层绘制黑色,上面的图层绘制红色,然后根据属性裁剪红色的Canvas,让它从左至右,裁剪的区域越来越大,也就最终实现了上面的效果,下面是代码实现

//width和height是整个view的宽高,在onDraw中线调用drawCenterText再调用drawCenterTopText
private void drawCenterText(Canvas canvas) {canvas.save();mPaint.setTextAlign(Paint.Align.CENTER);mPaint.setTextSize(150);mFontMetrics = mPaint.getFontMetrics();float baseline = getHeight()/2 - (mFontMetrics.descent + mFontMetrics.ascent)/2;canvas.drawText(mStr, width/2, baseline, mPaint);canvas.restore();
}
//mPercent是属性动画的改变属性,百分比
private void drawCenterTopText(Canvas canvas) {canvas.save();mRedPaint.setTextSize(150);mFontMetrics = mRedPaint.getFontMetrics();//测量字体宽度float fontWidth = mRedPaint.measureText(mStr);float left = width/2 - fontWidth/2;float right = left + fontWidth*mPercent;//居中公式float baseline = height/2 - (mFontMetrics.descent + mFontMetrics.ascent)/2;//裁剪区域Rect rect = new Rect((int)left,0, (int)right, (int)height);//裁剪canvascanvas.clipRect(rect);//绘制文字canvas.drawText(mStr, left, baseline, mRedPaint);canvas.restore();
}

这样写存在问题,过度绘制

过度绘制

过度绘制就是一个像素点被多次绘制,也就是说画布叠加绘制了,层数不多对手机影响不大,如果说很多层就会导致掉帧等问题

在开发者选项中可以开启过度绘制调试对ui进行优化

开启调试后我们的app就变得花花绿绿了,这里说明一下颜色的显示规则:

  • 蓝色:绘制 1 次
  • 绿色:绘制 2 次
  • 粉色:绘制 3 次
  • 红色:绘制 4 次或更多次

查看demo的颜色显示

显示为绿色,代表着绘制了两次,我们需要进行优化

解决过度绘制

人眼看到的永远只有最上边一层的不透明的Canvas,下层看不见的话就需要裁剪掉,根据上面代码可知,上层红色是根据属性动画往右逐渐显示的。那么下层的黑色是否也可以借助属性动画慢慢消失呢?

代码如下,只需要替换上面的drawCenterText方法即可

private void drawCenterTopText(Canvas canvas) {canvas.save();mRedPaint.setTextSize(150);mFontMetrics = mRedPaint.getFontMetrics();float fontWidth = mRedPaint.measureText(mStr);float left = width/2 - fontWidth/2;float right = left + fontWidth*mPercent;float baseline = height/2 - (mFontMetrics.descent + mFontMetrics.ascent)/2;Rect rect = new Rect((int)left,0, (int)right, (int)height);canvas.clipRect(rect);canvas.drawText(mStr, left, baseline, mRedPaint);canvas.restore();
}

变成蓝色说明没有过度绘制

Demo点赞评论找我要哦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/61936.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

歌词同步

歌词同步 前面的话歌词同步的需求歌词加载歌词显示歌曲播放时歌词的滚动计算歌词滚动范围如何同步歌词的滚动细节计算 鼠标拖拽时歌词的滚动自由滚动歌词 源码 前面的话 最近发现我们班同学做了一个很酷的Demo,这个Demo实现了一个很不错的歌词同步,着实…

终于等到你!Guitar Pro 8.1版本简谱功能首发

Guitar Pro是一款非常流行的音乐制谱软件它不仅适用于吉他谱还可以用于其他乐器的制谱。历经5年多时间研发Guitar Pro 在2022年正式发布了全新的8系列版本时隔不到1年Guitar Pro又给广大中国用户带来期盼已久的简谱功能下面让我带领大家一起体验吧 软件souurl.cn/BPln7d 图1 G…

人工智能火爆 国内这几家计算机视觉公司值得关注

 人工智能自降生以来就仿佛自带光环、备受瞩目。尤其是今年,国务院印发的《新一代人工智能发展规划》中提出,到2030年使中国人工智能理论、技术与应用总体达到世界领先水平,成为世界主要人工智能创新中心&#xff0c…

国内最值得关注的10家人工智能语音识别公司

在谈人工智能的时候,一定不能不谈语音识别,语音识别是人机交互的入口,是指机器/程序接收、解释声音,或理解和执行口头命令的能力。目前国内外都有公司在语音领域有所投入,其中包括才成立几年的初创企业,也包…

运气好到了一品

今天运气好,连续几把都赢了,一口气从布衣五品冲上了智贤一品,纪念一下。

到了智贤一品

朋友今天运气不错,今天连续打几把,都赢了,所以品级从智贤五品一路升级到了智贤一品,他很开心😁。

之伏一品纪念

昨天运气不错,玩了几把,结果巴巴赢,从智贤一品升级到了之伏五品,之伏往升级的需要赢的次数就更多了,我感觉自己没啥希望了,有一个已经非常满足了。因为再过两个月会重新排名,重新从零开始升级。…

每周一品 · 永磁联轴器 Magnetic Couplings

永磁联轴器(Magnetic Couplings)是通过永磁体的磁力将原动机与工作机联接起来的一种新型联轴器,它无需直接的机械联接,而是利用永磁体之间磁耦合,利用磁场可穿透一定的空间距离和物质材料的特性,进行机械能…

生活随记-斗地主直线一品

今天运气很好,进阶到了直线一品,记录下这个历史时刻吧

java毕业设计闲一品交易平台(附源码、数据库)

项目运行 环境配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: Springboot mybatis Maven Vue 等等组成,B/…

springboot闲一品交易平台系统(文档+源码)

大家好,我是火旺技术,一个混迹在java圈的码农,今天要和大家聊的 是一款基于springboot的闲一品交易平台系统网站,项目源码请联系火旺,目前有各类成品 毕设 javaweb ssh ssm springboot等等项目框架,源码丰富,欢迎咨询。…

每周一品 · 海尔贝克阵列 Halbach Array

海尔贝克阵列(Halbach Array、Halbach permanent magnet)是一种磁体结构,1979年美国学者Klaus Halbach在做电子加速实验时发现了这种特殊的永磁体结构并逐步完善,最终形成了“Halbach”磁体,它是工程上近似理想的结构&…

Spring系列一品境之指玄境

Spring系列复习(二) 相关导航 Spring系列一品境之金刚境 Spring指玄境导航 Spring系列复习(二)前言一、总思维导图二、Mybatis1、起因2、框架3、开发3.1 原始DAO方法3.2 Mapper代理方法3.3 输入输出映射3.4 动态SQL3.5 SpringBoot…

有道云笔记·协作android版,【每天一品】有道云笔记协作

有道协作是有道云笔记刚出的一个产品,作为内测用户,我为什么会使用它当做我团队协作的一个工具?在知乎上有一个问题叫做新人如何去学习产品思维,有位资深产品经理聊到,新人不要去研究已经完美的产品,去研究…

程序员光学技术还不够?推荐一份运营书单给你品一品

今天总结的这份【好书推荐】,你都不能错过~ ​ 读书从来不是一件非常简单的事情,无论你是想学运营还是学什么其他别的东西,如何真正有效地阅读一本书,如何坚持通过读书的方式来获取知识都是至关重要的,而这两个问题的…

Spring系列一品境之金刚境

Spring系列复习(一) 相关导航 Spring系列一品境之金刚境 Spring金刚境导航 Spring系列复习(一)前言一、Spring全家桶学习路线1、 思维导图 二、系列基础概念梳理1、Spring1.1 Bean1.2 Injection(注入)1.3 D…

一品黄山 天高云淡

图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App 图片发自简书App …

一品多码商品档案建立,相同商品有多个不同的条码的进销存管理

一品多码 就是某个商品,可能存在多个条码。 比如:王老吉瓶装500ml,货号:000001,主条码:6956367338666 另外还有条码:69100000000001;69100000000088,都代表是&#xf…

hrbust 2340 一品五彩

一品五彩棒 Time Limit: 2000 MSMemory Limit: 256000 K Total Submit: 22(5 users)Total Accepted: 2(2 users)Rating: Special Judge: No Description 公元2017年11月19日,王权熊熊和东方平平因为妖馨斋出品的“一品五彩棒”棒棒糖大打出手。王权熊熊祭出神剑王权…