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。
官方文档说明

属性说明
ascentThe recommended distance above the baseline for singled spaced text
bottomThe maximum distance below the baseline for the lowest glyph in the font at a given text size
descentThe recommended distance below the baseline for singled spaced text.
leadingThe recommended additional space to add between lines of text.
topThe 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。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值