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。

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