焦點與文字欄位
焦點在文字欄位中是如何運作的。
當一個文字欄位被選中並接收輸入時,即表示它擁有了“焦點”。通常情況下,使用者透過點選來切換文字欄位的焦點,而開發者則透過本指南中描述的工具以程式設計方式切換焦點。
管理焦點是構建具有直觀互動流程表單的基本工具。例如,假設你有一個帶有文字欄位的搜尋介面。當用戶導航到該搜尋介面時,你可以將焦點設定在該搜尋詞文字欄位上。這樣,使用者無需手動點選文字欄位,即可在介面可見時立即開始輸入。
在本指南中,你將學習如何在文字欄位可見時立即為其分配焦點,以及如何在點選按鈕時為文字欄位分配焦點。
在文字欄位可見時立即獲取焦點
#若要使文字欄位在可見時立即獲得焦點,請使用 autofocus 屬性。
TextField(
autofocus: true,
);
有關處理輸入和建立文字欄位的更多資訊,請參閱 Cookbook 中的 表單 (Forms) 部分。
在點選按鈕時獲取文字欄位焦點
#有時你可能不需要立即將焦點切換到某個特定的文字欄位,而是在稍後的時間點進行操作。在實際開發中,你可能還需要在 API 呼叫或驗證錯誤發生時,將焦點賦予特定的文字欄位。在此示例中,請按照以下步驟,在使用者按下按鈕後為文字欄位分配焦點:
- 建立一個
FocusNode。 - 將
FocusNode傳遞給TextField。 - 在點選按鈕時使
TextField獲取焦點。
1. 建立一個 FocusNode
#
首先,建立一個 FocusNode。使用 FocusNode 在 Flutter 的“焦點樹”中標識特定的 TextField。這使你能夠在後續步驟中為該 TextField 分配焦點。
由於焦點節點是長生命週期物件,請使用 State 物件來管理其生命週期。請遵循以下說明,在 State 類的 initState() 方法中建立 FocusNode 例項,並在 dispose() 方法中將其銷燬:
// Define a custom Form widget.
class MyCustomForm extends StatefulWidget {
const MyCustomForm({super.key});
@override
State<MyCustomForm> createState() => _MyCustomFormState();
}
// Define a corresponding State class.
// This class holds data related to the form.
class _MyCustomFormState extends State<MyCustomForm> {
// Define the focus node. To manage the lifecycle, create the FocusNode in
// the initState method, and clean it up in the dispose method.
late FocusNode myFocusNode;
@override
void initState() {
super.initState();
myFocusNode = FocusNode();
}
@override
void dispose() {
// Clean up the focus node when the Form is disposed.
myFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
// Fill this out in the next step.
}
}
2. 將 FocusNode 傳遞給 TextField
#
現在你已經有了 FocusNode,請在 build() 方法中將其傳遞給指定的 TextField。
@override
Widget build(BuildContext context) {
return TextField(focusNode: myFocusNode);
}
3. 在點選按鈕時使 TextField 獲取焦點
#
最後,當用戶點選浮動操作按鈕時,讓文字欄位獲取焦點。使用 requestFocus() 方法來執行此任務。
FloatingActionButton(
// When the button is pressed,
// give focus to the text field using myFocusNode.
onPressed: () => myFocusNode.requestFocus(),
),
互動示例
#import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(title: 'Text Field Focus', home: MyCustomForm());
}
}
// Define a custom Form widget.
class MyCustomForm extends StatefulWidget {
const MyCustomForm({super.key});
@override
State<MyCustomForm> createState() => _MyCustomFormState();
}
// Define a corresponding State class.
// This class holds data related to the form.
class _MyCustomFormState extends State<MyCustomForm> {
// Define the focus node. To manage the lifecycle, create the FocusNode in
// the initState method, and clean it up in the dispose method.
late FocusNode myFocusNode;
@override
void initState() {
super.initState();
myFocusNode = FocusNode();
}
@override
void dispose() {
// Clean up the focus node when the Form is disposed.
myFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Text Field Focus')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
// The first text field is focused on as soon as the app starts.
const TextField(autofocus: true),
// The second text field is focused on when a user taps the
// FloatingActionButton.
TextField(focusNode: myFocusNode),
],
),
),
floatingActionButton: FloatingActionButton(
// When the button is pressed,
// give focus to the text field using myFocusNode.
onPressed: () => myFocusNode.requestFocus(),
tooltip: 'Focus Second Text Field',
child: const Icon(Icons.edit),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}