textEditingController property

TextEditingController? textEditingController
final

The TextEditingController that is used for the text field.

The main purpose of this parameter is to allow the use of a separate text field located in another part of the widget tree instead of the text field built by fieldViewBuilder. For example, it may be desirable to place the text field in the AppBar and the options below in the main body.

When following this pattern, fieldViewBuilder can be omitted, so that a text field is not drawn where it would normally be. A separate text field can be created elsewhere, and a FocusNode and TextEditingController can be passed both to that text field and to RawAutocomplete.

This examples shows how to create an autocomplete widget with the text field in the AppBar and the results in the main body of the app.

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

import 'package:flutter/material.dart';

/// Flutter code sample for [RawAutocomplete.focusNode].

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

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

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

const List<String> _options = <String>['aardvark', 'bobcat', 'chameleon'];

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

  @override
  RawAutocompleteSplitState createState() => RawAutocompleteSplitState();
}

class RawAutocompleteSplitState extends State<RawAutocompleteSplit> {
  final TextEditingController _textEditingController = TextEditingController();
  final FocusNode _focusNode = FocusNode();
  final GlobalKey _autocompleteKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // This is where the real field is being built.
        title: TextFormField(
          controller: _textEditingController,
          focusNode: _focusNode,
          decoration: const InputDecoration(
            hintText: 'Split RawAutocomplete App',
          ),
          onFieldSubmitted: (String value) {
            RawAutocomplete.onFieldSubmitted<String>(_autocompleteKey);
          },
        ),
      ),
      body: Align(
        alignment: .topLeft,
        child: RawAutocomplete<String>(
          key: _autocompleteKey,
          focusNode: _focusNode,
          textEditingController: _textEditingController,
          optionsBuilder: (TextEditingValue textEditingValue) {
            return _options.where((String option) {
              return option.contains(textEditingValue.text.toLowerCase());
            }).toList();
          },
          optionsViewBuilder:
              (
                BuildContext context,
                AutocompleteOnSelected<String> onSelected,
                Iterable<String> options,
              ) {
                return Material(
                  elevation: 4.0,
                  child: ListView(
                    children: options
                        .map(
                          (String option) => GestureDetector(
                            onTap: () {
                              onSelected(option);
                            },
                            child: ListTile(title: Text(option)),
                          ),
                        )
                        .toList(),
                  ),
                );
              },
        ),
      ),
    );
  }
}

If this parameter is not null, then focusNode must also be non-null.

Implementation

final TextEditingController? textEditingController;