Android测量文字的三种方式

1,609 阅读2分钟

「这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

Android测量文字的三种方式

我们想要获取TextView组件的宽高,在显示出来的情况,直接getHeight、getWidth就可以满足需要,那么文字未显示的时候如何获取图片的宽高呢,在文本编辑时的垂直、水平对齐你们又是怎么处理的呢

Paint.measureText()

官方API这么说:

返回文本的宽度。 参数: text–要测量的文本。不能为空。 返回: 文本的宽度

使用它:

final String STR = "测试123YyMm";
final int SIZE = 50;

TextPaint paint = new TextPaint();
paint.setTextSize(SIZE);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setFakeBoldText(true);
paint.setUnderlineText(true);
float strWidth = paint.measureText(STR);
Log.d(TAG, "strWidth:" + strWidth);

通过测试发现,设置文字的大小、字体都会影响文字的宽度,但是设置加粗和下划线之类的,则不会影响文本的宽度。

那么通过该方法获取的宽度和TextView显示出来的宽度(getWidth)有什么区别呢? 其实是一样的。

我在相同的条件下测试,得到的都是326px。

 TextView textView = findViewById(R.id.test);
        textView.post(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "textView width:" + textView.getWidth());
            }
        });
<TextView
            android:id="@+id/test"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/purple_200"
            android:text="测试123YyMm"
            android:textSize="50px" />
TextPaint paint = new TextPaint();
        paint.setTextSize(SIZE);
        paint.setFakeBoldText(true);
        paint.setUnderlineText(true);
        float strWidth = paint.measureText(STR);
        Log.d(TAG, "strWidth:" + strWidth);

所以在不换行的情况下measureText获取的是TextView真实显示的宽度。 在换行的情况下就不一定了。

getTextBounds

官方API这么说:

检索文本边界框并存储到边界。在边界内返回(由调用方分配)包含所有字符的最小矩形

注意这个最小矩形,就是在去掉Padding之后的矩形,所以在相同条件的情况,getTextBounds获取到的宽高要比TextView的宽高要小一点。实际上也是如此。 所以如果要去除文本默认的间隙,则可以利用这个方法去实现。它返回的是一个矩形,包含文本在内的最小矩形。

 TextPaint paint = new TextPaint();
        paint.setTextSize(SIZE);
        Rect rect = new Rect();
        paint.getTextBounds(STR, 0, STR.length(), rect);

        Log.d(TAG, "width:" + rect.width() + ",height:" + rect.height()); //  width:322,height:53

        TextView textView = findViewById(R.id.test);
        textView.post(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "width:" + textView.getWidth() + ", height:" + textView.getHeight());  //width:326, height:67
            }
        });

FontMetrics

官方API这么说。

该类描述给定文本大小的字体的各种度量。请记住,Y值向下增加,因此这些值将为正值,而测量向上距离的值将为负值。

含义是以baseLine为基准,上方是负值,下方是正值,获取的内容还看图比较直观。

1.png

TextPaint paint = new TextPaint();
        paint.setTextSize(SIZE);
        Paint.FontMetrics fontMetrics = paint.getFontMetrics();

        Log.d(TAG, "height1:" + (fontMetrics.descent - fontMetrics.ascent)); // 58.59375
        Log.d(TAG, "height2:" + (fontMetrics.bottom - fontMetrics.top));// 66.35742

        TextView textView = findViewById(R.id.test);
        textView.post(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "width:" + textView.getWidth() + ", height:" + textView.getHeight());  //width:326, height:67
            }
        });