参考:/tc310/p/12721754.html
前言:
在我们做界面开发的时候,UI的标注图中经常是标注了文字的字号和文件的间距。而当我们使用多个TextView 实现后,却发现textView 之间的空白区域的高度,是远大于设计标注的。
前提: TextView height = warp_content。 设为单行。
原因: TextView 高度包含 1) IncludedFontPadding 2,Line height;
而LineHeight 也并不是文字字号高度,并且也大于字号高度。
TextView textView = (TextView) findViewById(R.id.sample_text);
textView.setBackgroundColor(Color.YELLOW);
textView.setTextSize(PLEX_UNIT_PX , 60);
1,关于行高获取:
intht = textView.getLineHeight();
这个高度的获取,并不需要对当前的Text 进行测量。 与当前的TextSize 正相关。
2,
textView.setIncludeFontPadding(false);
可以通过这个方法,禁掉首行文字和末行文字的font padding。 需要验证是否对行高也有影响。
if (includepad) {
spacing = metrics.bottom - metrics.top;
mDesc = metrics.bottom;
} else {
spacing = metrics.descent - metrics.ascent;
mDesc = metrics.descent;
}
......
if (includepad) {
mTopPadding = metrics.top - metrics.ascent;
mBottomPadding = metrics.bottom - metrics.descent;
}
3, 关于文字绘制与行高
视觉上的行间距的定义和Android系统对行间距的定义不一致。可以看到上图中文字上方到ascent还有间距。
Baseline是基线,在Android中,文字的绘制都是从Baseline处开始的,Baseline往上至字符“最高处”的距离我们称之为ascent(上坡度),Baseline往下至字符“最低处”的距离我们称之为descent(下坡度);
leading(行间距)则表示上一行字符的descent到该行字符的ascent之间的距离;
top和bottom文档描述地很模糊,其实这里我们可以借鉴一下TextView对文本的绘制,TextView在绘制文本的时候总会在文本的最外层留出一些内边距,为什么要这样做?因为TextView在绘制文本的时候考虑到了类似读音符号,下图中的A上面的符号就是一个拉丁文的类似读音符号的东西
public classMText extendsTextView{
publicMText(Context context) {
super(context);
}
publicMText(Context context, @NullableAttributeSet attrs) {
super(context, attrs);
}
publicMText(Context context, @NullableAttributeSet attrs, intdefStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Overridepublic voidonDraw(Canvas canvas){
super.onDraw(canvas);
// FontMetrics对象Paint textPaint = getPaint();
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
//计算每一个坐标floatbaseX = 0;
floatbaseY = getBaseline();
floattopY = baseY + fontMetrics.top;
floatascentY = baseY + fontMetrics.ascent;
floatdescentY = baseY + fontMetrics.descent;
floatbottomY = baseY + fontMetrics.bottom;
// BaseLine描画Paint baseLinePaint = newPaint( Paint.ANTI_ALIAS_FLAG);
baseLinePaint.setColor( Color.RED);
canvas.drawLine(0, baseY, getWidth(), baseY, baseLinePaint);
// Base描画canvas.drawCircle( baseX, baseY, 5, baseLinePaint);
// TopLine描画Paint topLinePaint = newPaint( Paint.ANTI_ALIAS_FLAG);
topLinePaint.setColor( Color.LTGRAY);
canvas.drawLine(0, topY, getWidth(), topY, topLinePaint);
// AscentLine描画Paint ascentLinePaint = newPaint( Paint.ANTI_ALIAS_FLAG);
ascentLinePaint.setColor( Color.GREEN);
canvas.drawLine(0, ascentY, getWidth(), ascentY, ascentLinePaint);
// DescentLine描画Paint descentLinePaint = newPaint( Paint.ANTI_ALIAS_FLAG);
descentLinePaint.setColor( Color.YELLOW);
canvas.drawLine(0, descentY, getWidth(), descentY, descentLinePaint);
// ButtomLine描画Paint bottomLinePaint = newPaint( Paint.ANTI_ALIAS_FLAG);
bottomLinePaint.setColor( Color.MAGENTA);
canvas.drawLine(0, bottomY, getWidth(), bottomY, bottomLinePaint);
}
}
文字的行高计算:
floatascentY = baseY + fontMetrics.ascent;
floatdescentY = baseY + fontMetrics.descent;
int lineHeght = descentY - ascentY; //[不是从源码得出的结论,待进一步验证]
top坐标计算:下一行Top值 = 本行Top值 + 行高
行高计算(排除第一行和最后一行):行高 = descent - ascent + 行间距 (descent值为正,ascent值为负)
参考:
/l732427480/article/details/51711970