关于自定义TextView的测量问题

来源:互联网 发布:怎么联系淘宝店铺客服 编辑:程序博客网 时间:2024/06/05 13:34

首先推荐一个鸿洋大神的一个关于自定义字体的博客: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

原创粉丝点击