前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android ImageSpan与TextView同一行图片居中

Android ImageSpan与TextView同一行图片居中

作者头像
用户3106371
发布2018-09-12 10:15:55
2.4K0
发布2018-09-12 10:15:55
举报
文章被收录于专栏:lzj_learn_note

在开发中常常会遇到标签(图片)+文字的需求,实现方式一般采用SpannableString的方式来实现。 这时候会遇到图片ImageSpan没有办法居中的问题。在解决这个问题之前,先学习字体属性Paint.FontMetrics。

图片1

图片2

通过上面的示意图,再看下FontMetrics 类:

代码语言:javascript
复制
 public static class FontMetrics {
        /**
         * The maximum distance above the baseline for the tallest glyph in
         * the font at a given text size.
         */
        public float   top;//最高字符到baseline的值,即ascent的最大值
        /**
         * The recommended distance above the baseline for singled spaced text.
         */
        public float   ascent;//系统建议的,绘制单个字符时,baseline至字符最高处的距离
        /**
         * The recommended distance below the baseline for singled spaced text.
         */
        public float   descent;//系统建议的,绘制单个字符时,baseline至字符最低处的距离
        /**
         * The maximum distance below the baseline for the lowest glyph in
         * the font at a given text size.
         */
        public float   bottom;//最低字符到baseline的值
        /**
         * The recommended additional space to add between lines of text.
         */
        public float   leading;//上一行字符的descent到下一行字符ascent之间的距离,行间距
    }

ascent线Y坐标 = baseline线的y坐标 + fontMetric.ascent;

descent线Y坐标 = baseline线的y坐标 + fontMetric.descent;

top线Y坐标 = baseline线的y坐标 + fontMetric.top;

bottom线Y坐标 = baseline线的y坐标 + fontMetric.bottom;

ImageSpan

在ImageSpan的构造函数中有一个对齐方式的参数,但只提供了 ALIGN_BASELINE(顶部对齐)、ALIGN_BOTTOM (底部对齐)两种对齐方式,没有居中对齐的方式, 所以只能重写ImageSpan实现图片的居中。 public void draw(Canvas canvas, CharSequence text,int start, int end, float x, int top, int y, int bottom, Paint paint) 参数解析:

  • x:要绘制的image的左边框到textview左边框的距离。
  • y:替换文字的基线坐标。
  • top:替换改行文字的最顶部位置。
  • bottom:替换改行文字的最底部位置,行间距属于上一行,因而bottom是行间距的底部位置。

然后重写draw()方法即可实现图片居中,实现方式如下:

代码语言:javascript
复制
 @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
        Drawable drawable = getDrawable();
        Paint.FontMetricsInt fontMetricsInt = paint.getFontMetricsInt();
        int transY = (y + fontMetricsInt.descent + y + fontMetricsInt.ascent) / 2 - drawable.getBounds().bottom/2;
        canvas.save();
        canvas.translate(x,transY);
        drawable.draw(canvas);
        canvas.restore();
    }
  • y +fontMetricsInt.descent得到字体的descent线坐标
  • y + fontMetricsInt.ascent得到字体的ascent线坐标
  • 两者相加除以2,得到改行文字的中线坐标
  • drawable.getBounds().bottom/2得到图片中线坐标
  • 然后两者相减,即可获得图片需要移动多长的距离可以居中
  • 最后将相减得到的距离传给canvas.translate(x,transY)即可
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.05.26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ImageSpan
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档