onChanged property

ValueChanged<String>? onChanged
final

Called when the user initiates a change to the TextField's value: when they have inserted or deleted text.

This callback doesn't run when the TextField's text is changed programmatically, via the TextField's controller. Typically it isn't necessary to be notified of such changes, since they're initiated by the app itself.

To be notified of all changes to the TextField's text, cursor, and selection, one can add a listener to its controller with TextEditingController.addListener.

onChanged is called before onSubmitted when user indicates completion of editing, such as when pressing the "done" button on the keyboard. That default behavior can be overridden. See onEditingComplete for details.

This example shows how onChanged could be used to check the TextField's current value each time the user inserts or deletes a character.

To see it in action, copy and run this code snippet on DartPad.

import 'package:flutter/material.dart';

/// Flutter code sample for [EditableText.onChanged].

void main() => runApp(const OnChangedExampleApp());

class OnChangedExampleApp extends StatelessWidget {
  const OnChangedExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: OnChangedExample());
  }
}

class OnChangedExample extends StatefulWidget {
  const OnChangedExample({super.key});

  @override
  State<OnChangedExample> createState() => _OnChangedExampleState();
}

class _OnChangedExampleState extends State<OnChangedExample> {
  final TextEditingController _controller = TextEditingController();

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: .center,
        children: <Widget>[
          const Text('What number comes next in the sequence?'),
          const Text('1, 1, 2, 3, 5, 8...?'),
          TextField(
            controller: _controller,
            onChanged: (String value) async {
              if (value != '13') {
                return;
              }
              await showDialog<void>(
                context: context,
                builder: (BuildContext context) {
                  return AlertDialog(
                    title: const Text('That is correct!'),
                    content: const Text('13 is the right answer.'),
                    actions: <Widget>[
                      TextButton(
                        onPressed: () {
                          Navigator.pop(context);
                        },
                        child: const Text('OK'),
                      ),
                    ],
                  );
                },
              );
            },
          ),
        ],
      ),
    );
  }
}

Handling emojis and other complex characters

It's important to always use characters when dealing with user input text that may contain complex characters. This will ensure that extended grapheme clusters and surrogate pairs are treated as single characters, as they appear to the user.

For example, when finding the length of some user input, use string.characters.length. Do NOT use string.length or even string.runes.length. For the complex character "👨‍👩‍👦", this appears to the user as a single character, and string.characters.length intuitively returns 1. On the other hand, string.length returns 8, and string.runes.length returns 5!

See also:

Implementation

// TODO(framework): Replace the following block with a @dartpad directive
// when it's supported. https://github.com/dart-lang/dartdoc/issues/4123
/// <small>
///
/// To see it in action, copy and run this code snippet on [DartPad](https://dartpad.dev/).
///
/// </small>
///
/// {@example /examples/api/lib/widgets/editable_text/editable_text.on_changed.0.dart#body}
///
/// </callout-box>
/// {@endtemplate}
///
/// ## Handling emojis and other complex characters
/// {@template flutter.widgets.EditableText.onChanged}
/// It's important to always use
/// [characters](https://pub.dev/packages/characters) when dealing with user
/// input text that may contain complex characters. This will ensure that
/// extended grapheme clusters and surrogate pairs are treated as single
/// characters, as they appear to the user.
///
/// For example, when finding the length of some user input, use
/// `string.characters.length`. Do NOT use `string.length` or even
/// `string.runes.length`. For the complex character "👨‍👩‍👦", this
/// appears to the user as a single character, and `string.characters.length`
/// intuitively returns 1. On the other hand, `string.length` returns 8, and
/// `string.runes.length` returns 5!
/// {@endtemplate}
///
/// See also:
///
///  * [inputFormatters], which are called before [onChanged]
///    runs and can validate and change ("format") the input value.
///  * [onEditingComplete], [onSubmitted], [onSelectionChanged]:
///    which are more specialized input change notifications.
///  * [TextEditingController], which implements the [Listenable] interface
///    and notifies its listeners on [TextEditingValue] changes.
final ValueChanged<String>? onChanged;