我是靠谱客的博主 仁爱服饰,最近开发中收集的这篇文章主要介绍android 字体竖直居中_Android Canvas drawText 实现文字垂直居中及其背景绘制,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1、需求

标题+标签组合显示。标签字体放在标题后面,标签四周加框并呈1dp圆角。

2、方案

使用TextView承载,结合SpannableString实现图文并排,具体选取ImageSpan实现标签样式。

绘制文字

在西文中,有基线(baseline)、升部(ascent)、降部(descent)的概念。

/**

* Class that describes the various metrics for a font at a given text size.

* Remember, Y values increase going down, so those values will be positive,

* and values that measure distances going up will be negative. This class

* is returned by getFontMetrics().

*/

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;

/**

* The recommended distance above the baseline for singled spaced text.

*/

public float ascent;

/**

* The recommended distance below the baseline for singled spaced text.

*/

public float descent;

/**

* The maximum distance below the baseline for the lowest glyph in

* the font at a given text size.

*/

public float bottom;

/**

* The recommended additional space to add between lines of text.

*/

public float leading;

}

通常来说中文就没有这样的概念,不过在绘制的时候,和英文字符的绘制并无两样,也是有类似基线、升部、降部的区分。

canvas.drawText("基", x, y, mPaint);

float size = mPaint.measureText("基");

canvas.drawLine(x, y + mPaint.ascent(), x + size, y + mPaint.ascent(), mPaint);

canvas.drawLine(x, y, x + size, y, mPaint);

canvas.drawLine(x, y + mPaint.descent(), x + size, y + mPaint.descent(), mPaint);

绘制文字有两个关键点文字的宽高由字号大小决定:

height = paint.descent() - paint.ascent()

width = paint. measureText(String)

文字绘制的起点由x和y决定:

y 就是基线(baseline)的坐标

y + paint.ascent() 就是文字的降部坐标

y + paint.descent() 就是文字的降部坐标

绘制背景图

ImageSpan extends DynamicDrawableSpan

源码中,ImageSpan并没有重写draw方法,而是使用父类DynamicDrawableSpan的绘制。

public void draw(Canvas canvas, CharSequence text,

int start, int end, float x,

int top, int y, int bottom, Paint paint) {

Drawable b = getCachedDrawable();

canvas.save();

int transY = bottom - b.getBounds().bottom;

if (mVerticalAlignment == ALIGN_BASELINE) {

transY -= paint.getFontMetricsInt().descent;

}

canvas.translate(x, transY);

b.draw(canvas);

canvas.restore();

}

public DynamicDrawableSpan() {

mVerticalAlignment = ALIGN_BOTTOM;

}

绘制背景图,有个关键点是画布会作偏移处理:

canvas.translate(x, transY)

注意到:

transY = bottom - b.getBounds().bottom

这代表什么意思呢?背景图距离view底部多少就整体往下偏移多少,也就是说背景图默认是从view底部开始的,与背景图设置的Rect(left, top, right, bottom)中Y轴上的坐标系没有绝对关系,反正都是会偏移到view底部中来。

一句话就是,自动与view的bottom值对齐。

修改x和bottom数据,就可以随意把背景图绘制到那个位置

3、实现

思路

绘制文字,基准线y。要居中,也就是中心点保持一致,计算字号修改后基准线的值。

y + paint.ascent() + y + paint.descent() = y + paint.ascent() + y + paint.descent()

绘制背景,背景图下边沿与bottom值对齐。

y + paint.decent() + 背景图边距宽度 + 其他的设置效果 = bottom

代码

SpannableString msp = new SpannableString(title + mark);

msp.setSpan(new ImageSpan(mDescriBg) {

@Override

public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {

paint.setTextSize(fontSize);

width.add(0, Math.round(paint.measureText(text, start, end)));

//整体左边加2个,加上文字内部左右各一个4个

return width.get(0) + 4 * fontPadding;

}

@Override

public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom,

Paint paint) {

float oldad = paint.descent() + paint.ascent();

paint.setTextSize(fontSize);

float newad = paint.descent() + paint.ascent();

//以改变前的字体为中间基准

int baseY = (int)(y * 2 + oldad - newad ) / 2;

int textHeight = (int)(paint.descent() - paint.ascent());

//字体净高度 + 背景边界宽度=总高度

int height = textHeight + cornerSize * 2;

//背景图的要显示实际下边沿,作为bottom

int bgBottom = (int)(baseY + paint.descent() + cornerSize);

getDrawable().setBounds(

0,

0,

width.get(0) + 2 * fontPadding,

height);

super.draw(canvas, text, start, end, x + 2 * fontPadding, top, y, bgBottom, paint);

paint.setColor(Color.RED);

//paint.setTypeface(Typeface.create("normal", Typeface.BOLD));

canvas.drawText(text.subSequence(start, end).toString(),

x + fontPadding * 3,

baseY, paint);

}

}, title.length(), title.length() + mark.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

最后

以上就是仁爱服饰为你收集整理的android 字体竖直居中_Android Canvas drawText 实现文字垂直居中及其背景绘制的全部内容,希望文章能够帮你解决android 字体竖直居中_Android Canvas drawText 实现文字垂直居中及其背景绘制所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部