android 获取textview的高度,Android TextView 高度问题

本文探讨了在Android开发中遇到的TextView高度问题,详细解释了TextView高度由包括字体内填充和行高在内的因素决定,并提供了如何获取行高、禁用内填充以及文字绘制的相关代码示例。

参考:https://www.cnblogs.com/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(TypedValue.COMPLEX_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, 关于文字绘制与行高

75d4c7c8900035146b37bdde43bb1454.gif

视觉上的行间距的定义和Android系统对行间距的定义不一致。可以看到上图中文字上方到ascent还有间距。

Baseline是基线,在Android中,文字的绘制都是从Baseline处开始的,Baseline往上至字符“最高处”的距离我们称之为ascent(上坡度),Baseline往下至字符“最低处”的距离我们称之为descent(下坡度);

leading(行间距)则表示上一行字符的descent到该行字符的ascent之间的距离;

top和bottom文档描述地很模糊,其实这里我们可以借鉴一下TextView对文本的绘制,TextView在绘制文本的时候总会在文本的最外层留出一些内边距,为什么要这样做?因为TextView在绘制文本的时候考虑到了类似读音符号,下图中的A上面的符号就是一个拉丁文的类似读音符号的东西

7a716d7fe17f407fb15f99f2490af213.png

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值为负)

参考:

https://blog.csdn.net/l732427480/article/details/51711970

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值