Android字体属性及测量(FontMetrics)

  • 字体的几个参数,以Android API文档定义为尊,见下图

要点如下:

  1. 基准点是baseline
  2. Ascent是baseline之上至字符最高处的距离
  3. Descent是baseline之下至字符最低处的距离
  4. Leading文档说的很含糊,其实是上一行字符的descent到下一行的ascent之间的距离
  5. Top指的是指的是最高字符到baseline的值,即ascent的最大值
  6. bottom指的是最下字符到baseline的值,即descent的最大值
为了帮助理解,我特此搜索了不同的示意图。对照示意图,会很容易理解FontMetrics的参数。

图1

图2

图3

图4

图5

图6

  • 测试
    我们使用自定义的View和Textview里的字符串作为研究对象
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#000000"android:orientation="vertical"><!--PaintView画字体--><video.ketu.com.fontmeasure.PaintView
       android:id="@+id/v_fontview"android:layout_width="match_parent"android:layout_height="1dp"android:layout_weight="1"/><!--Textview设置文字--><TextView
       android:id="@+id/tv_fontview1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="中国话fgiqÃÇŸŒú"android:textColor="@android:color/white"android:textSize="80px"android:layout_weight="1"/>
</LinearLayout>

MainActivity.class

public class MainActivity extends AppCompatActivity {TextView textView;View paintView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);paintView = findViewById(R.id.v_fontview);textView = (TextView) findViewById(R.id.tv_fontview1);//String text = "中国话fgiqÃÇŸŒúcqazweyghnhgd;lc,kjssnhjjomoomcod";String text = "中国话fgiqÃÇŸŒú";/*设置字体带下80px*/textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,80);textView.setText(text);Paint.FontMetrics fontMetrics = textView.getPaint().getFontMetrics();Log.d("textView", "fontMetrics.top        is:" + fontMetrics.top);Log.d("textView", "fontMetrics.ascent     is:" + fontMetrics.ascent);Log.d("textView", "fontMetrics.descent    is:" + fontMetrics.descent);Log.d("textView", "fontMetrics.bottom     is:" + fontMetrics.bottom);Log.d("textView", "fontMetrics.leading    is:" + fontMetrics.leading);}
}

PaintView.class

public class PaintView extends View {private Paint mPaint = new Paint();public PaintView(Context context) {super(context);}public PaintView(Context context, AttributeSet attrs) {super(context, attrs);}public PaintView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubmPaint.reset();mPaint.setColor(Color.WHITE);/*设置字体带下80px*/mPaint.setTextSize(80);//设置字体为斜体//mPaint.setTypeface(Typeface.create("", Typeface.ITALIC));// FontMetrics对象Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();String text = "中国话fgiqÃÇŸŒú";// 计算每一个坐标float textWidth = mPaint.measureText(text);float baseX = 0;float baseY = 100;float topY = baseY + fontMetrics.top;float ascentY = baseY + fontMetrics.ascent;float descentY = baseY + fontMetrics.descent;float bottomY = baseY + fontMetrics.bottom;float leading = baseY + fontMetrics.leading;Log.d("paintview", "baseX    is:" + baseX);Log.d("paintview", "baseY    is:" + baseY);Log.d("paintview", "fontMetrics.top        is:" + fontMetrics.top);Log.d("paintview", "fontMetrics.ascent     is:" + fontMetrics.ascent);Log.d("paintview", "fontMetrics.descent    is:" + fontMetrics.descent);Log.d("paintview", "fontMetrics.bottom     is:" + fontMetrics.bottom);Log.d("paintview", "fontMetrics.leading    is:" + fontMetrics.leading);Log.d("paintview", "topY     is:" + topY);Log.d("paintview", "ascentY  is:" + ascentY);Log.d("paintview", "descentY is:" + descentY);Log.d("paintview", "bottomY  is:" + bottomY);

截面图

PaintView和TextView设置的字体大小都是80px,Log打印结果

PaintView结果

TextView结果

Note 1:以上可见,字体属性类的FontMetrics类的top,ascent,descent,bottom,leading的值是正负数,是以基线baseline为0的相对值。当baseline是100时,各个参数的坐标就是正数。
所以对于文本框的文字的行高:fontMetrics.top-fontMetrics.bottom

Note 2:以上的TextView的文本长度是单行,获得leading=0,那么如果TextView的文本是多行,并且设置行间距后,leading的变化

public class MainActivity extends AppCompatActivity {TextView textView;View paintView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);paintView = findViewById(R.id.v_fontview);textView = (TextView) findViewById(R.id.tv_fontview1);String text = "中国话fgiqÃÇŸŒúcqazweyghnhgd;lc,kjssnhjjomoomcod";//String text = "中国话fgiqÃÇŸŒú";/*设置字体带下80px*/textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,80);textView.setText(text);Paint.FontMetrics fontMetrics = textView.getPaint().getFontMetrics();Log.d("textView", "fontMetrics.top        is:" + fontMetrics.top);Log.d("textView", "fontMetrics.ascent     is:" + fontMetrics.ascent);Log.d("textView", "fontMetrics.descent    is:" + fontMetrics.descent);Log.d("textView", "fontMetrics.bottom     is:" + fontMetrics.bottom);Log.d("textView", "fontMetrics.leading    is:" + fontMetrics.leading);}
<TextViewandroid:id="@+id/tv_fontview1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="中国话fgiqÃÇŸŒúcqazweyghnhgd;lc,kjssnhjjomoomcod"android:textColor="@android:color/white"android:lineSpacingExtra="5px"android:textSize="80px"android:layout_weight="1"/>

截面图

结果Log

Note:显然,即使是多行,并且设置5px行距的情况下,仍不能获得leading。

Android踩坑日记:Android字体属性及测量(FontMetrics)相关推荐

  1. Android WebView 踩坑日记,字体怎么突然变小了???

    背景 最近,端内在做 webView 统一的时候,个性签名中的 WebView 替换为 CustomWebView 之后,发现字体突然变小. 一开始不知道是什么原因,通过二分法查找最近的提交,排查之后 ...

  2. Android WebView 踩坑日记,字体怎么突然变小了?

    parsedHtml += "<meta name="viewport" content="width=device-width,initial-scal ...

  3. Android踩坑日记:使用Fesco图片加载库在GridView上的卡顿优化

    1,fresco是一个强大的图片加载库 2,fresco设计了一个叫做image pipeline(图片管道)的模块,它负责从从网络,从本地文件系统,从本地资源加载图片,为了最大限度节约资源和cpu时 ...

  4. Android踩坑日记:FloatingActionButton的设置大小问题

    FloatingActionButton(FAB) 是 Android 5.0 新特性--Material Design 中的一个控件,是一种悬浮的按钮.FloatingActionButton 是 ...

  5. Android踩坑日记:自定义水平和圆形ProgressBar样式

    自定义水平和圆形ProgressBar样式 1.自定义水平ProgressBar样式 ProgressBar分为两种,我们能明确看到进度,不确定的就是不清楚.不确定一个操作需要多长时间来完成,这个时候 ...

  6. Android踩坑日记:RecyclerView中EditText和ImageView的ViewHolder复用坑

    RecyclerView中EditText和ImageView的ViewHolder复用坑 RecyclerView作为ListView的升级版,目前来讲讲开发过程遇到的坑. RecyclerView ...

  7. Android踩坑日记:监听软键盘多次调用和刷新系统相册和获取所有相片

    EditText设置监听软键盘删除键(或enter) 一般使用方法 edittext.setOnKeyListener(new View.OnKeyListener(){@Overridepublic ...

  8. Android踩坑日记:Okhttp设置User-Agent你可能没遇到的坑

    Okhttp设置User-Agent你可能没遇到的坑 Http Header之User-Agent    User-Agent中文名为用户代理,是Http协议中的一部分,属于头域的组成部分,User ...

  9. Android踩坑日记:android7.0动态相机权限

    前提: 项目中使用的动态权限开源库github:https://github.com/yanzhenjie/AndPermission. 转载必须注明本文转自严振杰的博客:http://blog.cs ...

最新文章

  1. Javascript学习--------详解window窗口对象
  2. python单链表实现荷兰国旗问题_这道荷兰旗问题,我面试时遇到三次!
  3. python学多久可以接单-零基础小白多久能学会python
  4. Lucene——Field.Store(存储域选项)及Field.Index(索引选项)
  5. JSBinding+SharpKit / 更新的原理
  6. [leetcode]509. 斐波那契数
  7. 常用css属性集(持续更新…)
  8. mysql数据库二进制_Mysql数据库简单安装(二进制)
  9. 『TensorFlow』批处理类
  10. c/c++中关于sizeof、strlen的使用说明
  11. 太阳光轨迹软件_巧用虚拟天文馆软件Stellarium演示太阳周日视运动轨迹_贺志康...
  12. 烦哪烦哪烦哪没有力气..
  13. ffmpeg用法及如何使用fluent-ffmpeg
  14. JAVA实现的飞机大战小游戏-Asteroids
  15. VM虚拟机桥接模式的复制物理网络连接状态是什么意思
  16. 生信搬运工-01-fastq文件的处理
  17. 用TTL线在CFE环境下拯救半砖wrt54g路由器
  18. VLC播放画质延迟改善方法
  19. Oracle查询前1个小时到后一个小时之间的数据
  20. Dynamo 论文解读

热门文章

  1. class_create
  2. 十五、稀疏矩阵的乘法运算
  3. 第五章-分布式并行编程框架MapReduce
  4. 测验6: 组合数据类型 (第6周)
  5. R语言:常用函数总结
  6. 简单的计数器程序_javaweb
  7. 全国大学生电工数学建模竞赛赛题_A
  8. 【Pygame小游戏】这款休闲游戏你肯定了解过《开心消消乐》更新版本上线,好土好喜欢
  9. 防止Stack smash的技术
  10. Redis常见面试题及答案模板