一、前言
在应用开发过程中,可能需要这样的场景:一个现实区域有限的TextView
,但是需要显示不定长度的内容,在不调整控件的尺寸的情况下,需要将内容尽可能全部显示,只能通过调整字体的大小,但是如何调整却是个难题。在Android 8.0 (API level 26) 以上,你可以让TextView
中的文本根据自身布局自动调整大小,这个设定使得在不同的屏幕上为动态内容调整字体的大小变动非常简单。
Android 8.0 (API level 26) 以上?这个条件似乎很高啊,别忘了,Android还有个无所不能的支持库。通过26及以上版本的支持库,可以将这个限制放开到Android 4.0(API Level 14)及以上的系统(不过你的应用编译的targetSDKVersion必须在26及以上)。
二、设置TextView
文本自动调整大小
前面介绍到,你可以使用系统框架接口或者支持库,通过编程方式或者在XML不居中设置TextView
文本自动调整大小。你可以使用AndroidStudio属性窗口设置XML中TextView
的属性。
- 设置
TextView
文本自动调整大小的方法有以下几种:Default
默认缩放Granularity
按粒度缩放Preset Sizes
按预设定值缩放
注意:如果在XML布局中设置自动调整大小,强烈建议不要将
TextView
的宽高属性(layout_width
和layout_height
)使用wrap_content
进行控制,因为可能会出现预想不到的结果。
- 在XML中设置
TextView
文本自动调整大小,涉及到几个属性:android:autoSizeTextType
:自动调整大小的类型,取值none
(0,不自动缩放,默认)或者uniform
(1,水平和垂直均匀缩放文本大小适应容器),注意:这个功能不适用与EditText
,仅仅TextView
有效android:autoSizeMaxTextSize
:自动调整文本大小的最大值,可用的单位有:px(pixels),dp(density-independent pixels),sp(scaled pixels based on preferred font size),in(inches),还有mm(millimeters)android:autoSizeMinTextSize
:自动调整文本大小的最小值,可用的单位有:px(pixels),dp(density-independent pixels),sp(scaled pixels based on preferred font size),in(inches),还有mm(millimeters)android:autoSizePresetSizes
:预设定的尺寸数组(类型为uniform
时生效),会autoSizeStepGranularity
属性覆盖android:autoSizeStepGranularity
:自动调整字体大小的阶级(类型为uniform
时生效),默认1px,会被autoSizePresetSizes
属性覆盖
更多关于XML属性的描述及对应的接口API参考:TextView API Doc
2.1 默认缩放
默认缩放是使得TextView
在水平和垂直根据阶梯均匀缩放,默认缩放方式是指指开启了缩放功能,不设定任何值。
注意:默认的缩放的范围是:
minTextSize=12sp
,maxTextSize=112sp
,并且granularity=1px
-
编程方式定义默认缩放
调用setAutoSizeTextTypeWithDefaults(autoSizeTextType: Int)
接口进行配置,提供了两个值可选AUTO_SIZE_TEXT_TYPE_NONE
: 禁用缩放AUTO_SIZE_TEXT_TYPE_UNIFORM
:均匀缩放(设置此值表示启用缩放功能)
-
XML定义默认缩放
在XML中定义,只需要在TextView
中增加android:autoSizeTextType
属性,并赋值uniform
即可。
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:autoSizeTextType="uniform" />
2.2 按粒度缩放
按粒度缩放,是指你可以定义一个文字最小值和最大值的范围,以及缩放的间距,TextView
的文本大小在最小值与最大值之间,并且每次增大或者减小以缩放的间距变化。
- 编程方式设置按粒度缩放
调用API接口setAutoSizeTextTypeUniformWithConfiguration (autoSizeMinTextSize: Int, autoSizeMaxTextSize: Int, autoSizeStepGranularity: Int, unit: Int)
进行设置
参数 | 类型 | 说明 | 备注 |
---|---|---|---|
autoSizeMinTextSize | Int | 最小值 | - |
autoSizeMaxTextSize | Int | 最大值 | - |
autoSizeStepGranularity | Int | 间隔 | - |
unit | Int | 计量单位 | 前面三个参数的计量单位,取值参考:TypedValue |
- XML方式设置按粒度缩放
- 设置启用缩放:
autoSizeTextType
属性的值设置为uniform
- 设置粒度缩放的属性:分别设置
autoSizeMinTextSize
、autoSizeMaxTextSize
、
utoSizeStepGranularity
这三个属性的值
- 设置启用缩放:
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:autoSizeTextType="uniform"
android:autoSizeMinTextSize="12sp"
android:autoSizeMaxTextSize="100sp"
android:autoSizeStepGranularity="2sp" />
注意:按粒度缩放和按预设定值缩放是相互冲突的,所以请不要在XML中同时配置两种,否则会出现意想不到的结果
2.3 按预设定值缩放
按预设定值缩放,就是给定预设定的字体大小列表,文字的缩放只能在预设定的值中选取一个最合适的。
- 编程方式设置按预设定值缩放
调用接口setAutoSizeTextTypeUniformWithPresetSizes(presetSizes: IntArray, unit: Int)
进行设置
参数 | 类型 | 说明 | 备注 |
---|---|---|---|
presetSizes | iIntArray | 预设定制数组 | - |
unit | Int | 计量单位 | 前面三个参数的计量单位,取值参考:TypedValue |
- XML方式设置按预设定值缩放
- 设置启用缩放:
autoSizeTextType
属性的值设置为uniform
- 设置预设定值数组:
autoSizePresetSizes
属性的值为res/values/arrays.xml
中定义的数组
- 设置启用缩放:
<resources>
<array name="autosize_text_sizes">
<item>10sp</item>
<item>12sp</item>
<item>20sp</item>
<item>40sp</item>
<item>100sp</item>
</array>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:autoSizeTextType="uniform"
android:autoSizePresetSizes="@array/autosize_text_sizes" />
注意:按粒度缩放和按预设定值缩放是相互冲突的,所以请不要在XML中同时配置两种,否则会出现意想不到的结果
三、使用支持库实现文本自动缩放
其实使用支持库实现跟使用系统框架API差不多,差别就是系统框架API使用TextView
内部API,通过TextView
对象进行调用,而支持库通过TextViewCompat
定义的静态方法调用,并且需要将TextView
对象作为参数传入
-
编程方式实现缩放(支持库实现)
分别对应的接口是:TextViewCompat.setAutoSizeTextTypeWithDefaults(textView: TextView, autoSizeTextType: Int)
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration (textView: TextView, autoSizeMinTextSize: Int, autoSizeMaxTextSize: Int, autoSizeStepGranularity: Int, unit: Int)
TextViewCompat.setAutoSizeTextTypeUniformWithPresetSizes(textView: TextView, presetSizes: IntArray, unit: Int)
-
XML方式实现缩放(支持库实现)
XML方式实现,也跟使用系统框架差不多,有两点差别:- 需要额外引入支持库的属性,在布局的根节点上添加
xmlns:app="http://schemas.android.com/apk/res-auto"
声明(其中app
是可自定义的,这里就不多说了) - 属性调用使用引入的属性(引入属性的时候使用
app
,所以使用app
替代系统框架中的android
)
- 需要额外引入支持库的属性,在布局的根节点上添加
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
app:autoSizeTextType="uniform"
app:autoSizeMinTextSize="12sp"
app:autoSizeMaxTextSize="100sp"
app:autoSizeStepGranularity="2sp" />
</LinearLayout>