响应文本框内容的更改
在某些情境中,我们可能需要在每次文本框的文本内容变化时都调用回调函数。例如,当构建一个有自动填充功能的搜索页面时,我们希望根据用户输入的内容来更新返回的结果。
那么如何每次在文本内容改变时调用回调函数呢?在Flutter中,我们提供了两种选择:
-
给
TextField
或TextFormField
绑定onChanged()
回调 -
使用
TextEditingController
1. 给 TextField
或 TextFormField
绑定 onChanged()
回调
#
最简单的方法是给 TextField
绑定 onChanged()
回调。每当文本内容改变时,回调函数会被触发。
在下面的示例中,每次 text 的值改变,会在控制台中打印出当前文本框的值。
在处理用户的输入内容时,很重要的一点是要使用 characters,因为用户的输入内容可能会包含复杂的字符。 characters 会保证每一个显示到用户字符都被计数到。
TextField(
onChanged: (text) {
print('First text field: $text (${text.characters.length})');
},
),
2. 使用 TextEditingController
#
另外一种更强大但是更复杂的方法是绑定 TextEditingController
作为 TextField
和
TextFormField
的 controller
属性。
你可以通过如下步骤,使用 addListener()
方法来监听控制,实现在文本更改时收到通知:
-
创建一个
TextEditingController
-
将
TextEditingController
绑定到 text field -
创建一个函数来打印最新值
-
监听控制器的变化
创建一个 TextEditingController
#
创建一个 TextEditingController
:
// 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> {
// Create a text controller. Later, use it to retrieve the
// current value of the TextField.
final myController = TextEditingController();
@override
void dispose() {
// Clean up the controller when the widget is removed from the
// widget tree.
myController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
// Fill this out in the next step.
}
}
给 text field 绑定 TextEditingController
#
TextEditingController
必须绑定到 TextField
或者是 TextFormField
才能被正常的使用。一旦绑定,就能够开始监听文本框的变化。
TextField(
controller: myController,
),
创建一个打印当前值的方法
#现在,我们需要一个每当表单项变化都会运行的函数。在下面的示例中,我们会在 _MyCustomFormState
类中创建一个方法,实现打印出文本框当前值。
void _printLatestValue() {
final text = myController.text;
print('Second text field: $text (${text.characters.length})');
}
监听控制器的变化
#最后,需要监听 TextEditingController
并且在 text 值变化时运行
_printLatestValue()
方法。我们需要使用 addListener()
方法来实现这个功能。
下面的示例会在类 _MyCustomFormState
初始化的时候开始监听变化,dispose 时停止监听。
@override
void initState() {
super.initState();
// Start listening to changes.
myController.addListener(_printLatestValue);
}
@override
void dispose() {
// Clean up the controller when the widget is removed from the widget tree.
// This also removes the _printLatestValue listener.
myController.dispose();
super.dispose();
}
交互式样例
#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: 'Retrieve Text Input',
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> {
// Create a text controller and use it to retrieve the current value
// of the TextField.
final myController = TextEditingController();
@override
void initState() {
super.initState();
// Start listening to changes.
myController.addListener(_printLatestValue);
}
@override
void dispose() {
// Clean up the controller when the widget is removed from the widget tree.
// This also removes the _printLatestValue listener.
myController.dispose();
super.dispose();
}
void _printLatestValue() {
final text = myController.text;
print('Second text field: $text (${text.characters.length})');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Retrieve Text Input'),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
TextField(
onChanged: (text) {
print('First text field: $text (${text.characters.length})');
},
),
TextField(
controller: myController,
),
],
),
),
);
}
}
除非另有说明,本文档之所提及适用于 Flutter 的最新稳定版本,本页面最后更新时间: 2024-07-03。 查看文档源码 或者 为本页面内容提出建议。