Android 13 新的换行策略和针对日文的优化

简介: Android 13 新的换行策略和针对日文的优化

前言

Android 13 向 TextView 控件引入了新的换行策略,同时针对日文提供了换行优化。系统将依据开发者指定的换行策略、日文短语换行策略进行文本换行。这将促使文本内容不再杂乱无章、更加具有层次、便于阅读。


下面我们从 API、实战、适配办法等多个角度来快速学习一下这个新特性。

换行策略 lineBreakStyle

Indicates the line break strategies can be used when calculating the text wrapping.

1672189656496.png事实上来自于 CSS 的 line-break 属性,主要是针对 CJK 语言,也就是中日韩 3 种语言提供的换行规则。


Android 提供的属性和 CSS 的略有差异,但 loose、normal 和 strict 这三个属性进行了保留,后面将通过 DEMO 进行属性表现上的差异说明。

短语换行策略 lineBreakWordStyle

Specify the phrase-based line break can be used when calculating the text wrapping.

Constant Value Description
none 0 No line break word style specific.
phrase 1 Specify the phrase based breaking.

默认不生效,设置为 phrase 则生效。

动态设置

除了上述属性以外,TextView 理所应当地提供了 setLineBreakConfig() 来动态更新换行策略。

public void setLineBreakConfig (LineBreakConfig lineBreakConfig)
Parameters
lineBreakConfig LineBreakConfig: the line break config for text wrapping. This value cannot be null.

LineBreakConfig

Android 13 新引入的承载换行策略的配置类,提供了上述属性相对应的常量以及返回策略所必要的 get 方法。

1672189691810.png

public int getLineBreakWordStyle ()
public int getLineBreakStyle ()

实战

我们在中文和日语两种语言环境下提供一些测试文本,探究在不同换行策略下文本的实际表现。

换行策略的效果

换行策略的表现跟 CJK 语言里一些特定符号有关系,普通的文本表现上区别不是很明显。所以我们预设特别的一段文本在不同的显示宽度下的表现,来简要展现下不同规则下的差异。

  • 测试文本:【这里有个弯弯符号〜加“引号”然后最后有个问号?后面是普普通通一句话。】
class MainActivity : AppCompatActivity() {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        LineBreakConfig().run {
            lineBreakStyle = LINE_BREAK_STYLE_NONE
            lineBreakWordStyle = LINE_BREAK_WORD_STYLE_NONE
            breakTestTextViewCSS.lineBreakConfig = this
            breakTestTextViewCSS_2.lineBreakConfig = this
        }
    }
    fun onButtonClick(view: View) {
        when (view.id) {
            R.id.break_btn -> breakTestTextViewCSS.lineBreakConfig.apply {
                lineBreakStyle =
                    when (breakTestTextViewCSS.lineBreakConfig.lineBreakStyle) {
                        LINE_BREAK_STYLE_NONE -> LINE_BREAK_STYLE_LOOSE
                        LINE_BREAK_STYLE_LOOSE -> LINE_BREAK_STYLE_NORMAL
                        LINE_BREAK_STYLE_NORMAL -> LINE_BREAK_STYLE_STRICT
                        LINE_BREAK_STYLE_STRICT -> LINE_BREAK_STYLE_NONE
                        else -> LINE_BREAK_STYLE_NONE
                    }
                breakTestTextViewCSS.lineBreakConfig = this
                breakTestTextViewCSS_2.lineBreakConfig = this
            }
        }
    }
}

1672189750160.png

1672189764127.png

可以看到


none 和 strict 策略下,符号〜的前方必须有文字,不能单独作为行首,而 loose 和 normal 策略则无此限制

另外按照 css 的说明,只有在 strict 策略下,符号〜才允许作为行尾进行换行。但在 Android 13 上的测试发现,无论哪种策略都允许符号〜作为行尾换行,可能跟宽度配置有些关系

loose 策略下,符号? 允许在行首单独出现,而其他模式不允许,前面必须要有其他文字才可换行

其他更详细的换行差异可以参考 w3c 的 css 换行说明,并进行实际的尝试。

短语换行策略效果

短语换行策略指的是日文情况下句尾遇到短语、助词如何换行,是固定换行还是短语整体另起一行。


测试文本:【常に最新、最高のモバイル。Androidを開発した同じチームから。】

起初觉得只要展示的是日文都会应用该策略,便没有注意 App 当前语言是中文,以外发现画面中的日文文本没有按照预期进行换行。

class MainActivity : AppCompatActivity() {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        LineBreakConfig().run {
            lineBreakStyle = LINE_BREAK_STYLE_NONE
            lineBreakWordStyle = LINE_BREAK_WORD_STYLE_NONE
            breakTestTextView.lineBreakConfig = this
        }
    }
    fun onButtonClick(view: View) {
        when (view.id) {
            R.id.phrase_break_btn -> breakTestTextView.lineBreakConfig.apply {
                lineBreakWordStyle =
                    if (breakTestTextView.lineBreakConfig.lineBreakWordStyle == LINE_BREAK_WORD_STYLE_PHRASE)
                        LINE_BREAK_WORD_STYLE_NONE
                    else LINE_BREAK_WORD_STYLE_PHRASE
                breakTestTextView.lineBreakConfig = this
            }
        }
    }
}

2Zmh5D.gif

需要当前语言是日语

当 App 语言切换为日语场景后,短语换行策略才会生效。

2Zmh5D.gif

后来想想也是合理的,非日语的场景下用户能读懂日语的概率很低,在意换行的可能性更加小。系统没有必要耗费精力去判断文字是否是日文和进行换行。

而当 App 语言是日语的话,用户极高概率能读懂并且在乎短语换行的合理和连贯性,所以只在日语情况下生效则显得非常合理。

性能测试

可能有开发者会担心开启了短语换行是否造成性能的负担。通过覆写 TextView 并在 onMeasure() 里加入耗时统计,测定了展示 10000 个杂乱的日文文本下,短语换行策略开启与否的时间表现。

  • 设备版本是:Pixel 4 XL 13 Beta 1

1672189831456.png

可以看到即便是长度达到 10000 的超长文本,开启了短语换行策略的性能表现依旧没有什么明显劣化。在实际开发当中,显示长度达到 10000 的 TextView 文本的情况实属罕见。


我们可以断定短语换行策略对于文本显示的性能影响可以忽略不计。


另外,需要说明的是 TargetSDKVersion 不用升级到 33,所有的换行特性均可生效。

原理

目前只公开了 preview-1 的代码,搜索了一下没有发现 LineBreakConfig 相关的实现,后续等 Beta 版代码公开之后再作研究。


https://android.googlesource.com/platform/frameworks/base/+/refs/heads/android-t-preview-1/

适配

  1. 思考下 App 是否需要开启新的换行策略
  2. 如果 App 支持日语的话,建议开启短语换行策略,优化日文的阅读体验
  3. 确定开启上述新策略的话,需要注意如下两点影响:
  • 画面布局是否发生错乱、切掉
  • 与已有的日文手动换行 \n 是否会发生冲突

总结

本新特性非常简单直白,我们可以使用换行策略去指定和 css 一致的换行规则,也可以针对日语指定换行友好的短语策略。


和 View 的一般用法无差,均有属性配置和动态更新两种方案。


另外,留意如下几点:


该新特性不要求升级 TargetSDKVersion

指定换行策略的话需要留意布局是否发生错乱、切掉的问题

指定短语换行策略的话需要检查是否会和已有的手动换行发生冲突

当前语言是日语环境下,短语换行策略才可以生效

短语换行策略对于性能的影响可以忽略不计

参考资料

https://developer.android.google.cn/reference/android/widget/TextView

https://developer.android.google.cn/reference/android/graphics/text/LineBreakConfig

https://www.w3.org/TR/css-text-3/#line-break-property

https://www.zhangxinxu.com/wordpress/2021/02/css-line-break/


相关文章
|
14天前
|
缓存 监控 Android开发
探索iOS与安卓开发中的性能优化策略
在移动应用开发的竞技场上,iOS和安卓这两大操作系统不断推动着技术的边界。性能优化,作为提升用户体验的关键因素,已成为开发者们关注的焦点。本文将深入探讨两大平台上的性能优化实践,揭示如何通过工具、技术和策略来提升应用的响应速度和流畅度,同时考虑到电池寿命和内存管理等关键指标。
|
1月前
|
Java Android开发
Android面试题经典之Glide取消加载以及线程池优化
Glide通过生命周期管理在`onStop`时暂停请求,`onDestroy`时取消请求,减少资源浪费。在`EngineJob`和`DecodeJob`中使用`cancel`方法标记任务并中断数据获取。当网络请求被取消时,`HttpUrlFetcher`的`cancel`方法设置标志,之后的数据获取会返回`null`,中断加载流程。Glide还使用定制的线程池,如AnimationExecutor、diskCacheExecutor、sourceExecutor和newUnlimitedSourceExecutor,其中某些禁止网络访问,并根据CPU核心数动态调整线程数。
77 2
|
7天前
|
调度 Android开发 开发者
【颠覆传统!】Kotlin协程魔法:解锁Android应用极速体验,带你领略多线程优化的无限魅力!
【8月更文挑战第12天】多线程对现代Android应用至关重要,能显著提升性能与体验。本文探讨Kotlin中的高效多线程实践。首先,理解主线程(UI线程)的角色,避免阻塞它。Kotlin协程作为轻量级线程,简化异步编程。示例展示了如何使用`kotlinx.coroutines`库创建协程,执行后台任务而不影响UI。此外,通过协程与Retrofit结合,实现了网络数据的异步加载,并安全地更新UI。协程不仅提高代码可读性,还能确保程序高效运行,不阻塞主线程,是构建高性能Android应用的关键。
26 4
|
12天前
|
缓存 算法 数据库
安卓应用性能优化:一场颠覆平凡的极限挑战,拯救卡顿的惊世之战!
【8月更文挑战第7天】《安卓应用性能优化实战》
25 4
|
2天前
|
编译器 Android开发 开发者
Android经典实战之Kotlin 2.0 迁移指南:全方位优化与新特性解析
本文首发于公众号“AntDream”。Kotlin 2.0 已经到来,带来了 K2 编译器、多平台项目支持、智能转换等重大改进。本文提供全面迁移指南,涵盖编译器升级、多平台配置、Jetpack Compose 整合、性能优化等多个方面,帮助开发者顺利过渡到 Kotlin 2.0,开启高效开发新时代。
5 0
|
28天前
|
IDE API Android开发
安卓与iOS开发环境的差异及适配策略
在移动应用开发的广阔舞台上,Android和iOS两大操作系统各据一方,各自拥有独特的开发环境和工具集。本文旨在深入探讨这两个平台在开发环境上的关键差异,并提供有效的适配策略,帮助开发者优化跨平台开发流程。通过比较Android的Java/Kotlin和iOS的Swift/Objective-C语言特性、IDE的选择、以及API和系统服务的访问方式,本文揭示了两个操作系统在开发实践中的主要分歧点,并提出了一套实用的适配方法,以期为移动开发者提供指导和启示。
|
29天前
|
缓存 数据库 Android开发
安卓应用开发中的性能优化策略
【7月更文挑战第21天】在移动设备上,性能问题直接影响用户体验。本文将探讨在安卓应用开发过程中,开发者可以采用的多种性能优化方法。我们将从代码层面、资源管理、网络通信、UI渲染等方面入手,深入分析如何有效减少应用的内存占用和提升响应速度。此外,文章还将介绍一些实用的工具和平台,帮助开发者检测和解决性能瓶颈。
43 1
|
2月前
|
ARouter IDE 开发工具
Android面试题之App的启动流程和启动速度优化
App启动流程概括: 当用户点击App图标,Launcher通过Binder IPC请求system_server启动Activity。system_server指示Zygote fork新进程,接着App进程向system_server申请启动Activity。经过Binder通信,Activity创建并回调生命周期方法。启动状态分为冷启动、温启动和热启动,其中冷启动耗时最长。优化技巧包括异步初始化、避免主线程I/O、类加载优化和简化布局。
50 3
Android面试题之App的启动流程和启动速度优化
|
1月前
|
算法 Java API
Android性能优化面试题经典之ANR的分析和优化
Android ANR发生于应用无法在限定时间内响应用户输入或完成操作。主要条件包括:输入超时(5秒)、广播超时(前台10秒/后台60秒)、服务超时及ContentProvider超时。常见原因有网络、数据库、文件操作、计算任务、UI渲染、锁等待、ContentProvider和BroadcastReceiver的不当使用。分析ANR可借助logcat和traces.txt。主线程执行生命周期回调、Service、BroadcastReceiver等,避免主线程耗时操作
34 3
|
2月前
|
缓存 JSON 网络协议
Android面试题:App性能优化之电量优化和网络优化
这篇文章讨论了Android应用的电量和网络优化。电量优化涉及Doze和Standby模式,其中应用可能需要通过用户白名单或电池广播来适应限制。Battery Historian和Android Studio的Energy Profile是电量分析工具。建议减少不必要的操作,延迟非关键任务,合并网络请求。网络优化包括HTTPDNS减少DNS解析延迟,Keep-Alive复用连接,HTTP/2实现多路复用,以及使用protobuf和gzip压缩数据。其他策略如使用WebP图像格式,按网络质量提供不同分辨率的图片,以及启用HTTP缓存也是有效手段。
55 9