写点什么

文字太多?控件太小?试试 TextView 的新特性 Autosizing 吧

用户头像
Android架构
关注
发布于: 1 小时前
  1. 动态编码,使用 TextViewCompat 中提供的方法。

  2. layout-xml 布局属性,需要使用 app: 命名空间下的属性,记住要添加 xmlns:app="http://schemas.android.com/apk/res-auto" 这个命名空间。


<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns: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">


<TextViewandroid:layout_width="match_parent"android:layout_height="200dp"app:autoSizeTextType="uniform" /></LinearLayout>


使用标准的 8.0 Api 的使用场景,在现阶段会非常的少,所以我们这里只是简单了解一下区别就好了,下面的文章内容会主要以 Support v26 的方式进行讲解。

2.2 Autosizing 基础

到这里,你应该对 Autosizing 有了基本的概念,知道它是干什么的。


那么,如果让你来设计一个这样的功能,你会想要做到哪些点?


  1. 有开关限制,只在我们需要的 TextView 上,才开启这个特性。

  2. 允许设置边界值,最大缩放和最小缩放。

  3. 能配置每次缩放的最小尺寸,例如:10sp 为粒度进行缩放。

  4. 能预设一些缩放的定位尺寸,例如预设一组尺寸,只让它在这个范围内的值中选一个。

  5. 方便的 Api ,可以通过 layout-xml 属性和动态编码的方式操作它。


嗯,功能上大概就是这些了,已经满足我的需要了。


如果你看了 Autosizing 的文档,你会发现,它全部都支持!


Autosizing TextView Doc:

https://developer.android.google.cn/guide/topics/ui/look-and-feel/autosizing-textview.html

2.3 Autosizing 开关

Autosizing 是直接作用在 TextView 上的,对于它的开启和关闭,我们可以直接操作 autoSizeTextType 属性。


对于动态编码,可以使用 TextViewCompat 的 setAutoSizeTextTypeWithDefaults() 方法,下面是它的方法签名。



参数中的 textView 是我们要操作的 TextView,而 autoSizeTextType,就是我们关心的 Autosizing 的开关属性了,它接受两个参数。


  • AUTO_SIZE_TEXT_TYPE_NONE:关闭自动调整功能。

  • AUTO_SIZE_TEXT_TYPE_UNIFORM:开启统一缩放碎片轴和垂直轴。


我们也可以通过 layout-xml 属性的方式,来设置 autoSizeTextType,因为是 Support ,所以使用的 app: 命名空间下的属性。


<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns: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">


<TextViewandroid:layout_width="match_parent"android:layout_height="200dp"app:autoSizeTextType="uniform" />


</LinearLayout>


app:autoSizeTextType 同样接收两个参数 uniform 和 none,含义和上面代码中设置的参数一致。

2.4 操作 Autosizing 的粒度

粒度的含义其实就是 Autosizing 每次变动的最小单位,当然在设置粒度的同时,你还需要为其设置一个缩放的范围,最大值和最小值。


这样,在 Autosizing 生效的时候,它会在这个范围内,按照我们设定的粒度,去动态的调整文字的大小。


想要操作这些属性,动态编码的方式你需要调用 TextViewCompat 的 setAutoSizeTextTypeUniformWithConfiguration() 方法。



参数很直观,没什么好解释的,一个最小值、一个最大值、变动的粒度、前面设置的尺寸的单位。


我们可以通过 unit 参数,通过 TypedValue 来设置前面设置的几个参数的单位,例如:sp 、dp、px,都可以。


这里操作的参数,在 layout-xml 中,都提供了对应的属性可供我们使用。


<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns: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">


<TextViewandroid:layout_width="match_parent"android:layout_height="200dp"app:autoSizeTextType="uniform"app:autoSizeMinTextSize="12sp"app:autoSizeMaxTextSize="100sp"app:autoSizeStepGranularity="2sp" />


</LinearLayout>


下面我们举两个例子看看,就清晰了。


在默认情况下,如果你没有设置这三个属性,Autosizing 会根据当前 TextView 控件的大小,估算出一个最大值和最小值,并且将粒度设置为 1sp 。



可以看到,它设置的尺寸是跳动的,非常的不可控,我们很难知道下一次缩放,会将 文本 尺寸,设置成多大,所以才需要使用 粒度 的概念来限制它缩放的大小。


例如,现在我们修改上面的例子,将(minSize,maxSize),限制在 (10sp,80sp)之间,粒度(Granularity)设置为 10sp,此时再来看它的效果。



到这里可以看到,它每次放大或者缩小,粒度都是以 10sp 为基准。


所以,如果你需要使用 Autosizing ,强烈建议你使用 粒度 来控制它缩放的大小,让它在可控的范围内使用。需要注意的是,这里介绍的三个属性,一定要设置在一个合理的范围内,否则 TextView 会认为这是一个无效的设置,将它忽略掉。

2.5 预设尺寸范围

如果你按上一小节,介绍的属性,设置了 Autosizing 的粒度,就可以在这个范围内,根据我们设置的粒度进行缩放。通常,使用粒度来控制基本上可以达到我们的要求,但是如果对缩放有更精准的要求,例如:[10.15,40,60,100] 这样的缩放,使用粒度就达不到我们的要求了。


针对这样的操作,Autosizing 也提供了对应的属性来设置,那就是 预设尺寸(Preset Size)。


如果想要使用预设尺寸,动态编码的方式,你需要操作 TextViewCompat 的 `setAutosizeTextTypeUnifo


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


rmWithPresetSizes()` 方法。



预设尺寸可以接受一个尺寸数组,Autosizing 就会从我们设定的尺寸数组中,取一个尺寸进行设置。同时你可以为这些尺寸设置一个统一的尺寸单位。


如果想要在 layout-xml 使用属性的形式使用预设尺寸,你首先需要一个 array 的资源,然后通过 autoSizePresetSizes 属性进行设置即可。


array 资源的格式:


<resources><array name="autosize_text_sizes"><item>10sp</item><item>12sp</item><item>20sp</item><item>40sp</item><item>100sp</item></array></resources>


定义好 array 的尺寸资源之后,就可以在 layout-xml 中使用它。


<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns: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">


<TextViewandroid:layout_width="match_parent"android:layout_height="200dp"app:autoSizeTextType="uniform"app:autoSizePresetSizes="@array/autosize_text_sizes" /></LinearLayout>


预设尺寸非常简单,这里就不再给运行效果了。

三、查缺补漏

到这里,我们就把 Autosizing 的基本使用细节,都讲解清楚了。但是,依然还有一些概念,是在文档上没有反应出来的,下面我们就来讲讲这些 “经验”。

3.1 TextView 必须限定尺寸

如果你想要使用 Autosizing,就必须对 TextView 这个控件,限定大小,不能使用 wrap_content 来作为限定符。


用官方文档话来说,使用 wrap_content 可能出现不可预料的效果。其实这也非常好理解,如果 TextView 的尺寸不是固定的,那就不存在 TextView 重新计算尺寸的依据了,同比放大 TextView 就可以达到容纳文字的效果了。


我在实际使用过程中会发现,它会阻止放大效果。例如一个 TextView 中使用了 Autosizing,一直增加文本内容,是可以正常缩小的,但是当你删除文本的时候,它并不会随之放大文字尺寸。


但是不确定还有没有其它的问题,这里建议按照官方文档的建议来操作,限定 TextView 的尺寸。

3.2 Autosizing 不能作用在 EditText 中

虽然通常作用在 TextView 上的新属性,对于同样用于显示文本的控件,例如:Button、EditText 等,都是同样适用的。

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
文字太多?控件太小?试试 TextView 的新特性 Autosizing 吧