您的位置:首页 > 移动开发 > Android开发

Android进阶九:TextView绘制原理之top,bottom,ascent,descent,baseline

2017-12-23 12:44 417 查看

top,bottom,ascent,descent,baseline

先来看一张图:



文字在绘制的时候,会根据当前的字体,字体大小等信息,确认top,bottom,ascent,descent,baseline的值,这些值会最终影响到字体在TextView中的显示位置,

通过getPaint().getFontMetricsInt()可以获取到这些值

baseline:基准点,字符在TextView中的基准点,字符的绘制就是通过这个基准点来绘制的,相当于字符的零点,top,bottom,ascent,descent的值就是以这个为零点来得到的,在baseline上面的top和ascent是负数,在baseline下面的bottom和descent是正数

top:是指的是最高字符到baseline的值,即ascent的最大值,为负数

ascent:是baseline之上至字符最高处的距离,为负数

bottom:是指最低字符到baseline的值,即descent的最大值,为正数

descent:是baseline之下至字符最低处的距离,为正数

测试

我自定义了一个NonSpaceTextView:

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

Ln.e("font bottom:" + getPaint().getFontMetricsInt().bottom +
"  \ndescent:" + getPaint().getFontMetricsInt().descent +
" \nascent:" + getPaint().getFontMetricsInt().ascent +
" \ntop:" + getPaint().getFontMetricsInt().top +
" \nbaseline:" + getBaseline());

/**
* TextView组件的属性
*/
Ln.e("textview bottom:" + getBottom() +
" \ntop:" + getTop() +
" \nbaseline:" + getBaseline());

}


layout中加入:

<com.biyou.view.NonSpaceTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="6ms jkÖÄ"
android:textColor="@color/clr_black"
android:textSize="25sp"
android:background="#FFFF00FF"
android:layout_gravity="center_horizontal"
android:id = "@+id/id_value"
android:textStyle="bold" />


打印结果是:

font bottom:11
descent:5
ascent:-25
top:-26
baseline:26

textview bottom:37
top:0
baseline:26


显示如下:



发现TextView的上下边框占据很大的空间,有时候想把他们去掉,下面是个简单的方法:

去掉TextView的上下边框

一般当TextView的android:layout_height设置为wrap_content的时候,若未设置 android:lineSpacingExtra和android:lineSpacingMultiplier,TextView的高为:(bottom - top)

拿上面的例子TextView的高位37,font的bottom - top = 11 - (-25) = 37,

一般地,top到 ascent之间的空间,和bottom和descent之间的空间都是用不到的,

所以可以重写TextView来去掉这两个空间:

1.重写测量方法,把测量的高度减去上下两个边框的高度:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(heightMode == MeasureSpec.AT_MOST)
{
int deltaHeight = (getPaint().getFontMetricsInt().ascent - getPaint().getFontMetricsInt().top + getPaint().getFontMetricsInt().bottom - getPaint().getFontMetricsInt().descent);
setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight() - deltaHeight);
}
}


2.重写绘制方法,把绘制坐标往上移(ascent - top)的距离

@Override
protected void onDraw(Canvas canvas) {
int topDelta = (getPaint().getFontMetricsInt().ascent - getPaint().getFontMetricsInt().top);
setTop(-topDelta);
super.onDraw(canvas);
}


效果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android