这里有一篇文章关于设置段落间距(仅供参考):https://blog.csdn.net/yingpaixiaochuan/article/details/77996793

TextView行间距设置

在布局XML中有两个参数可以对TextView的行间距进行设置。

分别为:android:lineSpacingExtra 和 android:lineSpacingMultiplier。

在代码中可以通过TextView的setLineSpacing()方法来设置。

android:lineSpacingExtra

android:lineSpacingExtra表示额外的行间距数值,单位通常为dp。如android:lineSpacingExtra=”1dp”。

android:lineSpacingExtra的值可以为负数,小数和0。如果值为正数表示增加行间距,如果值为负数表示减少行间距,如果值为0,则没有变化。

android:lineSpacingMultiplier

android:lineSpacingMultiplier表示行间距的倍数,没有单位。如android:lineSpacingMultiplier=”1.2”。

android:lineSpacingMultiplier的值可以为任意浮点数。如果值大于1.0表示增加行间距,如果值小于1.0表示减少行间距。

android:lineSpacingExtra和android:lineSpacingMultiplier一起使用

android:lineSpacingExtra和android:lineSpacingMultiplier可以在一起对同一个TextView进行设置,同时使用时会先增加android:lineSpacingMultiplier设置的倍数,再加上android:lineSpacingExtra设置的额外的间距。

setLineSpacing()

setLineSpacing()原型为public void setLineSpacing(float add, float mult);

参数add表示要增加的间距数值,对应android:lineSpacingExtra参数。

参数mult表示要增加的间距倍数,对应android:lineSpacingMultiplier参数。

不同行间距设置下的显示效果

设置不同的android:lineSpacingExtra显示效果如下。

正常行间距下显示效果

设置android:lineSpacingExtra=”2dp”时的显示效果

设置android:lineSpacingExtra=”-6dp”时的显示效果

设置android:lineSpacingExtra=”-10dp”时的显示效果

设置不同的android:lineSpacingMultiplier显示效果如下。

正常行间距下显示效果

设置android:lineSpacingMultiplier=”1.2”时的显示效果

设置android:lineSpacingMultiplier=”2.0”时的显示效果

设置android:lineSpacingMultiplier=”0.5”时的显示效果

设置android:lineSpacingMultiplier=”0”时的显示效果(等于0时文字不可见)

行间距设置影响分析

对正常行间距,android:lineSpacingExtra=”2dp”,和android:lineSpacingMultiplier=”2”设置下的实际行间距进行测量,得到如下数值

正常行间距下,实际间距为12px

+2dp行间距下,实际间距为18px

2倍行间距下,实际间距为64px

可以看到在android:lineSpacingExtra=”2dp”设置下,实际行间距也增加了6px(测试手机上1dp=3px),但在android:lineSpacingMultiplier=”2”设置下,实际行间距并不是正常行间距的两倍。

进一步的,如果在测量时将文字高度也计算在内,得到如下数值:

正常行间距下,包含文字高度间距为52px

+2dp行间距下,包含文字高度间距为58px

2倍行间距下,包含文字高度间距为104px(这里测量使用的是第二行的间距,原因下文会描述)

通常意义下所说的行间距是指一行文字下方距离下一行文字上方的距离,行高是指一行文字上方距离下一行文字上方的距离。

通过对比可以看出,android:lineSpacingExtra和android:lineSpacingMultiplier的设置并不是直接影响行间距,而是通过行高来影响行间距。当设置android:lineSpacingExtra=”2dp”时,行高增加2dp,文字高度不变,于是行间距增加2dp。当设置android:lineSpacingMultiplier=”2”时,行高增加两倍,文字高度不变,行间距增加(”文字高度”+”文字正常行间距”)

获取TextView行高

TextView提供了getLineHeight()方法来获取TextView的行高。

对正常行间距,android:lineSpacingExtra=”2dp”和android:lineSpacingMultiplier=”2”设置下通过getLineHeight()方法获取的行高如下。

正常行间距:52px

android:lineSpacingExtra=”2dp”:58px

android:lineSpacingMultiplier=”2”:104px

和实际测量值相同。

TextView行高和间距的异常情况

TextView实际显示的每行高度并不总是和getLineHeight()方法获取到的行高相等(这也意味着每行的间距也并不总是等于getLineHeight()方法获取到的行高减去文字高度)。

TextView getLineHeight()方法的注释如下

/**

* @returnthe height of one standard line in pixels. **Note that markup

* within thetext can cause individual lines to be taller or shorter

* than this height, andthe layout may contain additional first-

* orlast-line padding.**

*/

也就是说如果某行文字内有markup(不知道是什么),那么该行文字高度可能会大于,也可能会小于getLineHeight()方法返回的高度。此外对TextView的首行和最后一行有一个额外的padding间距,这导致实际行高要大于getLineHeight()方法得到的行高,实际间距也要大于通过getLineHeight()计算得到的间距。

对首行行高实际测量得到如下数值。

android:lineSpacingMultiplier=”1”时,“首行行高=普通行行高”

android:lineSpacingMultiplier=”2”时,“首行行高=普通行行高+6px”

android:lineSpacingMultiplier=”3”时,“首行行高=普通行行高+12px”

android:lineSpacingMultiplier=”4”时,“首行行高=普通行行高+18px”

也就是说“首行行高=普通行行高 + 6 ×(android:lineSpacingMultiplier - 1)”

TextView源码分析

要了解为何android:lineSpacingExtra和android:lineSpacingMultiplier设置影响的是行高而不是行间距,以及为何首行和最后一行的行高和普通行不相等,需要通过TextView源码来进行分析。

TextView 构造函数部分源码和setLineSpacing()源码如下

case com.android.internal.R.styleable.TextView_lineSpacingExtra:

mSpacingAdd = a.getDimensionPixelSize(attr, (int) mSpacingAdd);break;

case com.android.internal.R.styleable.TextView_lineSpacingMultiplier:

mSpacingMult = a.getFloat(attr, mSpacingMult);break;

publicvoidsetLineSpacing(float add, float mult) {

if (mSpacingAdd != add || mSpacingMult != mult) {

mSpacingAdd = add;

mSpacingMult = mult;

if (mLayout != null) {

nullLayouts();

requestLayout();

invalidate();

}

}

}

即android:lineSpacingExtra的设置保存在mSpacingAdd成员变量中,android:lineSpacingMultiplier的设置保存在mSpacingMult成员变量中。

TextView getLineHeight()源码如下

publicintgetLineHeight() {

return FastMath.round(mTextPaint.getFontMetricsInt(null) * mSpacingMult + mSpacingAdd);

}

可以看到TextView计算行高就是将正常高度乘以mSpacingMult再加上mSpacingAdd得到的。

跟踪mSpacingAdd和mSpacingMult成员变量,发现在makeSingleLayout()方法中调用new StaticLayout构造方法时使用了这两个变量。在StaticLayout类的构造方法中调用了generate()方法,在generate()方法中又调用了out()方法,在out()方法中可以看到如下代码

if (needMultiply && !lastLine) {

double ex = (below - above) * (spacingmult - 1) + spacingadd;

if (ex >= 0) {

extra = (int)(ex + EXTRA_ROUNDING);

} else {

extra = -(int)(-ex + EXTRA_ROUNDING);

}

} else {

extra = 0;

}

其中needMultiply值定义为,即设置了android:lineSpacingExtra和android:lineSpacingMultiplier中任意一个,needMultiply的值就为true。

booleanneedMultiply = (spacingmult!= 1 || spacingadd!= 0);

那么只要设置了android:lineSpacingExtra和android:lineSpacingMultiplier中任意一个,就会计算一个extra的值,这个extra的值等于(below - above) * (spacingmult - 1) + spacingadd向上取整后的值。

在这之后有如下代码

lines[off + TOP] = v;

...

v += (below - above) + extra;

...

lines[off + mColumns + TOP] = v;

跟踪lines[]相关代码可以看到,lines[]是mLines的引用,而mLines中保存了每行文字的垂直位置信息,每个普通行文字有三个位置信息,分别对应mLines中的三个元素(mColumns = COLUMNS_NORMAL = 3, START = 0, TOP = 1, DESCENT = 2)。

因此lines[off + mColumns + TOP]表示的是下一行的TOP位置信息,将lines[off + mColumns + TOP] - lines[off + TOP]就可以得到下一行的TOP位置距离本行的TOP位置距离,也就是行高。显然lines[off + mColumns + TOP] - lines[off + TOP] = (below - above) + extra。如果忽略extra计算时的取整过程,则lines[off + mColumns + TOP] - lines[off + TOP] = (below - above) + extra = (below - above) + (below - above) * (spacingmult - 1) + spacingadd = (below - above) * spacingmult + spacingadd。这就解释了为何android:lineSpacingExtra和android:lineSpacingMultiplier设置影响的是行高而不是行间距。

在out()方法往前可以看到如下代码。

if (firstLine) {

if (trackPad) {

mTopPadding = top - above;

}

if (includePad) {

above = top;

}

}

跟踪includePad变量,可以看到是TextView的mIncludePad变量值,而TextView中mIncludePad固定设置为true,因此这里above = top;将执行,也就是说对首行文字,其above位置等于top位置,由此可以得出lines[off + mColumns + TOP] - lines[off + TOP] = (below - above) * spacingmult + spacingadd = (below - top) * spacingmult + spacingadd。也就是说首行文字的行高要比普通行高出(top - above) * spacingmult个像素。

注意到above = top的设定,首行文字在测量其行高时,其起始位置应当在文字top - above像素上方的空白位置。结合上文中首行行高的测量情况有如下数值。

android:lineSpacingMultiplier=”1”时,“首行行高=普通行行高+6px”

android:lineSpacingMultiplier=”2”时,“首行行高=普通行行高+12px”

android:lineSpacingMultiplier=”3”时,“首行行高=普通行行高+18px”

android:lineSpacingMultiplier=”4”时,“首行行高=普通行行高+24px”

也就是说“首行行高 - 普通行行高 = 6 ×(android:lineSpacingMultiplier)”这里的6显然就是top - above的数值。这和代码中得到的结论相同。

android中段落距离,Android中TextView 行间距和段间距设置相关推荐

  1. Android中TextView 行间距和段间距设置

    这里有一篇文章关于设置段落间距(仅供参考):https://blog.csdn.net/yingpaixiaochuan/article/details/77996793 TextView行间距设置 ...

  2. latex如何设置行间距和段间距

    latex如何设置行间距和段间距 设置全文行间距: \usepackage{setspace} \setstretch{1.2} 设置全文段落间距: \usepackage{setspace} \se ...

  3. php中控制段落的行距,如何设置行间距和段间距

    原标题:如何设置行间距和段间距 行间距是只行与行之间的距离,段间距则是相邻段落之间的距离,用户可以根据需求来调整文本的行间距与段间距. 1.设置行间距 默认情况下,Word自动设置段落内文本的行间距为 ...

  4. iOS 文字样式处理总结(字体、前背景色、斜体、加粗、对齐、行间距、段间距、动态获取字符串label宽高等)...

    在iOS开发中,常常会有一段文字显示不同的颜色和字体,或者给某几个文字加删除线或下划线的需求.NSMuttableAttstring(带属性的字符串),可以灵活实现以上功能. NSMutablePar ...

  5. 【LaTeX入门】04、设置行间距、段间距

    设置行间距.段间距 段落间距有关变量: \baselineskip:行基线间距. \lineskip :行间距. \baselinestretch:伸展因子. \parskip:部分段间距. \lin ...

  6. Android自定义view,圆形的TextView,并通过xml设置属性,AttributeSet中取值

    Android自定义view设置xml属性 一个圆形的自定义TextView,通过xml来设置背景颜色的属性 values/attrs <declare-styleable name=" ...

  7. word如何调整字间距离_Word如何快速调整行间距和字间距?

    WORD中调整行间距和字间距是文档编辑中经常性的操作,但如何快速调整,我还真想了一段时间,下面我介绍的方法不知能不能叫快速? 为了完整性先一般是如何调整行间距和字间距的. 行间距 选中要调整的文字段落 ...

  8. CoreText 轻松设置字体大小,间距,行间距,段间距,算高度

    [http://blog.sina.com.cn/s/blog_691a202f0101bq6q.html] 下面主要讲,如何设置字体,间距,并计算(带特定段间距,行间距,字间距,字大小)文字的高度. ...

  9. Qt QTextEdit设置行间距和段间距

    段间距比较容易实现,通过设置html的css即可实现段间距调整: 行间距需要利用Qt用的几个类配合实现: 代码比较简单具体实现如下: QString HD = ui->H1Edit->te ...

最新文章

  1. 【22,23节】Django的GET和POST属性笔记
  2. linux虚拟终端快捷键
  3. hashmap 存的是对象的引用地址_Java互联网架构-面试虐我千百遍HashMap源码真讨厌...
  4. 基于jquery的php分页,基于jQuery封装的分页组件
  5. java POI导出多张图片到表格(占位符方式)
  6. LeTax报错之 Incomplete \iffalse
  7. Android源码之路(二、AsyncTask)
  8. NYOJ 37 动态规划 回文字符串
  9. 解决THINKCMF后台文章的相册图集只能上传一个图片的问题
  10. mysql服务器无法启动
  11. 哪些情况会造成小程序违规或下架
  12. 针对VMware安装Win10需要安装.NET Framework 3.5常见的0x800F0906、0x800F081F错误解决办法
  13. Java 設計模式 - 適配器模式
  14. EXCEL应用:数据可视化终极教程
  15. 测试岗位面试题库---支付功能测试思路有哪些?
  16. 金蝶K3开发-工业单据显示物料图片
  17. c#简单几步实现圆角按钮
  18. 差动直流放大电路仿真 -- 单端输入,双端输入,共模,差模(附Multisim)
  19. python分割压缩_python实现文件压缩与解压
  20. 挤奶网络POJ2185

热门文章

  1. 【Android车载系列】第7章 车载通信-USB通信原理
  2. webpack 打包配置
  3. 计算机的鼠标左键的功能,老司机详解鼠标怎样自定义按键功能
  4. 书论46 米芾《书史》
  5. 怎样做校园外卖配送系统创业?打造一体化服务校园平台如何进行?
  6. Ableton Live Suite如何降低CPU负载?
  7. html怎么打开时出现动画效果,html5动画制作打开抽出卡片动画效果代码
  8. 【优秀的修图工具】泼辣修图 Polarr Photo Editor Pro for Mac
  9. PHP与redis队列实现电商订单自动确认收货
  10. IT人读《论语》:1.5节理解和感悟