【Android】TextView文字长度测量和各种Paddding解析
老规矩,先上张图
o,这篇好像是分析篇,没有效果图。不管了,位置占着,老规矩不能坏,下面开始正文。
***
这篇博客会讲得比较杂:
- TextView里各部分的大小该怎么测量?
- 如何计算每行文字的长度?
- 设置android:maxLines="1"和android:singleLine="true"有什么区别?
- 为什么设置android:maxLines="1"时TextView的跑马灯效果就不能正常工作?
TextView里各部分的大小该怎么测量?
虽然我们平时只用TextView显示纯文本数据,但其实TextView支持设置Background,四周的drawable小图标,以及Span数据比如文本或图片。在Android里不管是什么控件都是占据一个矩形的空间,那么在一个TextView里该如何计算各个矩形的大小呢?下面是TextView提供的各个获取长度宽度的接口:
getWidth(), getHeight()
getPaddingLeft/Right/Top/Bottom()
getCompoundPaddingLeft/Right/Top/Bottom()
getExtendedPaddingBottom/Top()
getTotalPaddingLeft/Right/Top/Bottom()
先看一下布局代码:

@drawable/icon_person_n

下面是效果图,做了一些标注:

下面来看一下上述获取长度的接口的数据,你可以使用打日志方式,我是比较习惯用调试方式:

所以,总结一下:
getWidth(), getHeight():对应你代码里的layout_width和layout_height。
getPaddiingLeft/Right/Top/Bottom():对应代码里的Padding。
以上两个比较容易理解,毕竟经常打交道。
getCompoundPaddingLeft/Top/Right/Bottom(): 翻译成中文就是获取混合的Padding, 既然是混合的,那么它的值也就是padding + 图片的大小 + drawablePadding的值。说得通俗点就是,它是获取文字区域到TextView边界之间的间隔。附上源码:

getExtendedPaddingTop():这个是当有部分文字没有显示出来时,也就是设置了maxLine时,它的值就等于首行文字到TextView顶端的距离。同理,getExtendedPaddingBottom()就是最后一行文字到TextVeiw底部距离。其他情况下,他的值等于getCompoundPaddingTop/Bottom()的值。这个源码不多,但也不怎么好讲解,就贴两张图对比下,就明白了。


getTotalPaddingLeft/Right/Top/Bottom():翻译下就是获取总的Padding值,看了下源码,左右的值直接就是等于compoundPadding的值,上下的值等于ExtendedPadding的值再加上offset的值(跟Gravity的垂直方向的布局有关。说得通俗点就是,不管有没有maxLines,上下的值都分别等于首行到TextView顶端和末行到TextView底部的值。
这些接口除了前面两个比较常用外,其他基本很少用吧,我也是因为在看TextView的跑马灯部分的源码才接触到,然后为了弄明白才记录下来的。至于后面那些接口的应用场景,getCompoundPadding()这个的应用场景倒是很明确,可以用来判断相应的drawable是否发生点击事件之类的需求。至于extendedPadding和totalPadding这两个的应用场景,我想了想,觉得应该是涉及需要计算显示出来后的文字高度的相关需求时会用到吧。有对这些接口很熟悉的童鞋可以分享出来哈,一起学习学习。
最后用一张图总结一下,我把TextView分成内容区域,内容区域和TextView边界之间的间隔就是padding的值,内容区域包括drawable区域和文字区域,drawable区域和文字区域之间的间隔就是drawablePadding的值,文字区域和TextView之间的间隔就是CompoundPadding的值。

如何计算每行文字的长度?
Q:每行文字的长度不就等于TextView的宽度吗?直接getWidth()不就好了?
A:再看一下上面那部分内容你就清楚了,只有当TextView宽度设置为wrap_content,且没有背景图或drawable时,文字的长度才等于getWidth();当文字很少,没有填充满时,或是溢出时,文字的长度都得另外计算。
Q:每行文字的长度不一样长吗?
A:因为TextView有自己的换行策略,如下图所示,显然每行的文字长度不一样长。

Q:文字的长度是指哪段长度?
A:看需求吧,我觉得通常情况下都是只需要计算显示在屏幕上的可见区域的每行文字的长度即可。还有那么一种需求,当设置了溢出内容用...表示时,那么其实每行文字的实际长度就不止可见区域那么长了。
那么该如何计算文字的长度呢?单单根据上一部分里的各种Padding值肯定不够,根据各种Padding顶多计算出文字区域的宽度,但实际上每一行文字并不会那么刚刚好占满文字区域的宽度,那么就还得借助其他来进行计算。
方法1:TextView.getPaint().measureText(String text)

但这种方法只是测试传入的text在该TextView的配置下的总长度,并不是计算每一行的长度。
方法2:TextView.getLayout().getLineWidth(int line)

TextView对应的是图14,正好,利用方法1验证一下,这个方法计算得到的是不是每行文字的长度。

完全正确,所以说这个方法确实计算得到的是每一行文字的实际长度,注意这里是实际长度,也就是说当设置singleLine属性时,用这个方法测量得到的是一整行文字的长度,包括溢出部分。
设置android:maxLines="1"和android:singleLine="true"有什么区别?
官方是推荐说不要再使用singleLine,用maxLines="1"代替。但其实这两个的效果是不一样的,官方api接口里有说明,都是英文我就不贴图了,大概翻译下:
maxLines:限制TextView的最高高度,大概就是指通过限制行数来限制最高高度。
singleLine: 强制设置TextView的文字不换行。
区别就是:maxLines还是会默认自动进行换行策略,假如一段文字自动换行后有5行,maxLines设置为1,那么就只显示第一行的内容,其他行不显示。
但是,如果是设置了singleLine, 那么这段可以有5行的文字将会被强制放在1行里,然后看最多能显示多少字符,剩下的不显示。
这样的区别就是导致了很多人在使用TextVeiw的跑马灯效果时不能正常工作的状态,所以下面单独列出个问题来讲。
为什么设置android:maxLines="1"时TextView的跑马灯效果就不能正常工作?
明白了maxLines="1"和singleLine的区别后,只要再明白跑马灯的原理,就很容易理解为什么设置成maxLines="1"时跑马灯不工作了。我在上一篇博客里写过跑马灯启动的条件,具体的分析可以去上一篇看,这里大概说下。
跑马灯要启动要同时满足四个条件,其中有一个条件就是这一行的文字长度要大于文字区域的宽度,文字区域的宽度就是TextView的getWidth()扣去ComPoundpaddingLeft再扣去CompoundPaddingRight剩下的长度。
如果是maxLines="1"的话,那么就像上一问中分析的那样,所有的文字其实已经被自动换行了,只显示第一行,而换行是什么,就是为了让每行文字的长度超过文字区域的宽度才进行的换行,也就是说,如果一段文字经过TextView的换行后,那么每行的文字长度都不会超过文字区域的长度。这样一来,自然就不满足跑马灯的启动条件之一了,跑马灯也就不能正常工作了。
singleLine的话,则是不会对一段文字进行换行处理,这样一来,自然就超过了文字区域的长度,所以如果要设置跑马灯效果的话,只能用singleLine不能用maxLines="1"。
【Android】TextView文字长度测量和各种Paddding解析的更多相关文章
- Android:TextView文字跑马灯的效果实现
解决TextView文字显示不全的问题. 简单设置跑马灯的效果: <TextView android:id="@+id/textView" android:layout_wi ...
- Android TextView 文字居中
有2种方法可以设置TextView文字居中: 一:在xml文件设置:android:gravity="center" 二:在程序中设置:m_TxtTitle.setGravity( ...
- Android TextView文字描边的实现!!
Android开发:文字描边 转自:http://www.oschina.net/code/snippet_586849_37287 1. [代码][Java]代码 1 2 3 4 5 6 7 8 9 ...
- Android TextView文字过多时通过滚动条显示多余内容
方法一: TextView文字过多,显示不全,怎么办?我们可以为Textview添加滚动条. <TextView android:id="@+id/bus_detail_content ...
- Android TextView文字横向自动滚动(跑马灯)
TextView实现文字滚动需要以下几个要点: 1.文字长度长于可显示范围:android:singleLine="true" 2.设置可滚到,或显示样式:android: ...
- Android TextView文字超出一屏不能显示其它的文字 解决方案
在android上面让TextView 过多的文字实现有滚动条,之前想简单了以为设置TextView的属性就可以实现,结果还是需要ScrollView配合使用,才能达到滚动条的效果有两种方式实现, 一 ...
- Android—— TextView文字链接4中方法
转自:http://ghostfromheaven.iteye.com/blog/752181 Android 的实现TextView中文字链接的方式有很多种. 总结起来大概有4种: 1.当文字中出现 ...
- Android TextView文字透明度和背景透明度设置
textview1.setTextColor(Color.argb(255, 0, 255, 0)); //文字透明度 控件设为半透明: 控件名.getBackground().setAlpha(in ...
- android TextView 文字垂直的设置
<TextView android:id="@+id/tv_status" android:layout_width="wrap_content" and ...
随机推荐
- tbl.js div实现的表格控件,完全免费,不依赖jquery
html上现在有比较好用的表格控件是datatable,但是编辑.按钮等部分是收费的,只有基础功能免费.而且尺寸发生变化时需要手工刷新等繁琐操作较多.所以我开发一个免费的供大家使用. 本项目已用于&q ...
- Angular企业级开发(6)-使用Gulp构建和打包前端项目
1.gulp介绍 基于流的前端自动化构建工具,利用gulp可以提高前端开发效率,特别是在前后端分离的项目中.使用gulp能完成以下任务: 压缩html.css和js 编译less或sass等 压缩图片 ...
- 《JAVASCRIPT高级程序设计》错误处理与调试
一.错误处理 错误处理在程序设计中的重要性是毋庸置疑的,任何有影响力的web应用程序都需要一套完善的错误处理机制.良好的错误机制可以让用户得到提醒,知道发生了什么事. 1.try-catch语句 tr ...
- 框架篇:Spring+SpringMVC+hibernate整合开发
前言: 最近闲的蛋疼,搭个框架写成博客记录下来,拉通一下之前所学知识,顺带装一下逼. 话不多说,我们直接步入正题. 准备工作: 1/ IntelliJIDEA的安装配置:jdk/tomcat等..(本 ...
- GitLab Wiki 内容恢复版本管理
原来一直在网站上写Wiki文档, 最近手欠误删一篇文档, 想要恢复文档时才发现原来gitlab的Wiki是用git管理的从此再也不用为误删担心了 实现步骤: mac系统安装gollow brew in ...
- react构建淘票票webapp,及react与vue的简单比较。
前言 前段时间使用vue2.0构建了淘票票页面,并写了一篇相关文章vue2.0构建淘票票webapp,得到了很多童鞋的支持,因此这些天又使用react重构了下这个项目,目的无他,只为了学习和共同进步! ...
- matlab for循环应用(阶乘及the day of year)
一.N的阶乘 %脚本文件:test.m %N的阶乘 使用举例 % 定义变量 % ii ---循环变量,也就是循环次数 % N ---N的阶乘 % N_factorial --计算N的阶乘 clc;cl ...
- IIS7.0发布后关于"不能在此路径中使用此配置节”的解决办法
在系统为window sever2008,iis7.0上安装后发布出现 IIS Web Core 通知 BeginRequest 处理程序 尚未确定 错误代码 0x80070021 配置错误 不能在此 ...
- Spring MVC 的环境搭建和入门小程序
1.1.下载spring框架包. 1.1.1百度搜索Spring Framework. 进入spring官网,在网页右边选择想要下载的版本.如图 1.1.2进入页面按Ctrl+F搜索Distribut ...
- web开发之Servlet 一
因为最近在研究公司一套新的框架,发现这套框架的底层是对Struts2,Spring 封装后的WEB应用框架,而我发现如果仅仅是利用这个框架开发,确实很容易快速上手,做业务来说是没有问题的,但我觉得如果 ...