Android——SpannableString字体大小不一致垂直居中
16lz
2021-01-24
用
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);
最终效果如下:
更多相关文章
- Android(安卓)ViewFlipper触摸动画
- Viewpager显示前后两页部分界面(含5种demo)
- Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运
- Android:支持不同分辨率的屏幕设计
- Android界面制作中最重要最强大的武器: 9-patch
- Android(安卓)自定义控件实现刮刮卡效果 真的就只是刮刮卡么
- Android实现动态向Gallery中添加图片及倒影与3D效果示例
- 【Android】Android动画入门Animation 、AnimationUtils
- android 控件描边取消重叠