「译」Android文本测量

作者: 郭非文 | 来源:发表于2016-01-21 23:53 被阅读746次

    Chris Banes 原文
    欢迎转载,但请保留译者出处:http://www.jianshu.com/p/7f99f0e3f1ed

    如果你开始在Android的Canvas上人工绘制事物,你极有可能同时也会面临文本的绘制。

    当你这样做的时候,需要知晓放置文本的具体位置,而要做到这一点,你需要测量出文本的开始位置的x/y轴坐标。


    最近在一款app中我需要在Canvas上绘制同时满足水平与竖直居中的文本,所以我从以下代码开始着手:

    Paint mTextPaint = new Paint();
    mTextPaint.setTextAlign(Paint.Align.CENTER); // 文本居中
    
    // 之后你进行绘制...
    canvas.drawText(mText, // 用于显示的文本
            mBounds.centerX(), // canvas bounds 的 X 中间坐标
            mBounds.centerY(), // canvas bounds 的 Y 中间坐标
            mTextPaint
    );
    

    我并不指望第一次就成功并且确如所料,其输出效果如下:

    测量文本

    接着我试着给文本定位,计算文本宽、高并且正确修改绘制的X值与Y值:

    int mTextWidth, mTextHeight; // 我们计算出来的文本界限
    Paint mTextPaint = new Paint();
    
    // 现在让我们计算文本尺寸
    Rect textBounds = new Rect();
    mTextPaint.getTextBounds(mText, 0, mText.length(), textBounds);
    mTextWidth = textBounds.width();
    mTextHeight = textBounds.height();
    
    // 之后你进行绘制...
    canvas.drawText(mText, // 用于显示的文本
            mBounds.centerX() - (mTextWidth / 2f),
            mBounds.centerY() + (mTextHeight / 2f),
            mTextPaint
    );
    

    这一次我们朝目标接近了许多,但正如你所看到的那样,它并不是十分正确的置中。

    为了确定我没有看到的事物,我添加了额外的绘制调用让文本背后多出了一个矩形,该矩形的界限由[Paint.getTextBounds()](https://developer.android.com/reference/android/graphics/Paint.html#getTextBounds(java.lang.String, int, int, android.graphics.Rect))精确计算得出。

    如你所见,文本的绘制明显超出了它自身计算得出的界限,不论是宽还是高。

    另一种文本测量方法

    在这一点上,我看过Paint有另一种方法用于测量文本宽度:Paint.measureText()

    这个方法只计算宽度而没有高度,于是我试着将两种方法联合使用:

    int mTextWidth, mTextHeight; // 我们计算出来的文本界限
    Paint mTextPaint = new Paint();
    
    // 现在让我们计算文本尺寸
    Rect textBounds = new Rect();
    mTextPaint.getTextBounds(mText, 0, mText.length(), textBounds);
    mTextWidth = mTextPaint.measureText(mText); // 使用 measureText 来计算宽度
    mTextHeight = textBounds.height(); // 使用 getTextBounds() 计算出来的高度
    
    // 之后你进行绘制...
    canvas.drawText(mText, // 用于显示的文本
            mBounds.centerX() - (mTextWidth / 2f),
            mBounds.centerY() + (mTextHeight / 2f),
            mTextPaint
    );
    

    哎呀!由此产生了近乎完美的置中文本。


    Related Posts

    Support Libraries v22.1.0
    22 Apr 2015

    Theme vs Style
    12 Nov 2014

    Palette v21
    20 Oct 2014

    相关文章

      网友评论

      • 皮球二二:博主,mTextHeight的计算方式没有发生变化,是不是还是向下多一点了
        皮球二二: @端泽 对,我看字体大小都计算进去了
        郭非文:@r17171709 是的,drawText()中的y参数其实是baseline,如果要精准竖直居中,需要自己计算。
      • Mock章鱼小丸子:翻译的很不错,我会继续关注你的,加油!

      本文标题:「译」Android文本测量

      本文链接:https://www.haomeiwen.com/subject/nwglkttx.html