热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android安卓中的TextView自动调整文字大小——Autosizing功能详解

Android8.0已经发布了有一阵子了,如果你有在关注它,你应该会知道它新增了一个对于TextView字体大小变动的新特性:Autosi

Android 8.0 已经发布了有一阵子了,如果你有在关注它,你应该会知道它新增了一个对于 TextView 字体大小变动的新特性:Autosizing。

本身这个新特性,如果只是在 Android 8.0 才有效,对于开发者而言,就显得有点鸡肋了,可能还需要一段时间才能普及使用。不过呢,在 Android Support v26 之上,也对 Autosizeing 提供了兼容支持,最低可以支持到 Android Level 14。

这样,我们就有了研究的必要了,接下来本文就来讲解一下,Autosizeing 属性,你在使用过程中的所有细节。

一、什么是 Autosizeing?

Autosizeing 允许 TextView 根据其内部文本的显示大小,动态的调整其 TextSize 属性值得大小,通过此设置,开发者可以很轻松的在具有动态内容的情况下,对不同的屏幕中,文本大小进行优化。

简单来说,一个 100dp 长度的 TextView ,正常来说只能显示 10 个 10dp 的文字,而如果它的内容超出了 10 个字,以前的通用做法,是通过属性设置,让它在末尾显示 “…” 。而采用了 Autosizeing 这个新特性,它的方案是将字体的尺寸缩小,例如缩小到 8dp,让 TextView 可以容纳下更多的文字,显示完全。而这一切,使用 Autosizeing 我们只需要设置一些属性就可以做到,非常的简单。
在这里插入图片描述
上面这个 Gif 应该可以很直观的描述 Autosizeing 的特性,而它也反映出,触发 Autosizeing 重新计算 TextSize 的时机有两个:

  1. TextView 中的文字增多到无法容纳的地步。
  2. TextView 本身的尺寸被放大或缩小了。

Autosizeing 的核心设计思想,就是为了让 文本 尽可能的完全显示在既定大小的 TextView 中,哪怕是修改它的文字大小。

二、使用 Autosizeing

2.1 Autosizeing 不同使用方式

前面也提到,使用 Autosizeing 其实是区分使用 Android Api Level 26(8.0) 和 使用 Support Library v26 两种。它们的使用方式,会略微有点区别。

下面,我们先来了解一下它们之间的区别。
Autosizeing 的带来的效果很简单,就是根据文字的内容,动态修改 TextSize ,而想要使用它,可以通过动态编码和静态的 layout-xml 布局属性的方式使用。

对于 Android 8.0 Api:

  1. 动态编码是直接操作的 TextView 上的方法。
  2. layout-xml 布局属性,是使用的 android: 命名空间下的属性进行设置。



而在低于 Android 8.0 的设备上,只能使用 Support v26 了。此时,TextView 上并没有对应的方法能让我们调用,所以我们需要绕一层。

  1. 动态编码,使用 TextViewCompat 中提供的方法。
  2. layout-xml 布局属性,需要使用 app: 命名空间下的属性,记住要添加 xmlns:app="http://schemas.android.com/apk/res-auto"这个命名空间。




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

2.2 Autosizeing 基础

到这里,你应该对 Autosizeing 有了基本的概念,知道它是干什么的。
那么,如果让你来设计一个这样的功能,你会想要做到哪些点?

  1. 有开关限制,只在我们需要的 TextView 上,才开启这个特性。
  2. 允许设置边界值,最大缩放和最小缩放。
  3. 能配置每次缩放的最小尺寸,例如:10sp 为粒度进行缩放。
  4. 能预设一些缩放的定位尺寸,例如预设一组尺寸,只让它在这个范围内的值中选一个。
  5. 方便的 Api ,可以通过 layout-xml 属性和动态编码的方式操作它。

嗯,功能上大概就是这些了,已经满足我的需要了。
如果你看了 Autosizeing 的文档Autosizeinging TextView Doc,你会发现,它全部都支持!

2.3 Autosizeing 开关

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

对于动态编码,可以使用 TextViewCompat 的 setAutosizeingTextTypeWithDefaults() 方法,下面是它的方法签名。
在这里插入图片描述
参数中的 textView 是我们要操作的 TextView,而 autoSizeTextType,就是我们关心的 Autosizeing 的开关属性了,它接受两个参数。

• AUTO_SIZE_TEXT_TYPE_NONE:关闭自动调整功能。
• AUTO_SIZE_TEXT_TYPE_UNIFORM:开启统一缩放碎片轴和垂直轴。

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



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

2.4 操作 Autosizeing 的粒度

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

这样,在 Autosizeing 生效的时候,它会在这个范围内,按照我们设定的粒度,去动态的调整文字的大小。
想要操作这些属性,动态编码的方式你需要调用 TextViewCompat 的 setAutosizeingTextTypeUniformWithConfiguration() 方法。
在这里插入图片描述
参数很直观,没什么好解释的,一个最小值、一个最大值、变动的粒度、前面设置的尺寸的单位。

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

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



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

在默认情况下,如果你没有设置这三个属性,Autosizeing 会根据当前 TextView 控件的大小,估算出一个最大值和最小值,并且将粒度设置为 1sp 。
在这里插入图片描述
可以看到,它设置的尺寸是跳动的,非常的不可控,我们很难知道下一次缩放,会将 文本 尺寸,设置成多大,所以才需要使用 粒度 的概念来限制它缩放的大小。

例如,现在我们修改上面的例子,将(minSize,maxSize),限制在 (10sp,80sp)之间,粒度(Granularity)设置为 10sp,此时再来看它的效果。
在这里插入图片描述
到这里可以看到,它每次放大或者缩小,粒度都是以 10sp 为基准。
所以,如果你需要使用 Autosizeing ,强烈建议你使用 粒度 来控制它缩放的大小,让它在可控的范围内使用。需要注意的是,这里介绍的三个属性,一定要设置在一个合理的范围内,否则 TextView 会认为这是一个无效的设置,将它忽略掉。

2.5 预设尺寸范围

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

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

如果想要使用预设尺寸,动态编码的方式,你需要操作 TextViewCompat 的 setAutosizeingTextTypeUniformWithPresetSizes() 方法。
在这里插入图片描述
预设尺寸可以接受一个尺寸数组,Autosizeing 就会从我们设定的尺寸数组中,取一个尺寸进行设置。同时你可以为这些尺寸设置一个统一的尺寸单位。
如果想要在 layout-xml 使用属性的形式使用预设尺寸,你首先需要一个 array 的资源,然后通过 autoSizePresetSizes 属性进行设置即可。
array 资源的格式:

10sp12sp20sp40sp100sp

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




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

三、查缺补漏

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

3.1 TextView 必须限定尺寸

如果你想要使用 Autosizeing,就必须对 TextView 这个控件,限定大小,不能使用 wrap_content 来作为限定符。
用官方文档话来说,使用 wrap_content 可能出现不可预料的效果。其实这也非常好理解,如果 TextView 的尺寸不是固定的,那就不存在 TextView 重新计算尺寸的依据了,同比放大 TextView 就可以达到容纳文字的效果了。
我在实际使用过程中会发现,它会阻止放大效果。例如一个 TextView 中使用了 Autosizeing,一直增加文本内容,是可以正常缩小的,但是当你删除文本的时候,它并不会随之放大文字尺寸。
但是不确定还有没有其它的问题,这里建议按照官方文档的建议来操作,限定 TextView 的尺寸。

3.2 Autosizeing 不能作用在 EditText 中

虽然通常作用在 TextView 上的新属性,对于同样用于显示文本的控件,例如:Button、EditText 等,都是同样适用的。
但是 Autosizeing 就是这么特殊,它只对单纯只能显示 文本 的控件有效,例如 Button,而对于 EditText 这种可以输入 文本 的控件,是无效的。
这个,你可以在 AppCompatTextViewAutosizeingHelper 这个类的 supportsAutosizeingText() 方法中找到答案,它是一个兼容类,用于向下兼容 Autosizeing 特性。
在这里插入图片描述
这里可以看到,只要不是 AppCompatEditText 就返回 true,注释也说明了这一点。
暂时没有想到这样设计的原因,可能是因为输入文本的控件,本身长度就是在经常变化的,是一个极端不可控的情况,所以应该为输入的控件,限定一个固定的尺寸。

3.3 预设尺寸不一定都命中

如果想要控制文字的缩放尺寸为限定的范围内,例如使用 粒度 限定它在一个 10sp 的精度下缩放;或者使用预设尺寸,限定一些尺寸,让它只能使用我们预定的一些尺寸。
但是这些,并不是一定的。
例如,我们使用预设尺寸,预设了一组[10sp,20sp,25sp,40sp],这样一组尺寸,其中,可能某个尺寸就永远不会被命中,例如 25sp。
这是因为,Autosizeing 在起作用的时候,会去计算尺寸是否合适,假如到 20sp 之后,再减少文字,这个时候先获取 25sp ,通过计算发现 25sp 也放不下这些文字,就会直接跳到 40sp 这个尺寸上去。
所以,并不是我们设定的尺寸,它就是以线性的方式去获取尺寸。

3.4 和 singleLine 冲突

如果你想在 TextView 中,只显示一行文字,在之前你可以使用 android:singleLine 这个属性,对其标记。而如果你 同事使用 Autosizeing,你会发现 AutoSizeing 就不再生效,它会在末尾显示 “…”。
所幸的是,android:singleLine 已经被标记为废弃,所以本身我们就不建议使用它,如果你想让 TextView 只显示单行文字,可以使用 android:maxLines=“1” 属性,它是可以正常和 Autosizeing 兼容的。

四、使用场景

Autosizeing 说起来非常的简单,但是它能有哪些适用场景呢?简单说说我能想到的一些适用场景吧,大家可以开放思维。

4.1 限定条目的 UI

这个,其实很常见,例如一些选择题的 UI,当你有多个需要选择答案的 UI ,并列的显示出来。如果它们的文字长度是可变的(通常都是可变的),你除了放大某一行的高度之外,现在还可以使用 Autosizeing 来控制它的大小。
例如最近比较火的冲顶大会类 App,就是一个标准的选择题的 UI 布局。
在这里插入图片描述
我们可以在答案文字过多的时候,使用 Autosizeing 将它缩小,就能正好放在这个既定大小的选项 UI 中。

4.2 多语言

Autosizeing 在 App 的多语言适配中,也可以大放异彩。
首先你要考虑到,当你想让 App 适配多语言的话,一个很严重的问题,就是不同的语言,描述同一个词的时候,长度是不一致的。
例如中文下简单的一句:我是 Android 开发者,翻译成不同的语言,长度是不一致的。
• 英语:I am an Android developer
• 阿拉伯语:أنا مطور الروبوت
• 意大利语:Sono uno sviluppatore Android
• 德语:Ich bin ein Android-Entwickler
• 法语:Je suis un développeur Android
在这样的情况下,我们如果有 Autosizeing 就非常的好解决这个问题了。

五、小结

本文到这里,就已经完成了 Autosizeing 的所有细节,从基本使用到注意事项,应该算是解释的很详细了。
不知道你觉得 Autosizeing 在实际使用中,还有什么使用场景?可以在评论中留言,分享给大家!

本文参考来源:
[1]https://www.jianshu.com/p/cf4fddbb99df?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation


推荐阅读
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • Spring框架的核心组件与架构解析 ... [详细]
  • 深入解析 Android 中 EditText 的 getLayoutParams 方法及其代码应用实例 ... [详细]
  • 在Android应用开发中,实现与MySQL数据库的连接是一项重要的技术任务。本文详细介绍了Android连接MySQL数据库的操作流程和技术要点。首先,Android平台提供了SQLiteOpenHelper类作为数据库辅助工具,用于创建或打开数据库。开发者可以通过继承并扩展该类,实现对数据库的初始化和版本管理。此外,文章还探讨了使用第三方库如Retrofit或Volley进行网络请求,以及如何通过JSON格式交换数据,确保与MySQL服务器的高效通信。 ... [详细]
  • 在本文中,我们将为 HelloWorld 项目添加视图组件,以确保控制器返回的视图路径能够正确映射到指定页面。这一步骤将为后续的测试和开发奠定基础。首先,我们将介绍如何配置视图解析器,以便 SpringMVC 能够识别并渲染相应的视图文件。 ... [详细]
  • 今天我开始学习Flutter,并在Android Studio 3.5.3中创建了一个新的Flutter项目。然而,在首次尝试运行时遇到了问题,Gradle任务 `assembleDebug` 执行失败,退出状态码为1。经过初步排查,发现可能是由于依赖项配置不当或Gradle版本不兼容导致的。为了解决这个问题,我计划检查项目的 `build.gradle` 文件,确保所有依赖项和插件版本都符合要求,并尝试更新Gradle版本。此外,还将验证环境变量配置是否正确,以确保开发环境的稳定性。 ... [详细]
  • 本文介绍了如何在iOS平台上使用GLSL着色器将YV12格式的视频帧数据转换为RGB格式,并展示了转换后的图像效果。通过详细的技术实现步骤和代码示例,读者可以轻松掌握这一过程,适用于需要进行视频处理的应用开发。 ... [详细]
  • 在 Vue 应用开发中,页面状态管理和跨页面数据传递是常见需求。本文将详细介绍 Vue Router 提供的两种有效方式,帮助开发者高效地实现页面间的数据交互与状态同步,同时分享一些最佳实践和注意事项。 ... [详细]
  • 在探讨Hibernate框架的高级特性时,缓存机制和懒加载策略是提升数据操作效率的关键要素。缓存策略能够显著减少数据库访问次数,从而提高应用性能,特别是在处理频繁访问的数据时。Hibernate提供了多层次的缓存支持,包括一级缓存和二级缓存,以满足不同场景下的需求。懒加载策略则通过按需加载关联对象,进一步优化了资源利用和响应时间。本文将深入分析这些机制的实现原理及其最佳实践。 ... [详细]
  • 尽管我们尽最大努力,任何软件开发过程中都难免会出现缺陷。为了更有效地提升对支持部门的协助与支撑,本文探讨了多种策略和最佳实践,旨在通过改进沟通、增强培训和支持流程来减少这些缺陷的影响,并提高整体服务质量和客户满意度。 ... [详细]
  • Java解析YAML文件并转换为JSON格式(支持JSON与XML的结构化查询)
    本文探讨了如何利用Java解析YAML文件并将其转换为JSON格式,同时支持JSON和XML的结构化查询。YAML、JSON和XML这三种数据格式通过其名称作为文件扩展名,便于区分和使用。文章详细介绍了这些格式的层次结构和数据表示方法,并重点讨论了在数据传输过程中,XML的特性和优势。此外,还提供了具体的代码示例和实现步骤,帮助开发者高效地进行数据格式转换和查询操作。 ... [详细]
  • 在Android 4.4系统中,通过使用 `Intent` 对象并设置动作 `ACTION_GET_CONTENT` 或 `ACTION_OPEN_DOCUMENT`,可以从相册中选择图片并获取其路径。具体实现时,需要为 `Intent` 添加相应的类别,并处理返回的 Uri 以提取图片的文件路径。此方法适用于需要从用户相册中选择图片的应用场景,能够确保兼容性和用户体验。 ... [详细]
  • 在Ubuntu系统中配置Python环境变量是确保项目顺利运行的关键步骤。本文介绍了如何将Windows上的Django项目迁移到Ubuntu,并解决因虚拟环境导致的模块缺失问题。通过详细的操作指南,帮助读者正确配置虚拟环境,确保所有第三方库都能被正确识别和使用。此外,还提供了一些实用的技巧,如如何检查环境变量配置是否正确,以及如何在多个虚拟环境之间切换。 ... [详细]
  • 在 Kubernetes 中,Pod 的调度通常由集群的自动调度策略决定,这些策略主要关注资源充足性和负载均衡。然而,在某些场景下,用户可能需要更精细地控制 Pod 的调度行为,例如将特定的服务(如 GitLab)部署到特定节点上,以提高性能或满足特定需求。本文深入解析了 Kubernetes 的亲和性调度机制,并探讨了多种优化策略,帮助用户实现更高效、更灵活的资源管理。 ... [详细]
  • 利用树莓派畅享落网电台音乐体验
    最近重新拾起了闲置已久的树莓派,这台小巧的开发板已经沉寂了半年多。上个月闲暇时间较多,我决定将其重新启用。恰逢落网电台进行了改版,回忆起之前在树莓派论坛上看到有人用它来播放豆瓣音乐,便萌生了同样的想法。通过一番调试,终于实现了在树莓派上流畅播放落网电台音乐的功能,带来了全新的音乐享受体验。 ... [详细]
author-avatar
缪宇驰
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有