Android 测量文字宽高

前言

最近自定义控件,需要绘制文本,用到了获取文本宽高的代码,在此做下记录。

Paint.measureText() 获取文本宽度

   Paint paint = new Paint();
   paint.setTextSize(textSize);
   float strWidth = paint.measureText(content);

Paint.getTextBounds() 获取文字所在区域,进而获取文本宽高

Paint paint = new Paint();
Rect rect = new Rect();  
paint.getTextBounds(content, 0, content.length(), rect);  
int w = rect.width();  
int h = rect.height();

Paint.FontMetrics or Paint.FontMetricsInt 获取文本高度

这两个类的属性意义相同,前者单位float后者单位int。
官方文档说明

属性 说明
ascent The recommended distance above the baseline for singled spaced text
bottom The maximum distance below the baseline for the lowest glyph in the font at a given text size
descent The recommended distance below the baseline for singled spaced text.
leading The recommended additional space to add between lines of text.
top The maximum distance above the baseline for the tallest glyph in the font at a given text size.

ascent :系统建议的,绘制单个字符时,字符应当的最高高度所在线(相对baseline为负值)
bottom:可绘制的最低高度所在线(相对baseline 为正值)
descent:系统建议的,绘制单个字符时,字符应当的最低高度所在线(相对baseline 为正值)
leading:行间距,即前一行的descent与下一行的ascent之间的距离
top:可绘制的最高高度所在线(相对baseline为负值)
baseline:为绘制基准线
代码示例子

PaintForMetrics.java

package com.xol.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by wwzhang on 2019/3/4
 */
public class PaintForMetrics extends View {
    private Paint mPaint;
    private int mTextSize = 120;
    private int mTopColor = Color.parseColor("#cc3333");
    private int mAscentColor = Color.parseColor("#003366");
    private int mBaseLineColor = Color.parseColor("#993333");
    private int mDescentColor = Color.parseColor("#cccc00");
    private int mBottomColor = Color.parseColor("#663366");
    private int mBackColor = Color.parseColor("#888888");
    private int mTextColor = Color.parseColor("#ffffff");

    public PaintForMetrics(Context context) {
        this(context, null);
    }

    public PaintForMetrics(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PaintForMetrics(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(mTextSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(mBackColor);
        mPaint.setColor(mTextColor);
        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        //设置基准线
        float baseLine = 150;
        String testContent = "Aa Bb Ff Gg Jj 张?";
        //绘制文本
        canvas.drawText(testContent, 0, baseLine, mPaint);
        //绘制topline
        mPaint.setColor(mTopColor);
        canvas.drawLine(0, baseLine + fontMetrics.top
                , getMeasuredWidth(), baseLine + fontMetrics.top, mPaint);
        //绘制ascent
        mPaint.setColor(mAscentColor);
        canvas.drawLine(0, baseLine + fontMetrics.ascent
                , getMeasuredWidth(), baseLine + fontMetrics.ascent, mPaint);
        //绘制baseLine
        mPaint.setColor(mBaseLineColor);
        canvas.drawLine(0, baseLine
                , getMeasuredWidth(), baseLine, mPaint);
        //绘制descent
        mPaint.setColor(mDescentColor);
        canvas.drawLine(0, baseLine + fontMetrics.descent,
                getMeasuredWidth(), baseLine + fontMetrics.descent, mPaint);
        //绘制bottom
        mPaint.setColor(mBottomColor);
        canvas.drawLine(0, baseLine + fontMetrics.bottom,
                getMeasuredWidth(), baseLine + fontMetrics.bottom, mPaint);
        //绘制中心线
        float centerY = getMeasuredHeight() / 2;
        canvas.drawLine(0, centerY,
                getMeasuredWidth(), centerY, mPaint);
        //绘制竖子居中文本
        float centerBaseLine = centerY + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
        canvas.drawText(testContent, 0, centerBaseLine, mPaint);
    }
}


ActivityForFontMetrics.java

package com.xol.viewpagerfragment;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;

/**
 * Created by wwzhang on 2019/3/4
 */
public class ActivityForFontMetrics extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_for_fontmetrics);
    }
}

布局文件

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

    <com.xol.widget.PaintForMetrics
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_gravity="center" />

</FrameLayout>

运行结果:
在这里插入图片描述
文本单行高度:fontMetrics.bottom-fontMetrics.top。
文本高度 :fontMetric.descent-fontMetrics.ascent。
总结:通过fontMetrics绘制文本,关键点是找到绘制的基准线座标y值。
view中心线求竖直文本居中baseLine公式:centerY+(fontMetric.bottom-fontMetric.top)/2-fontMetroc.bottom。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章