聊技术在android中实现自适应文本大小显示(代码片段)

萧文翰 萧文翰     2022-11-03     256

关键词:

本周的聊技术话题和大家说说如何在Android中实现自适应文本大小显示。
想象一下,在布局中,通常显示文本的区域大小是固定的,但是文本长度并不总是固定的。比如列表中的文章标题、界面下方的按钮文本等等。
为了尽可能让这些文字可见,传统的做法是通过文本长度设置文本大小,或者通过android:ellipsize属性设置文本省略方式等等。
实际上,从Android O开始,Android API引入了自适应文本大小的简易实现。它不仅可以用于TextView,对于Button等具有文本显示的控件同样适用。通过androidX,还可以适配到低版本的Android中。
下面,我们以TextView为例,来看看如何使用它们吧。

开启自适应显示模式

我们以Empty Activity方式创建一个新的工程,其中默认包含了只显示Hello World!文本的TextView控件,我们为其加上id,并修改尺寸和默认文本。为了兼容低版本的Android设备,使用androidX中提供的的AppCompatTextView替代TextView。
完整的布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/activity_main_tv"
        android:layout_width="100dp"
        android:layout_height="20dp"
        android:text="abcdefghijklmno"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

然后,将程序运行起来,可以看到,文字的显示仅到字母“n”处就停止了,”o”并没有显示。显而易见,这是因为文本框的大小限制了文字的显示。


下面,我们来到MainActivity代码,调用setAutoSizeTextTypeWithDefaults();方法,开启自适应缩放。

private AppCompatTextView demoTv;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    demoTv = findViewById(R.id.activity_main_tv);
    demoTv.setAutoSizeTextTypeWithDefaults(TextView.AUTO_SIZE_TEXT_TYPE_UNIFORM);

重新运行后,可以看到文本被完整地显示出来了:


对于setAutoSizeTextTypeWithDefaults();方法,我们可以传入的参数值通常有两个,分别是TextView.AUTO_SIZE_TEXT_TYPE_UNIFORM和TextView.AUTO_SIZE_TEXT_TYPE_NONE。对应开启自适应文本大小与否。

自定义文本缩放方式

下面,我们修改TextView的文本,继续追加:

android:text="abcdefghijklmnopqrstuvwxyz"

再次运行App,我们发现:无论自适应模式开关与否,都无法完整地显示所有文本。这时候,我们就要对文本大小的自动缩放进行自定义了。

设定缩放配置

首先要介绍一种通过设定缩放配置实现自定义缩放的方法。我们先来看代码:

demoTv.setAutoSizeTextTypeUniformWithConfiguration(4,15,2, TypedValue.COMPLEX_UNIT_SP);

如上代码所示,setAutoSizeTextTypeUniformWithConfiguration();是实现此种缩放方式的关键,它由4个参数构成。

  • 4:表示文本缩放的最小值;
  • 20:表示文本缩放的最大值;
  • 2:表示文本缩放的尝试步长;
  • TypedValue.COMPLEX_UNIT_SP:指定前三个参数使用SP作为单位。

可以这样理解,当文本无法显示完全时,系统将以步长为单位递减文本大小设定值,直到文本完全显示,或者尝试值小于给定的文本缩放的最小值。
重新运行App,可以看到文本已经被完整地显示出来了。

定义预设值

自定义缩放的第二种方式是通过定义预设值实现。我们还是直接看代码:

demoTv.setAutoSizeTextTypeUniformWithPresetSizes(new int[]9, 11, 13, 15, TypedValue.COMPLEX_UNIT_SP);

通过setAutoSizeTextTypeUniformWithPresetSizes();方法定义预设值,需要两个参数,第一个是预设值的具体数值;第二个则是预设值的单位。
以上面的代码为例,在进行文字缩放时,文字大小只能从9SP,11SP,13SP和15SP这4个值中取。遗憾的是,即使取到9SP,文字依然无法完全显示:


仔细观察图中第二行文字,可以发现文字的下面由于高度不够,被截去了一段。

小结

综上,我们总共讲解了三种文本自动缩放的方式。这三种方式无所谓孰优孰劣,只是使用场景的区别。有了它们,我们无需自己定义不同的文字大小,更无需自己实现文字的自适应缩放了。
最后,特别需要说明:一定要在xml以及java代码中使用AppCompatTextView控件,除非你的App只支持Android O及以上版本。
这次的分享就到这里,希望上述内容对你有所帮助。

如何在android中实现自定义可折叠工具栏?

】如何在android中实现自定义可折叠工具栏?【英文标题】:HowtoimplementCustomCollapsableToolbarinandroid?【发布时间】:2015-11-2212:08:36【问题描述】:使用thistutorial实现灵活空间模式(带有折叠工具栏的模式)。我正在尝试实现与Lollipop... 查看详情

在 Android 中实现自定义 ListView

】在Android中实现自定义ListView【英文标题】:ImplementacustomListViewinAndroid【发布时间】:2016-10-2802:16:18【问题描述】:我在我的MainActivity中创建了一个listView,并为行布局创建了另一个布局文件,如下所示:问题是,我该如何实现... 查看详情

在 Freemarker 中实现自定义 Escaper

】在Freemarker中实现自定义Escaper【英文标题】:ImplementaCustomEscaperinFreemarker【发布时间】:2010-11-0920:21:59【问题描述】:Freemarker可以使用以下方式进行文本转义:<#escapexasx?html>Foo:$someValBar:$someOtherVal</#escape>xml、xhtml和html... 查看详情

在 Gradle Android 中实现自定义库时未解析类

】在GradleAndroid中实现自定义库时未解析类【英文标题】:ClassnotresolvedwhenimplementingcustomlibraryinGradleAndroid【发布时间】:2022-01-0201:32:22【问题描述】:我创建了一个android库并在Jitpack中发布。目前,我的构建在Jitpack中取得了成功... 查看详情

在spring boot中实现自定义错误

】在springboot中实现自定义错误【英文标题】:Implementthecustomerrorinspringboot【发布时间】:2019-04-0702:58:26【问题描述】:我想页面。在应用程序中,id是主键,所以当没有给出id时,它会将请求传输到页面,但我希望应用程序在索... 查看详情

android中实现自定义xmpp消息包收发

       在Android平台实现XMPP即时通讯主要是使用asmack这个包,asmack是XMPP协议的实现。但是asmack只能帮助我们实现一些基本消息包的收发,如果需要实现特定的自定义消息包收发需要我们自己处理。一、asm... 查看详情

android中实现自定义的拍照应用

可以参考:http://www.android-doc.com/guide/topics/media/camera.html一、添加相应的权限<uses-permissionandroid:name="android.permission.CAMERA"/><uses-featureandroid:name="android.hardware.camera"/><!- 查看详情

如何在 keras 中实现自定义指标?

】如何在keras中实现自定义指标?【英文标题】:howtoimplementcustommetricinkeras?【发布时间】:2016-10-0601:13:54【问题描述】:我得到这个错误:sum()得到了一个意外的关键字参数\'out\'当我运行这段代码时:importpandasaspd,numpyasnpimportkera... 查看详情

如何在 iPhone 中实现自定义相机功能? [关闭]

】如何在iPhone中实现自定义相机功能?[关闭]【英文标题】:HowtoimplementcustomcamerafunctionalityiniPhone?[closed]【发布时间】:2011-08-1605:07:13【问题描述】:我想开发一种功能,以便在iPhone应用程序中实现自定义相机功能,所以请给我... 查看详情

在 MembershipProvider 中实现自定义“ValidateUser”

】在MembershipProvider中实现自定义“ValidateUser”【英文标题】:Implementcustom"ValidateUser"inMembershipProvider【发布时间】:2011-03-2510:32:38【问题描述】:我正在实现一个自定义MembershipProvider,我正在尝试使用ValidateUser方法来验证... 查看详情

在具有条件的 keras 中实现自定义损失函数

】在具有条件的keras中实现自定义损失函数【英文标题】:Implementingcustomlossfunctioninkeraswithcondition【发布时间】:2018-12-0813:49:59【问题描述】:我需要一些有关keras损失函数的帮助。我一直在使用Tensorflow后端在keras上实现自定义损... 查看详情

在 kvm 中实现自定义超级调用

】在kvm中实现自定义超级调用【英文标题】:Implementingacustomhypercallinkvm【发布时间】:2016-02-0900:28:27【问题描述】:我对虚拟化非常陌生,最近我一直在尝试熟悉VMM的操作方式以及如何进行超级调用。谈到我打算在安装在我的Ubu... 查看详情

如何在 Spark SQL(PySpark) 中实现自增

】如何在SparkSQL(PySpark)中实现自增【英文标题】:HowtoimplementautoincrementinsparkSQL(PySpark)【发布时间】:2016-10-2504:20:43【问题描述】:我需要在我的sparksql表中实现一个自动增量列,我该怎么做。请指导我。我正在使用pyspark2.0谢谢卡... 查看详情

如何在canvas中实现自定义路径动画(代码片段)

在最近的项目中笔者需要做一个新需求:在canvas中实现自定义的路径动画。这里所谓的自定义路径不单单包括一条直线,也许是多条直线的运动组合,甚至还包含了贝塞尔曲线,因此,这个动画也许是下面这个样子的:那么如何... 查看详情

如何在黄瓜中实现自定义监听器?

】如何在黄瓜中实现自定义监听器?【英文标题】:Howtoimplementcustomlistenersincucumber?【发布时间】:2021-12-2214:55:47【问题描述】:如何在cucumber中实现客户监听?哪个可以记录到控制台/报告失败方法的发生?使用黄瓜4.0注意:钩... 查看详情

如何在 Alamofire 中实现自签名证书?

】如何在Alamofire中实现自签名证书?【英文标题】:HowtoimplementselfsignedcertificatesinAlamofire?【发布时间】:2015-03-0500:56:19【问题描述】:我编写了一个基于swift的应用程序,带有自签名证书服务器通信。作为一个网络库,我想使用A... 查看详情

在 SDK 中实现自定义取消按钮

】在SDK中实现自定义取消按钮【英文标题】:ImplementcustomCancelButtoninaSDK【发布时间】:2015-11-0917:24:08【问题描述】:我想用paysbuySDK实现支付功能....问题是它没有任何cancel选项,以便用户可以在支付成功后取消关闭操作。默认情... 查看详情

为啥不推荐使用 JScript 在 WiX 中实现自定义操作?

】为啥不推荐使用JScript在WiX中实现自定义操作?【英文标题】:WhyisusingJScriptforimplementingcustomactionsinWiXnotrecommended?为什么不推荐使用JScript在WiX中实现自定义操作?【发布时间】:2013-07-1008:19:33【问题描述】:在浏览有关WiX的文... 查看详情