跳至主要內容

使用 maxLengthEnforcement 取代 maxLengthEnforced

摘要

#

為了控制 LengthLimitingTextInputFormattermaxLength 的行為,請使用 maxLengthEnforcement 取代現在已棄用的 maxLengthEnforced

背景

#

maxLengthEnforced 參數用於決定文字欄位在達到 maxLength 限制時,是否應截斷輸入值,或者(對於 TextFieldTextFormField)當使用者輸入的長度超過 maxLength 時,是否應在字元計數中顯示警告訊息。

然而,為了輸入 CJK 字元,某些輸入法需要使用者在文字欄位中輸入一連串的拉丁字元,然後將此序列轉換為所需的 CJK 字元(稱為文字組合)。拉丁序列通常比產生的 CJK 字元長,因此對文字欄位設定硬性的最大字元限制可能意味著使用者由於 maxLength 字元限制而無法正常完成文字組合。

某些輸入法也使用文字組合來指示突出顯示的組合區域內的文字正在被積極編輯,即使輸入的是拉丁字元。例如,Android 上的 Gboard 英文鍵盤(與 Android 上的許多其他輸入法一樣)會將當前單字放入組合區域。

為了改善這些情境下的輸入體驗,引入了一個新的三態枚舉 MaxLengthEnforcement。它的值描述了在應用 LengthLimitingTextInputFormatter 時處理活動組合區域的支援策略。在文字欄位中新增了一個使用此枚舉的新 maxLengthEnforcement 參數,以取代布林值 maxLengthEnforced 參數。透過新的枚舉參數,開發人員可以根據文字欄位預期的內容類型選擇不同的策略。

如需更多資訊,請參閱 maxLengthMaxLengthEnforcement 的文件。

maxLengthEnforcement 參數的預設值是從應用程式的 TargetPlatform 推斷出來的,以符合平台的慣例。

變更說明

#
  • 新增了使用新的枚舉類型 MaxLengthEnforcementmaxLengthEnforcement 參數,以取代 TextFieldTextFormFieldCupertinoTextFieldLengthLimitingTextInputFormatter 類別中現在已棄用的布林值 maxLengthEnforced 參數。

遷移指南

#

建議使用目前平台的預設行為,因為這將是使用者最熟悉的行為。

maxLengthEnforcement 的預設值

#
  • Android、Windows: MaxLengthEnforcement.enforced。這些平台的原生行為會被強制執行。無論使用者是否使用組合輸入,輸入的值都會被截斷。
  • iOS、macOS: MaxLengthEnforcement.truncateAfterCompositionEnds。這些平台沒有「最大長度」功能,因此需要開發人員自己實作此行為。這些平台上似乎沒有形成標準慣例。我們選擇允許組合超過最大長度,以避免中斷 CJK 輸入。
  • Web 和 Linux: MaxLengthEnforcement.truncateAfterCompositionEnds。雖然這些平台上沒有標準(並且存在許多行為衝突的實作),但常見的慣例似乎是預設允許組合超過最大長度。
  • Fuchsia: MaxLengthEnforcement.truncateAfterCompositionEnds。此平台上尚未有平台慣例,因此我們選擇預設為最不可能導致資料遺失的慣例。

強制總是限制長度

#

為了強制限制長度,在達到限制時始終截斷值(例如,輸入驗證碼時),請在可編輯的文字欄位中使用 MaxLengthEnforcement.enforced

當與依賴文字組合的輸入法一起使用時,此選項可能會提供次佳的使用者體驗。當文字欄位預期包含可能包含 CJK 字元的任意使用者輸入時,請考慮使用 truncateAfterCompositionEnds 選項。有關更多資訊,請參閱背景部分。

遷移前的程式碼

dart
TextField(maxLength: 6)

dart
TextField(
  maxLength: 6,
  maxLengthEnforced: true,
)

遷移後的程式碼

dart
TextField(
  maxLength: 6,
  maxLengthEnforcement: MaxLengthEnforcement.enforced,
)

不強制限制長度

#

為了在 TextField 中顯示最大長度錯誤,但當超過限制時截斷,請使用 MaxLengthEnforcement.none 取代 maxLengthEnforced: false

遷移前的程式碼

dart
TextField(
  maxLength: 6,
  maxLengthEnforced: false,
)

遷移後的程式碼

dart
TextField(
  maxLength: 6,
  maxLengthEnforcement: MaxLengthEnforcement.none,
)

對於無法顯示錯誤訊息的 CupertinoTextField,請不要設定 maxLength 值。

遷移前的程式碼

dart
CupertinoTextField(
  maxLength: 6,
  maxLengthEnforced: false,
)

遷移後的程式碼

dart
CupertinoTextField()

強制限制長度,但不包含文字組合

#

為了避免在使用組合輸入文字時截斷文字,請指定 MaxLengthEnforcement.truncateAfterCompositionEnds。這種行為允許使用大於結果文字的組合區域的輸入法,例如中文、日文和韓文 (CJK) 文字常見的情況,暫時忽略限制,直到編輯完成。

Android 上的 Gboard 英文鍵盤(以及許多其他 Android 輸入法)會為正在輸入的單字建立組合區域。當在 truncateAfterCompositionEnds 文字欄位中使用時,使用者不會立即在 maxLength 限制處停止。如果您確信文字欄位不會與使用臨時長組合區域(例如 CJK 文字)的輸入法一起使用,請考慮使用 enforced 選項。

實作的程式碼

dart
TextField(
  maxLength: 6,
  maxLengthEnforcement: MaxLengthEnforcement.truncateAfterCompositionEnds, // Temporarily lifts the limit.
)

小心假設輸入不會使用組合區域

#

當鎖定特定地區時,很容易假設所有使用者都會對該地區的輸入感到滿意。例如,針對英文社群的論壇軟體可能會被認為只需要處理英文文字。但是,這種假設通常是不正確的。例如,也許英文論壇參與者會想要討論日本動漫或越南烹飪。也許其中一位參與者是韓國人,並且喜歡用他們的母語文字表達他們的名字。因此,自由格式欄位應很少使用 enforced 值,並且應盡可能優先使用 truncateAfterCompositionEnds 值。

時程

#

發佈版本: v1.26.0-1.0.pre
穩定版本: 2.0.0

參考資料

#

設計文件

API 文件

相關議題

相關 PR

  • PR 63754: 修正設定組合和 maxLength 時 TextField 崩潰的問題
  • PR 68086: 引入 MaxLengthEnforcement