关于自定义TextView的测量问题

首先推荐一个鸿洋大神的一个关于自定义字体的博客:http://blog.csdn.net/lmj623565791/article/details/44098729

本文的内容都是在观看博客时的一些总结,所以若下文有看不懂的请结合上面博客。

——————————我是萌萌的分割线———————————
首先我们看一下measureText中的处理:

    mTextWidth = (int) mPaint.measureText(mText);
    Paint.FontMetrics fm = mPaint.getFontMetrics();
    mTextHeight = (int) Math.ceil(fm.descent - fm.top);

    mPaint.getTextBounds(mText, 0, mText.length(), mTextBound);
    mTextHeight = mTextBound.height();

其中关于文字的宽度我们是根据measureText方法测量得到的,查看measureText的源码在注释中我们就能发现,这个方法是Return the width of the text.

下面的得到文字的高度的时候我们就发现没有直接得到高度的方法,一个简单的办法在Paint.java中搜索Return the height为空。这里我们就要分析一下getFontMetrics这个方法了。
这里写图片描述
要点如下:

  1. 基准点是baseline

  2. Ascent是baseline之上至字符最高处的距离

  3. Descent是baseline之下至字符最低处的距离

  4. Leading文档说的很含糊,其实是上一行字符的descent到下一行的ascent之间的距离

  5. Top指的是指的是最高字符到baseline的值,即ascent的最大值

  6. 同上,bottom指的是最下字符到baseline的值,即descent的最大值
    这里写图片描述

看到这里我们就发现其实大神的代码里有个错误:mTextHeight = (int) Math.ceil(fm.descent - fm.top);这句话明显不能得到正确的高度。
但是下面就得到了纠正
mPaint.getTextBounds(mText, 0, mText.length(), mTextBound);
mTextHeight = mTextBound.height();

其实可以看到这里完全覆盖了上面的定义,所以上面那句可能是大神为了启发我们故意留的吧。
这里我们对getTextBounds又陌生了。这里再看一幅图:
这里写图片描述
这是关于drawText方法的一个描述,其中的红色框架就代表了getTextBounds方法获得的Rect的大小,这是文字的实际所占用的区域的大小,所以我们可以得到文字所需要的实际高度。

但是我们又发现了drawText方法指向的是一个蓝色的方框,代表在实际布局中TextView所占用的实际面积的大小。同时告诉了我们绘制时的起点是在基准线BaseLine那里。所以我们在调用drawText方法时要注意起始的位置

canvas.drawText(mText, mTextStartX,getMeasuredHeight() / 2- ((mPaint.descent() + mPaint.ascent()) / 2), mPaint);

这里为什么这么写,大家可以参考我上面说的计算方法并参考博客中的实际位置看一下。

其中参考了:http://blog.51cto.com/mikewang/871765
http://blog.csdn.net/linghu_java/article/details/46404081

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值