焦點和文字框
當一個文字框(輸入框)被選中並接受輸入時,被稱為獲得了『焦點』。通常情況下,使用者能夠透過點選文字框以使其聚焦,開發人員也可以使用本文所描述的方法來讓文字框得到焦點。
管理焦點是一種直觀地建立表單流程的基本方法。例如,假設我們有一個帶有文字框的搜尋頁面。當用戶導向到搜尋頁面時,我們可以聚焦文字框的搜尋項。這將允許使用者在搜尋頁面可見時能夠立即開始輸入,而無需手動點選文字框。
在本文中,我們將學習如何聚焦到文字框上,以及點選按鈕時聚焦文字框。
一旦文字框可見,就將其聚焦
為了在文字框可見時將其聚焦,我們可以使用 autofocus
屬性。
TextField(
autofocus: true,
);
有關處理輸入和建立文字框的更多訊息,請參閱 實用教程的 Forms 部分。
點選按鈕時聚焦文字框
我們也可能需要在之後的某個時間點聚焦特定的文字框,而不是立即聚焦它。在這個例子中,我們將看到在使用者按下按鈕後如何聚焦文字框。在實際開發中,你還可能需要聚焦特定的文字框以回應 api 呼叫或錯誤校驗。
-
建立一個
FocusNode
-
將
FocusNode
傳遞給TextField
-
透過點選按鈕聚焦
TextField
FocusNode
1. 建立一個 首先,我們需要建立一個 FocusNode
。我們將使用 FocusNode
來識別 Flutter 的『focus tree』中的特定的 TextField
。這將允許我們能夠在接下來的步驟中聚焦 TextField
。
由於 focus node 是長壽命物件,我們需要使用 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.
}
}
FocusNode
傳遞給 TextField
2. 將 現在已經有了 FocusNode
,我們可以將這個 TextField
傳遞給 build()
方法。
@override
Widget build(BuildContext context) {
return TextField(
focusNode: myFocusNode,
);
}
TextField
3. 透過點選按鈕聚焦 最後,當用戶點選 floating action button 時,我們將要聚焦文字框!為此我們將要使用 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.
);
}
}