返回介绍

Handling changes to a text field

发布于 2019-12-09 21:31:27 字数 7776 浏览 1028 评论 0 收藏 0

In some cases, it can be handy to run a callback function every time the text in a text field changes. For example, we might want to build a search screen with autocomplete functionality. In this case, we would want to update the results as the user types.

How can we run a callback function every time the text changes? With Flutter, we have two options:

  1. Supply an onChanged callback to a TextField
  2. Use a TextEditingController

1. Supply an onChanged callback to a TextField

The simplest approach is to supply an onChanged callback to a TextField. Whenever the text changes, the callback will be invoked. One downside to this approach is it does not work with TextFormField Widgets.

In this example, we will print the current value of the text field to the console every time the text changes.

TextField(
  onChanged: (text) {
    print("First text field: $text");
  },
);

2. Use a TextEditingController

A more powerful, but more elaborate approach, is to supply a TextEditingController as the controller property of the TextField or a TextFormField.

To be notified when the text changes, we can listen to the controller using its addListener method.

Directions

  • Create a TextEditingController
  • Supply the TextEditingController to a TextField
  • Create a function to print the latest value
  • Listen to the controller for changes

Create a TextEditingController

First, we’ll need to create a TextEditingController. In the subsequent steps, we will supply the TextEditingController to a TextField. Once we’ve wired these two classes together, we can listen for changes to the text field!

// Define a Custom Form Widget
class MyCustomForm extends StatefulWidget {
  @override
  _MyCustomFormState createState() => _MyCustomFormState();
}

// Define a corresponding State class. This class will hold the data related to
// our Form.
class _MyCustomFormState extends State<MyCustomForm> {
  // Create a text controller. We will 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) {
    // We will fill this out in the next step!
  }
}

Note: Please remember to dispose the TextEditingController when it is no longer needed. This will ensure we discard any resources used by the object.

Supply the TextEditingController to a TextField

In order to work, the TextEditingController must be supplied to either a TextField or a TextFormField. Once it’s wired up, we can begin listening for changes to the text field.

TextField(
  controller: myController,
);

Create a function to print the latest value

Now, we’ll need a function that should run every time the text changes! In this example, we’ll create a method that prints out the current value of the text field.

This method will live inside our _MyCustomFormState class.

_printLatestValue() {
  print("Second text field: ${myController.text}");
}

Listen to the controller for changes

Finally, we need to listen to the TextEditingController and run the _printLatestValue method whenever the text changes. We will use the addListener method to achieve this task.

In this example, we will begin listening for changes when the _MyCustomFormState class is initialized, and stop listening when the _MyCustomFormState is disposed.

class _MyCustomFormState extends State<MyCustomForm> {
  @override
  void initState() {
    super.initState();

    // Start listening to changes
    myController.addListener(_printLatestValue);
  }
}

Complete example

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Retrieve Text Input',
      home: MyCustomForm(),
    );
  }
}

// Define a Custom Form Widget
class MyCustomForm extends StatefulWidget {
  @override
  _MyCustomFormState createState() => _MyCustomFormState();
}

// Define a corresponding State class. This class will hold the data related to
// our Form.
class _MyCustomFormState extends State<MyCustomForm> {
  // Create a text controller. We will use it to retrieve the current value
  // of the TextField!
  final myController = TextEditingController();

  @override
  void initState() {
    super.initState();

    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();
  }

  _printLatestValue() {
    print("Second text field: ${myController.text}");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Retrieve Text Input'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: <Widget>[
            TextField(
              onChanged: (text) {
                print("First text field: $text");
              },
            ),
            TextField(
              controller: myController,
            ),
          ],
        ),
      ),
    );
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文