TextView 所谓的文本控件,是android界面设计和开发中最常用的一个控件,也是我们需要掌握的最重要的控件之一,甚至没有之一。阅读多android官方文档的童鞋们可能会发现android原生开发中使用的控件诸如Button,Checkbox,甚至EditText等都是从TextView基础上衍生出来的。正如很多武侠小说中描述枪为百兵之王,那么TextView也可以称作android的可视化控件之祖,当然View这个远古老祖宗除外。这一章就让领略一下TextView使用的一点皮毛。
学习环境:
- 一台电脑
- OpenJDK 11+ 或者 JDK 8.0+,推荐前者,亦是官方推荐,无论学习还是开发
- Android Studio 3.4.0+ 兼SDK,AVD以及Gradle等插件工具
Java编程基础是必要的软技能和基础,如果没有接触过,请找一本Java编程开发基础教程恶补一下。环境安装配置是大家需要做的额外功课,
这里不教授软件安装过程。Android Studio安装过程确实是一个阵痛,但是也是大家必修的一课,过了这一关迎接你的将是android开发的星辰大海。这里记述的是很基础甚至相对细致的开发基础,面向的是和作者一样以前未接触过android开发,但又心生向往的小白新手。
初识****TextView
TextView通常作为文本标签控件使用,具有常用控制文本标签外观,颜色,尺寸大小,位置等属性,同时与Html中诸如等纯文本控件不同的是,TextView更像是一个把文本装在一个盒子里面并展示的控件,它不仅控制着盒子里的文本的如何显示,同时也控制着盒子本身的显示,例如TextView在整个空白界面的布局位置以及盒子本身的大小。
图1. TextView基本使用
在图1中展示了TextView最基本的一种用法-文本标签。这种使用方式比较常见,突出使用的TextView的属性通常如图上所示:
- id: 控件身份表识,如果你是一个静态文本标签,在后续程序的操作中不会改变,比如表单项目的名称,那么该属性就不是必要的。通常我们需要在程序代码中操控控件,改变控件一些属性时需要使用该属性去获取控件实例。
- layout_width, layout_height以及layout_gravity等以layout_打头的都是布局属性,需要和LinearLayout等布局容器控件结合使用,这部分会在后续讲解布局容器的章节中详细介绍。
- text: 你要显示在界面上的文本字符。
- textColor: 文本颜色。
- textSize: 文本大小。
- gravity: 文本在文本框中的对齐方式。
- padding: 边距。
- margin:间距。
在这里需要多说两句,图示代码并不符合产品应用程序代码规范,通常我们需要将TextView的属性提炼到样式(style)中。即使不使用style,像textColor以及textSize这些属性值,都应该分别配置到color.xml以及dimens.xml等文件中。如果TextView是一个静态文本标签,那么它的text属性值应该放入strings.xml中。对于最后一点很多应用商店审查时,甚至是强制的。如果你考虑以后需要做多语言版本,那么你更应该这么做了。当然,在设计开发初期阶段,你可以像图示方式去处理,方便你设计出你想要的效果和快速定位问题。
2. gravity vs layout_gravity
Gravity和layout_gravity都是对齐方式的属性,两周很容易搞混,但是两者的使用有很大的不同,这也与我将TextView比作一个装着文本的盒子的比喻有关。
Gravity属性是控制文本在TextView这个盒子里的对齐,但盒子本身不会变化,如下图所示:
图2 gravity的左对齐和居中对齐
而layout_gravity则需要配合包容TextView控件特定的布局容器控件一起使用才有作用,它通常只是控制TextView这个蓝色选中高亮的小盒子在布局容器这个大盒子里的位置,如下图所示:
图3 layout_gravity的垂直居中和置底
3. 文本缩略
文本缩略是TextView的另一种常用的用法,通常用于显示类似事项备注等长文本。例如很多日历app中通常会带有事项备忘录功能,因为受限手机设备屏幕大小显示,每个事项备注信息通常会简略显示。通常文本缩略会显示文本的启示一段,后面的文字略去,代替以省略号显示, 如下图所示:
图4 TextView文本省略
要实现TextView的文本显示,我们需要借助下面几个属性:
- lines或者maxLines: 行数,允许显示的行数
- Ellipsize:省略设置,设置省略的位置
通过上述属性的设置,我们就可以使得TextView的长文本缩略显示。需要注意在android studio的设计界面上并不会显示省略号,但是在虚拟机或者实机测试中都是会显示省略号,所以说明上述属性是可以正确工作的。另外在android的旧版本中还有一个单行文本属性singleLine,在此声明,在新版本android中TextView这个属性已经废弃,尽管它还可以工作,但是大家在后续开发中最好不要再使用。
此外,有注意到LinearLayout的horizontal形式下layout_weight会使得TextView的缩略失效的情况。目前本人没有碰到该情况,在此提及一下。
4. Font Family
Font Family通常用于指定字体,android studio在attributes面板中提供了downloadable的字体服务以方便字体设置如下图所示。说实话,这个属性我们通常不太会使用,而且对中文字体显得不是很友好,所以略微提及。
图5 Downloadable Font Family
具体操作,选中需要设置的TextView控件,打开Attributes面板,找到fontFamily选项,在下拉列表中选择More Fonts,在新的面板中可以选择你想要的字体。当然需要这个功能你需要一个3.0+以上版本的android studio。
5. Span 文本片段
Span对TextView是对文本的分段化处理的衍生出来的产物,提供了丰富的文本片段的多样化处理。例如,通过BackgroundColorSpan突出文本片段的背景。通过ClickableSpan给特定文本片段指定点击事件。甚至可以通过URLSpan实现跨应用处理等。此外,你可以结合上述多种手法推出组合拳打法,真是绝妙的设计。Span文本片段的操作有多个途径,这里介绍其中比较常用的两种:
- SpannableString
SpannableString是一个CharSequence的具体实现。是不是对CharSequence很熟悉?没错,对java很熟悉的朋友们,对它应该不会陌生。因为它就是lang包中String类的接口。SpannableString的原理很简单。它包装了一个完整的长文本,并指定Span对这个长文本中某一段文本进行渲染处理。具体实例看下图:
图6 SpnnableString的使用
上述例子中我们创建了一个访问百度的事例,对文本中的“baidu”进行字体放大突出显示,给baidu网址添加链接事件。首先创建一个包含“我们需要访问baidu,请点击www.baidu.com”的SpinnableString对象实例,然后通过AbsoluteSizeSpan对象对“baidu”片段所在范围内的文本指定大小渲染,再通过ClickableSpan对象对“https://www.baidu.…
需要注意的是ClickableSpan对象只对具有LinkMovementMethod的TextView起作用,所以需要对TextView设置MovementMethod。
- SpannableStringBuilder
相对于SpannableString,个人更喜欢在动态构建复杂文本对象时候使用SpannableStringBuilder,除非你想锻炼你的数数能力。SpannableStringBuilder不需要你事先指定完整的文本,它具有动态拼接能力而不需要程序员去指定片段的起止范围,这一点是SpannableString所不具备的。此外它具备了SpannableString一样的功能,说白了就是你有的我也有,你没有的我还是有。下面我们看一下使用SpannableStringBuilder对上述事例的处理。
图7 SpannableStringBuilder的使用
如上图所示,我们通过SpannableStringBuilder复刻了访问baidu的例子,但是很可惜的是,越是强大好用的新技术总是要求比较高,SpannableStringBuilder需要Android API 21+才能使用,所以对于21以下的同学,乖乖使用第一种方法,或者你可以自己通过SpannableString封装一个SpannableStringBuilder实现。
6. 自定义背景样式**-Background****的使用**
对于TextView我们通常只需要设置上面小节的基本属性就可以满足很多基本工作。但是个性化时代的到来,使得很多app在界面设计上提出更高的要求。因此更多个性化绚丽多彩的界面也成为基本要求的一部分。对于TextView而言,我们可以通过设置Background属性做到一定的个性化设计。
Background属性用于设置TextView背景展示,不仅限于通过指定背景颜色,还可以借助图片资源甚至通过android内建的诸如shape,layer-list等矢量绘制来实现TextView背景的个性化设置,可谓相当灵活。
-
指定背景颜色
-
在资源文件夹res下的values目录的colors.xml中添加一个颜色。
< color name="colorGray">#cccccc</ color>
-
给TextView的背景属性引用colors.xml设置的颜色值。
android:background=“@color/colorGray"
最后呈现效果如下图所示
图8 指定颜色的Background
- 2. 指定图片作为背景
这种方式不太推荐,所以不在此展开讲述。因为非矢量图片在不同尺寸的设备中显示有差异,很难做到满意的效果。大体过程和指定颜色一致,只是指定资源的地方从color值换成mipmap下的图片文件。
-
3. 指定矢量图形
-
新建资源文件,选择shape,取名为custom_background
-
在shape文件中定义一个矩形,并通过gradient给矩形设置渐变色,最后通过corners赋予圆角特性。
-
给background属性指定shape矢量图形
android:background=“@drawable/custom_background"
最终我们将得到一个带有圆角的渐变色背景的类圆角按钮的TextView
通过background个性化定值时,通过指定背景颜色不能满足你的个性化需求时,推荐还是尽量采用矢量图形的方式,通过shape可以满足你基本的自定义静态效果,通过layer-list层叠图形将多个矢量图形叠加组合足以应对复杂一些的个性化需求,配合selector甚至能做到基本的交互状态设置。
7. Style
Style简单可以认为是一组控件属性的组合设置,其概念和Html中使用css如出一辙。和使用css一样,style可以简化控件的属性配置,让UI文件或者布局文件看起来更加简洁而不臃肿,更易维护,同时增加了可复用性。虽然单个控件的style并不能减少代码量,但是在复用的作用下,积少成多,你的app体积也能得到精简,从而使得其整体性能有所提升。所以不要小看这么一小步的作用。正如经济学里的复利一样,在一定的经济基础上,通过不停的复利收益,在未来某一天你也可以收获不菲的收益。合理有效使用style,你总能从中受益。
设置TextView样式其实有好几种方式:通过TextAppearance,通过Style,通过TextView本身还有通过设置theme。
通过控件本身设置样式不再累述。对于theme作者还不是很明了,还需要深入研究,大体给我的感觉就是系统的成体系的style的组合套餐。而TextAppearance是一个类似style的奇葩而鸡肋的东西,调研过很多资料,确实没有看到大牛们有对这个属性的存在说出一个合理的所以然来。上述四种方式都有应用的优先级先后顺序大体是:本身 > style > theme > TextAppearance.
这里对style做一个具体的事例展开,下面通过TextView模拟一个save button。这个button具有深底圆角边框,并附有“保存”字样的,上下左右留有一定边距,上下窄左右宽,点击后底色会变深:
-
在colors.xml定义两个颜色用于按钮默认的背景色和按钮被按下状态时的深一点的背景色。
< color name="colorSaveButton">#5080FB</ color> < color name="colorSaveButtonDark">#2457DA</ color>
-
在自建的dimens.xml定义按钮的上下边距。顺便提一句在UI设计规范中,需要注意边距留白最好是8个单位的倍数,而按钮的大小至少要有24个单位以便易于触按操作,太小的话会造成手指在手机屏幕上触按障碍。
< dimen name="buttonVerticalPadding">8dp</ dimen> < dimen name="buttonHorizontalPadding">16dp</ dimen> < dimen name="buttonRadius">5dp</ dimen>
-
使用在background小节中提到的selector做一个背景交互状态的设置,实现按钮按下时的背景色变换。
-
在strings.xml文件中添加“保存”文本。
< string name="save_button_text">保存</ string>
-
在styles.xml创建save button的样式,使用上面的配置设置TextView的属性值。注意,如果需要让selector触按效果触发,目标TextView必须是clickable。
<item name="android:background">@drawable/save_button</item> <item name="android:textColor">@color/colorWhite</item> <item name="android:paddingTop">@dimen/buttonVerticalPadding</item> <item name="android:paddingBottom">@dimen/buttonVerticalPadding</item> <item name="android:paddingLeft">@dimen/buttonHorizontalPadding</item> <item name="android:paddingRight">@dimen/buttonHorizontalPadding</item> <item name="android:gravity">center</item> <item name="android:clickable">true</item> <item name="android:focusable">true</item> -
给TextView指定style.
最终我们得到如下效果:
所以大家可以看到style结合shape,selector或者layer-list可以变得很强大。所以也推荐使用这种方式,虽然看上去步骤有点多,但是使用习惯之后会让你的工作变得很轻松。
8. drawable 和 drawablePadding
这一节介绍两个个人比较喜欢的TextView所有的比较特别的属性。此drawable非彼drawable。准确来说drawable属性应该具体指如下四个属性drawableLeft,drawableTop,drawableRight和drawableBottom。而drawablePadding是和前面四个属性配套使用的一个属性。我们先来看一个图示,展示一下这些属性的使用效果。
图9 drawable的使用
正如上图所示,这里在应用头部创建了四个水平排放的带图标的菜单按钮。每个菜单按钮由一个图标和文字组成。而每个按钮都是由TextView创建而成。这个效果就是有TextView的drawable属性实现。你甚至可以将图标放在上下左右任何一个方向。具体事例过程如下:
-
在colors.xml新建两个颜色作为菜单项的默认背景色和点击下的状态背景色,和style事例一样。
< color name="colorButton">#5080FB</ color> < color name="colorButtonDark">#2457DA</ color>
-
新建selector资源文件,添加默认渐变背景和点击下的深色背景色。
-
在styles.xml文件中添加菜单项样式。
<item name="android:background">@drawable/menu_button</item> <item name="android:padding">@dimen/buttonHorizontalPadding</item> <item name="android:drawablePadding">@dimen/buttonVerticalPadding</item> <item name="android:gravity">center_horizontal</item> <item name="android:textColor">@color/colorWhite</item> <item name="android:clickable">true</item> <item name="android:focusable">true</item> -
导入四个菜单项矢量图标资源文件。
-
在strings.xml中添加四个菜单项文本。
< string name="home_menu">主页</ string> < string name="done_menu">完成</ string> < string name="undo_menu">未完成</ string> < string name="warning_menu">预警</ string>
-
通过LinearLayout加四个TextView并应用菜单样式,矢量图标,文本生成菜单栏。
正如最终的效果图所示,通过drawableTop在菜单项上部设置一个图标,而通过drawablePadding设置图标和文本之间的间距。通过选择drawableLeft或者drawableBottom等,你还可以在不同方向上设置图标。在构建一些菜单项时候就很有用。
总结
上述8个小节分别粗浅的介绍了TextView的一些属性,并配合一些事例对其使用进行了展开。每一小节其实也有很多东西可以深挖研究。篇幅有限,只能简单讲解一下TextView一点皮毛的使用。很多东西很基础很简单,但对于小白新手而言也是很重要的东西。本人也是新入门,所以通过这种方式,将学习过程中的一些细枝末节加以记录,积少成多,聚沙成塔。如果你们也有TextView有趣的使用方式,也可以分享出来。