SpannableString来实现TextView的富文本效果(改变字体大小,设置颜色,设置图片,设置超链接效果等等),大家应该都已经用过很多次了。这里不再详述,今天我们主要讨论,当TextView中的文本字体大小不一致时如何垂直居中。

首先,我们需要明确TextView绘制的基本度量标准,如下图:

各个字段的具体解释可以参考这篇文章,写的非常详细。
https://blog.csdn.net/u010983881/article/details/53995020
默认情况下,TextView的文字都是底部对齐的,当字体大小不一致时,效果如下:

通过了解图1中的各个字段含义之后,我们知道,我们可以通过重设TextView某些文字的Y坐标来实现他在整个TextView中垂直居中的效果。代码如下:
VerticalAlignTextSpan.java

public class VerticalAlignTextSpan extends ReplacementSpan {    private int fontSizeSp = -1;//单位:sp    public VerticalAlignTextSpan() {    }    public VerticalAlignTextSpan(int fontSizeSp) {        this.fontSizeSp = fontSizeSp;    }    @Override    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {        Paint newPaint = getCustomTextPaint(paint);        return (int) newPaint.measureText(text, start, end);    }    @Override    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int            bottom, @NonNull Paint paint) {        Paint newPaint = getCustomTextPaint(paint);        Paint.FontMetricsInt fontMetricsInt = newPaint.getFontMetricsInt();        int offsetY = (y + fontMetricsInt.ascent + y + fontMetricsInt.descent) / 2 - (top + bottom) / 2;        Log.d("VerticalAlignTextSpan", "offsetY-> " + offsetY);        canvas.drawText(text, start, end, x, y - offsetY, newPaint);    }    private TextPaint getCustomTextPaint(Paint srcPaint) {        TextPaint textPaint = new TextPaint(srcPaint);        if (fontSizeSp != -1) {//-1没有重设fontSize            textPaint.setTextSize(fontSizeSp * textPaint.density);//sp转px        }        return textPaint;    }}

MainActivity.java

SpannableString ss = new SpannableString("900米");Drawable drawable = getResources().getDrawable(R.drawable.cattle);drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());AbsoluteSizeSpan bigFontSpan = new AbsoluteSizeSpan(40, true);ss.setSpan(bigFontSpan, 0, ss.length() - 1, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);VerticalAlignTextSpan verticalAlignTextSpan = new VerticalAlignTextSpan(23);ss.setSpan(verticalAlignTextSpan, ss.length() - 1, ss.length(), SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);tvImageSpan.setText(ss);

最终效果如下:

更多相关文章

  1. Android(安卓)ViewFlipper触摸动画
  2. Viewpager显示前后两页部分界面(含5种demo)
  3. Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运
  4. Android:支持不同分辨率的屏幕设计
  5. Android界面制作中最重要最强大的武器: 9-patch
  6. Android(安卓)自定义控件实现刮刮卡效果 真的就只是刮刮卡么
  7. Android实现动态向Gallery中添加图片及倒影与3D效果示例
  8. 【Android】Android动画入门Animation 、AnimationUtils
  9. android 控件描边取消重叠

随机推荐

  1. android 测试读取LEB数据的函数
  2. Android 实现文件的下载
  3. android 格式化SD卡
  4. Android跨进程通信IPC之15——Binder之na
  5. android pm 和 install 选项 命令
  6. 转:android 调用系统的接口
  7. Android第二十一课 Jni日志打印以及注意
  8. android 引用工程作为类库
  9. Android URL中参数的获取、拼接及修改
  10. 一个更多按钮popwindow