Android Canvas的drawText()和文字居中方案

自定义View是绘制文本有三类方法:

// 第一类
public void drawText (String text, float x, float y, Paint paint)
public void drawText (String text, int start, int end, float x, float y, Paint paint)
public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint)
public void drawText (char[] text, int index, int count, float x, float y, Paint paint)// 第二类
public void drawPosText (String text, float[] pos, Paint paint)
public void drawPosText (char[] text, int index, int count, float[] pos, Paint paint)// 第三类
public void drawTextOnPath (String text, Path path, float hOffset, float vOffset, Paint paint)
public void drawTextOnPath (char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)

说明:

  • drawText():最常用
  • drawPosText():是根据一个个坐标点指定文字位置
  • drawTextOnPath():是根据路径绘制。

其中drawText()的x,y参数是干嘛的呢?


先来看下下面这段代码的运行效果:

@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint paint=new Paint();paint.setStyle(Paint.Style.FILL);paint.setStrokeWidth(12);paint.setTextSize(100);String text="测试:my text";canvas.drawText(text, 200, 400, paint);//画两条线标记位置paint.setStrokeWidth(4);paint.setColor(Color.RED);canvas.drawLine(0, 400, 2000, 400, paint);paint.setColor(Color.BLUE);canvas.drawLine(200, 0, 200, 2000, paint);
}

左对齐-left

左对齐-left

可以看到,x,y并不是指定文字的中点位置,并且x,y与文字对齐方式有关(通过setTextAlign()指定,默认为left)


居中对齐-center

居中对齐-center

右对齐-right

右对齐-right

注:为了使文字完整,上面调整了下x,y的值。


从上面三种情况得出结论,x所对应的竖线:

  • 左对齐 — 文字的左边界
  • 居中对齐 — 文字的中心位置
  • 右对齐 — 文字的左边界

y对应的横线并不是文字的下边界,而是基准线Baseline

在这里插入图片描述

  • Top:文字的最顶部
  • Baseline:基准线
  • Bottom:文字的底部

那这些值如何获取呢?

	Paint.FontMetrics fontMetrics=paint.getFontMetrics();fontMetrics.topfontMetrics.ascentfontMetrics.descentfontMetrics.bottom

记得要在设置完Paint的文字大小,宽度之类属性后再获取FontMetrics,Baseline对应对应值为0,在它下面的descent和bottom值为正,top和ascent为负。

那文字的高度为: bottom - top

在这里插入图片描述
所以,实际绘制的时候取决于基线上一个点来绘制文字,而这个点有三种分别对应为left,center,right。

在这里插入图片描述
好啦,把drawText()中x,y参数讲清楚后实现文字居中就很容易了。

直接上代码:

@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);//矩形背景Paint bgRect=new Paint();bgRect.setStyle(Paint.Style.FILL);bgRect.setColor(Color.YELLOW);RectF rectF=new RectF(200, 200, 800, 600);canvas.drawRect(rectF, bgRect);Paint textPaint=new Paint();textPaint.setStyle(Paint.Style.FILL);textPaint.setStrokeWidth(8);textPaint.setTextSize(50);textPaint.setTextAlign(Paint.Align.CENTER);String text="测试:my text";//计算baselinePaint.FontMetrics fontMetrics=textPaint.getFontMetrics();float distance=(fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;float baseline=rectF.centerY()+distance;canvas.drawText(text, rectF.centerX(), baseline, textPaint);
}

效果:
在这里插入图片描述
将对齐方式设置为center,那要让文字居中显示,x值就为矩形中心x值,y值也就是Baseline的计算看下图:
在这里插入图片描述
y = 矩形中心y值 + 矩形中心与基线的距离

距离 = 文字高度的一半 - 基线到文字底部的距离(也就是bottom)= (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom

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

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

相关文章

IntelliJ IDEA配置Tomcat

查找该问题的童鞋我相信IntelliJ IDEA,Tomcat的下载,JDK等其他的配置都应该完成了,那我直接进入正题了。 1、新建一个项目 2、由于这里我们仅仅为了展示如何成功部署Tomcat,以及配置完成后成功运行一个jsp文件,我仅勾…

C++对于文件的相关操作 创建、读写、删除代码

创建 /*** brief 创建文件:在密码设备内部创建用于存储用户数据的文件* param pucFileName 缓冲区指针,用于存放输入的文件名,最大长度128字节* param uiNameLen 文件名长度* param uiFileSize 文件所占存储空间的长度*/void CreateFile(sdf_uint8_t…

Android开发之Path详解

目录一、xxxTo方法1、lineTo(float x, float y)2、moveTo(float x, float y)3、arcTo3.1、arcTo(RectF oval, float startAngle, float sweepAngle)3.2、arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)3.3、arcTo(float left, float top, float r…

git大文件拷贝代码命令

git clone 链接 --recursive

Android APK打包流程

目录一、概述二、打包流程1、打包资源文件,生成R.java文件2、处理aidl文件,生成相应的Java文件3、编译项目源代码,生成class文件4、转换所有的class文件,生成classes.dex文件5、打包生成APK文件6、对APK文件进行签名7、对签名后的…

使用openssl,实现输入和输出都是字符串的类型,注意:输入最好是16的倍数

头文件crypto_util.h #pragma once#include <string>namespace hsm{namespace mgmt{void get_md5_digest(const std::string &data,uint8_t result[16]);std::string aes_encrypt_to_string(const std::string &string,const std::string &password);std::s…

Android Studio 安装ASM插件

目录一、安装步骤1、Android Studio -> Preferences...2、Plugins -> Browse repositories...3、搜索ASM -> 选中要安装的插件 -> 右侧点击Install4、安装完后点击Restart Android Studio5、Android Studio重启后右侧会有个ASM图标6、找一个类右键 -> Show Byte…

使用openssl完成aes-cbc模式的数据加解密,输入和输出都是字符串的形式

代码 #include <cstring> #include <memory>#include <openssl/aes.h> #include <openssl/md5.h>namespace hsm{namespace mgmt{void get_md5_digest(const std::string &data,uint8_t result[16]){MD5_CTX md5_ctx{};MD5_Init(&md5_ctx);MD5…

Android 网络异常

目录前言一、UnknownHostException1、网络断开验证2、DNS 服务器意外挂掉验证3、DNS 服务器故障验证4、所需诊断信息二、ConnectTimeoutException三、SocketTimeoutException1、子错误 - 读超时2、子错误 - SSL 握手超时3、子错误 - 未知原因四、HttpHostConnectException1、服…

Android ViewRoot、DecorViewWindow浅析

目录简介目录1、VeiwRoot1.1、简介1.2、特别注意2、DecorView2.1、定义2.2、作用2.3、特别说明3、Window4、Activity5、之间关系5.1、总结5.2、之间的关系简介 DecorView为整个Window界面的最顶层View。DecorView只有一个子元素为LinearLayout。代表整个Window界面&#xff0c;…

Java集合Stream类

Java集合Stream类 ----按条件对集合进行过滤filter public class Test {public static void main(String[] args) {List<String>allnew ArrayList<>();all.add("ghjt");all.add("ghjiiii");Stream<String>streamall.stream();List<S…

使用openssl完成aes-ecb模式的数据加解密,输入和输出都是字符串类型

代码 #include <cstring> #include <memory>#include <openssl/aes.h> #include <openssl/md5.h>namespace hsm{namespace mgmt{void get_md5_digest(const std::string &data,uint8_t result[16]){MD5_CTX md5_ctx{};MD5_Init(&md5_ctx);MD5…

Java Stream MapReduce大数据开发模型

实现一个购买商品后,对数据进行处理统计的功能. 将购买的商品信息保存在Orders类中 public class Orders {private String name;private double price;private int amount;public Orders(String name, double price, int amount) {this.name name;this.price price;this.am…

随机函数的生成

函数代码 #include <string>bool GenerateRandom(std::string *str,unsigned int len) {srand(time(NULL));for(unsigned int i0;i<len;i){switch(rand()%3){case 1:(*str).push_back(Arand()%26);break;case 2:(*str).push_back(arand()%26);break;default:(*str).p…

Android 为控件设置阴影

在Android中设置一个阴影很简单&#xff0c;只需要两步&#xff1a; 设置eleavation值&#xff08;高度&#xff09;添加一个背景或者outline &#xff08;即阴影的形状&#xff09; 说明&#xff1a; View的大小位置都是通过x&#xff0c;y确定的&#xff0c;而现在有了z轴的…

Android在代码中设置drawableLeft(Right/Top/Bottom)

根据业务的需要&#xff0c;要在代码中设置控件的drawableLeft&#xff0c;drawableRight&#xff0c;drawableTop&#xff0c;drawableBottom属性。 我们知道在xml中设置的方法为&#xff1a; android:drawableLeft"drawable/xxxxx"但是在代码中并没有相关的setDr…

Java 冒泡排序

冒泡排序–时间复杂度n^2 对数组序列从前向后依次比较相邻两个元素的大小,若逆序则两个元素交换位置如果一趟下来没有发生交换,则说明序列有序,可以在序列中设置一个标志flag判断元素是否发生交换,从而来减少不必要的比较(在写完排序算法后再写)小结:一共进行数组大小-1次的外…

使用openssl开源AES算法,实现aes、aes-cbc和aes-ecb对字符串的加解密

注意事项 对于用户输入的密码进行了md5运算&#xff0c;从而保证数据格式的统一性 内部调用的随机函数&#xff0c;参考我的其他博文 参考链接 头文件crypto_util.h #pragma once#include <string>namespace hsm{namespace mgmt{void get_md5_digest(const std::strin…

Android学习指南

目录核心分析内容1、学什么1.1、Android基础 & 常用1.2、Android进阶1.3、与时俱进、热门技术1.4、编程语言&#xff1a;Java与Java虚拟机1.5、计算机基础1.6、总结2、怎么学2.1、学习路径&#xff1a;如何循序渐进、阶段性的学习Android的理论知识&#xff1f;2.2、获取途…

使用memcmp函数判断两个函数的前n位字节数是否相等

memcmp函数的介绍 头文件&#xff1a;#include <string.h>定义函数&#xff1a;int memcmp (const void *s1, const void *s2, size_t n);函数说明&#xff1a;memcmp()用来比较s1 和s2 所指的内存区间前n 个字符。字符串大小的比较是以ASCII 码表上的顺序来决定&#x…