使用 maxLengthEnforcement 替换 maxLengthEnforced
摘要
#要控制LengthLimitingTextInputFormatter
中maxLength
的行为,请使用maxLengthEnforcement
代替现已弃用的maxLengthEnforced
。
上下文
#maxLengthEnforced
参数用于确定当输入值达到maxLength
限制时,文本字段是否应该截断输入值,或者(对于TextField
和TextFormField
)是否应该在字符计数中显示警告消息,当用户输入的长度超过maxLength
时。
但是,要输入 CJK 字符,一些输入法需要用户在文本字段中输入一系列拉丁字符,然后将此序列转换为所需的 CJK 字符(称为文本合成)。拉丁字符序列通常比生成的 CJK 字符更长,因此在文本字段上设置硬性最大字符限制可能意味着用户无法正常完成文本合成,因为maxLength
字符限制。
文本合成也被一些输入法用来表示突出显示的合成区域内的文本正在被积极编辑,即使在输入拉丁字符时也是如此。例如,Android 上的 Gboard 英语键盘(与 Android 上许多其他输入法一样)将当前单词放在合成区域中。
为了改善这些场景下的输入体验,引入了一个新的三态枚举MaxLengthEnforcement
。它的值描述了在应用LengthLimitingTextInputFormatter
时处理活动合成区域的支持策略。一个使用此枚举的新maxLengthEnforcement
参数已添加到文本字段中,以替换布尔型maxLengthEnforced
参数。使用新的枚举参数,开发人员可以根据文本字段期望的内容类型选择不同的策略。
有关更多信息,请参阅maxLength
和MaxLengthEnforcement
的文档。
maxLengthEnforcement
参数的默认值是从应用程序的TargetPlatform
推断出来的,以符合平台的约定。
更改说明
#- 添加了一个使用新枚举类型
MaxLengthEnforcement
的maxLengthEnforcement
参数,以替换现已弃用的布尔型maxLengthEnforced
参数,该参数位于TextField
、TextFormField
、CupertinoTextField
和LengthLimitingTextInputFormatter
类上。
迁移指南
#建议使用当前平台的默认行为,因为这将是用户最熟悉的行为。
maxLengthEnforcement
的默认值
#- Android、Windows:
MaxLengthEnforcement.enforced
。这些平台的原生行为被强制执行。无论用户是否使用合成输入,输入值都将被截断。 - iOS、macOS:
MaxLengthEnforcement.truncateAfterCompositionEnds
。这些平台没有“最大长度”功能,因此要求开发人员自己实现此行为。在这些平台上似乎没有形成标准约定。我们选择允许合成超过最大长度,以避免破坏 CJK 输入。 - Web 和 Linux:
MaxLengthEnforcement.truncateAfterCompositionEnds
。虽然这些平台上没有标准(并且许多实现具有冲突的行为),但常见的约定似乎是默认情况下允许合成超过最大长度。 - Fuchsia:
MaxLengthEnforcement.truncateAfterCompositionEnds
。此平台上还没有平台约定,因此我们选择默认为最不可能导致数据丢失的约定。
始终强制执行限制
#要强制执行始终在值达到限制时截断值的限制(例如,在输入验证码时),请在可编辑文本字段中使用MaxLengthEnforcement.enforced
。
当与依赖文本合成的输入法一起使用时,此选项可能会提供不太理想的用户体验。如果文本字段期望包含可能包含 CJK 字符的任意用户输入,请考虑使用truncateAfterCompositionEnds
选项。有关更多信息,请参阅上下文部分。
迁移前的代码
TextField(maxLength: 6)
或
TextField(
maxLength: 6,
maxLengthEnforced: true,
)
迁移后的代码
TextField(
maxLength: 6,
maxLengthEnforcement: MaxLengthEnforcement.enforced,
)
不强制执行限制
#要在TextField
中显示最大长度错误,但不在超过限制时截断,请使用MaxLengthEnforcement.none
代替maxLengthEnforced: false
。
迁移前的代码
TextField(
maxLength: 6,
maxLengthEnforced: false,
)
迁移后的代码
TextField(
maxLength: 6,
maxLengthEnforcement: MaxLengthEnforcement.none,
)
对于无法显示错误消息的CupertinoTextField
,只需不要设置maxLength
值即可。
迁移前的代码
CupertinoTextField(
maxLength: 6,
maxLengthEnforced: false,
)
迁移后的代码
CupertinoTextField()
强制执行限制,但文本合成时除外
#要避免在用户使用合成输入文本时截断文本,请指定MaxLengthEnforcement.truncateAfterCompositionEnds
。此行为允许使用合成区域大于结果文本的输入法(例如,中文、日语和韩语 (CJK) 文本很常见),在编辑完成之前暂时忽略限制。
Android 上的 Gboard 英语键盘(以及许多其他 Android 输入法)为正在输入的单词创建一个合成区域。当在truncateAfterCompositionEnds
文本字段中使用时,用户不会在maxLength
限制处立即被阻止。如果您确信文本字段不会与使用暂时较长的合成区域(例如 CJK 文本)的输入法一起使用,请考虑enforced
选项。
实现代码
TextField(
maxLength: 6,
maxLengthEnforcement: MaxLengthEnforcement.truncateAfterCompositionEnds, // Temporarily lifts the limit.
)
注意不要假设输入不会使用合成区域
#当针对特定区域设置时,很容易假设所有用户都将对来自该区域设置的输入感到满意。例如,针对英语社区的论坛软件可能会被认为只需要处理英文文本。但是,这种假设通常是不正确的。例如,也许英语论坛参与者希望讨论日本动画或越南烹饪。也许其中一位参与者是韩国人,并且更喜欢用他们的母语象形文字表达他们的名字。因此,自由格式字段应很少使用enforced
值,而应尽可能使用truncateAfterCompositionEnds
值。
时间线
#包含版本:v1.26.0-1.0.pre
稳定版本:2.0.0
参考文献
#设计文档
API 文档
相关问题
相关 PR
除非另有说明,否则本网站上的文档反映了 Flutter 的最新稳定版本。页面上次更新于 2024-04-04。 查看源代码 或 报告问题。