自定义控件之绘图篇( 五):drawText()详解

本文详细介绍了在Android自定义控件中使用canvas.drawText()进行文字绘制的相关知识,包括四线格与基线的概念、drawText()函数的用法、文字的对齐方式以及如何获取所绘文字的宽度、高度和最小矩形。同时,通过实例展示了如何定点写字,并探讨了FontMetrics类在计算文字四线格位置中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:但行好事,莫问前程。只需努力每一天。

 

相关文章:

《Android自定义控件三部曲文章索引》:  http://blog.csdn.net/harvic880925/article/details/50995268

long long ago,有讲过有关Canvas绘图的系列知识,当时着重在基本绘图要领和canvas的保存与回退上,对drawText没有细讲,但DrawText这个函数,确是相当复杂,这里开一篇重新讲解一下。

一、概述

 

1、四线格与基线

小时候,我们在刚开始学习写字母时,用的本子是四线格的,我们必须把字母按照规则写在四线格内。
比如:

 

那么问题来了,在canvas在利用drawText绘制文字时,也是有规则的,这个规则就是基线!
我们先来看一下什么是基线:

可见基线就是四线格中的第三条线!
也就是说,只要基线的位置定了,那文字的位置必然是定了的!

2、canvas.drawText()

(1)、canvas.drawText()与基线

下面我们来重新看看canvas.drawText()这个函数,有关drawText的所有drawText()函数的基本用法,在文章《android Graphics(二):路径及文字》中已经讲过,这里就不再一一讲解,只拿出一个来讲解下drawText与基线的关系:

 

 

/**
* text:要绘制的文字
* x:绘制原点x坐标
* y:绘制原点y坐标
* paint:用来做画的画笔
*/
public void drawText(String text, float x, float y, Paint paint)

上面这个构造函数是最常用的drawText方法,传进去一个String对象就能画出对应的文字。
但这里有两个参数需要非常注意,表示原点坐标的x和y.很多同学可能会认为,这里传进去的原点参数(x,y)是所在绘制文字所在矩形的左上角的点。但实际上并不是!比如,我们上面如果要画"harvic's blog"这几个字,这个原点坐标应当是下图中绿色小点的位置

 

在(x,y)中最让人捉急的是y坐标,一般而言,(x,y)所代表的位置是所画图形对应的矩形的左上角点。但在drawText中是非常例外的,y所代表的是基线的位置!

(2)实例

下面我们就举个例子来看一下drawText中,原点坐标(x,y)的位置。
1、首先,新建一个工程blogDrawText,然后自定义一个View:MyView

 

 

public class MyView extends View{

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

2、重写onDraw函数:
我们重写MyView的onDraw函数,自定义一个基线,然后利用drawText画出来:

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

	int baseLineX = 0 ;
    int baseLineY = 200;
    
    //画基线
    Paint paint = new Paint();
    paint.setColor(Color.RED);
    canvas.drawLine(baseLineX, baseLineY, 3000, baseLineY, paint);

    //写文字
    paint.setColor(Color.GREEN);
    paint.setTextSize(120); //以px为单位
    canvas.drawText("harvic\'s blog", baseLineX, baseLineY, paint);
}

在这里,先定义drawText原点的位置:(0,200)
首先,我们把(0,200)所在的这条横线画出来,所以我先画了一条线从点坐标为(0,200)到点坐标为(3000,200)的一条直线
然后利用canvas.drawText以(0,200)为原点画出文字
3、在main.xml中添加使用代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
        >

    <com.example.blogDrawText.MyView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            />
</LinearLayout>

效果图如下:

 

结论:

  • 1、drawText是中的参数y是基线的位置。
  • 2、一定要清楚的是,只要x坐标、基线位置、文字大小确定以后,文字的位置就是确定的了。

 

3、paint.setTextAlign(Paint.Align.XXX);

在上面我们讲了,drawText()函数中的Y坐标表示所要绘制文字的基线所在位置。从上面的例子,我们可以看到,我们绘图结果是在X坐标的右边开始绘制的,但这并不是必然的结果。
我们来看一张图:

 

我们知道,我们在drawText(text, x, y, paint)中传进去的源点坐标(x,y);其中,y表示的基线的位置。那x代表什么呢?从上面的例子运行结果来看,应当是文字开始绘制的地方。
并不是!x代表所要绘制文字所在矩形的相对位置。相对位置就是指指定点(x,y)在在所要绘制矩形的位置。我们知道所绘制矩形的纵坐标是由Y值来确定的,而相对x坐标的位置,只有左、中、右三个位置了。也就是所绘制矩形可能是在x坐标的左侧绘制,也有可能在x坐标的中间,也有可能在x坐标的右侧。而定义在x坐标在所绘制矩形相对位置的函数是:

 

/**
* 其中Align的取值为:Panit.Align.LEFT,Paint.Align.CENTER,Paint.Align.RIGHT
*/
Paint::setTextAlign(Align align);

我们再来重新看一下上面的例子,当我们设置为不同的值时,绘制结果是怎样的。
同样的代码,我们加上paint.setTextAlign()来设置相对位置来看看结果。
(1)、setTextAlign(Paint.Align.LEFT)
在原来代码上加上paint.setTextAlign(Paint.Align.LEFT)

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    int baseLineY = 200;
    int baseLineX = 0 ;

    //画基线
    Paint paint = new Paint();
    paint.setColor(Color.RED);
    canvas.drawLine(baseLineX, baseLineY, 3000, baseLineY, paint);

   
### 构建任务失败解决方案 当遇到 `Execution failed for task ':app:shrinkReleaseRes'` 错误时,这通常意味着资源压缩过程中出现了问题。此错误可能由多种原因引起,包括但不限于配置不正确、依赖冲突或特定于项目的其他因素。 #### 可能的原因分析 1. **ProGuard 或 R8 配置不当** ProGuard R8 是用于优化混淆代码以及减少 APK 大小的工具。如果这些工具的配置存在问题,可能会导致资源无法正常处理[^1]。 2. **重复资源** 如果项目中有多个模块定义了相同的资源名称,可能导致冲突并引发该错误。检查是否存在重名的 drawable、string 等资源文件[^2]。 3. **第三方库兼容性** 某些第三方库可能当前使用的 Gradle 插件版本或其他库存在兼容性问题,从而影响到资源打包过程中的行为[^3]。 4. **Gradle 缓存问题** 有时旧缓存数据会干扰新编译的结果,尝试清理本地仓库重新同步项目可以帮助排除此类潜在障碍[^4]。 #### 推荐的操作方法 为了有效解决问题,建议按照以下步骤逐一排查: ```bash # 清理项目构建目录 ./gradlew clean # 删除 .gradle 文件夹下的所有内容以清除缓存 rm -rf ~/.gradle/caches/ ``` 调整 `build.gradle` 中的相关设置也是一个重要环节: ```groovy android { ... buildTypes { release { minifyEnabled true // 是否启用代码缩减 shrinkResources true // 是否开启资源压缩 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' // 尝试禁用 shrinkResources 来测试是否为资源压缩引起的错误 // shrinkResources false } } } ``` 此外,在 `proguard-rules.pro` 文件内添加必要的保留规则,防止关键类被意外移除: ```text -keep class com.example.yourpackage.** { *; } # 替换为你自己的包路径 -dontwarn androidx.**,com.google.** # 忽略警告信息 ``` 最后,确保所使用的 Android Studio 版本是最新的稳定版,并且已经应用了所有的补丁更新。
评论 51
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值