TextField FocusNode 附加位置變更
EditableText.focusNode 不再附加於 EditableTextState 的 BuildContext。
摘要
#
EditableText.focusNode 現在會附加到
EditableText 下方的一個專用 Focus 元件 (Widget)。
背景說明
#
一個文字輸入欄位元件(例如 TextField)
通常會擁有一個 FocusNode。
當該 FocusNode 是應用程式的主要焦點時,
事件(例如鍵盤按鍵)會被傳送到
FocusNode 所附加的 BuildContext。
FocusNode 也在快捷鍵處理中扮演角色:
Shortcuts 元件會將按鍵序列轉換為 Intent,
並嘗試從附加了 FocusNode 的 BuildContext
開始,往元件樹(Widget tree)根部尋找第一個適合該 Intent 的處理器。
這代表如果一個 Actions 元件(提供不同 Intent 的處理器)
位於樹狀結構下方,當主要焦點的 BuildContext 位於其上方時,
將無法處理任何快捷鍵 Intent。
過去在 EditableText 中,FocusNode 會附加於
EditableTextState 的 BuildContext。
任何在 EditableTextState 中定義的 Actions 元件(這些元件會被插入在 EditableTextState
的 BuildContext 下方)
即使該 EditableText 已獲得焦點,也無法處理快捷鍵,
原因如上所述。
變更說明
#
EditableTextState 現在會建立一個專用的 Focus 元件來
承載 EditableText.focusNode。
這讓 EditableTextState 可以為快捷鍵 Intent 定義處理器。
例如,EditableText 現在有一個處理器,
當按下 DEL 鍵時,會處理 "deleteCharacter" intent。
這項變更不涉及任何公開 API 變更,
但會影響依賴該特定實作細節來判斷
FocusNode 是否與文字輸入欄位相關聯的程式碼庫。
這項變更不會導致建置失敗,但可能會在執行時產生問題, 或導致現有測試失敗。
遷移指南
#
EditableText 元件(Widget)會以 FocusNode 作為參數,
過去這個參數會附加到其 EditableText 的 BuildContext。
如果你依賴於執行時型別檢查來判斷
FocusNode 是否附加於文字輸入欄位或可選取文字欄位,例如:
focusNode.context.widget is EditableText(focusNode.context as StatefulElement).state as EditableTextState
請繼續閱讀,並考慮依照下方遷移步驟操作,以避免破壞。
如果你不確定程式碼庫是否需要遷移,
請搜尋 is EditableText、as EditableText、is EditableTextState
和
as EditableTextState,並確認搜尋結果中是否有對 FocusNode.context 進行型別檢查或型別轉換的情況。
如果有,則需要進行遷移。
為了避免對 FocusNode 關聯的 BuildContext 進行型別檢查或向下轉型,
並根據程式碼庫實際想從該 FocusNode 呼叫的功能,
請從該 BuildContext 觸發一個 Intent。
例如,如果你想將目前獲得焦點的 TextField 文字更新為特定值,請參考下方範例:
遷移前的程式碼:
final Widget? focusedWidget = primaryFocus?.context?.widget;
if (focusedWidget is EditableText) {
widget.controller.text = 'Updated Text';
}
遷移後的程式碼:
final BuildContext? focusedContext = primaryFocus?.context;
if (focusedContext != null) {
Actions.maybeInvoke(focusedContext, ReplaceTextIntent('UpdatedText'));
}
如需 EditableText 元件所支援的 Intent 完整清單,
請參閱 EditableText 元件的文件。
時程
#
合併於版本:2.6.0-12.0.pre
進入穩定版:2.10.0
參考資料
#API 文件:
相關 PR:
Unless stated otherwise, the documentation on this site reflects Flutter 3.44.0. Page last updated on 2026-06-14. View source or report an issue.