RawAutocomplete<T extends Object> class Null safety
A widget for helping the user make a selection by entering some text and choosing from among a list of options.
The user's text input is received in a field built with the fieldViewBuilder parameter. The options to be displayed are determined using optionsBuilder and rendered with optionsViewBuilder.
This is a core framework widget with very basic UI.
This example shows how to create a very basic autocomplete widget using the
fieldViewBuilder and optionsViewBuilder parameters.
To create a local project with this code sample, run:
flutter create --sample=widgets.RawAutocomplete.1 mysample
flutter create --sample=widgets.RawAutocomplete.1 mysample
This example shows how to create a very basic autocomplete widget using the
fieldViewBuilder and optionsViewBuilder parameters.
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
// ...
class AutocompleteBasicExample extends StatelessWidget {
AutocompleteBasicExample({Key? key}) : super(key: key);
static final List<String> _options = <String>[
'aardvark',
'bobcat',
'chameleon',
];
@override
Widget build(BuildContext context) {
return RawAutocomplete<String>(
optionsBuilder: (TextEditingValue textEditingValue) {
return _options.where((String option) {
return option.contains(textEditingValue.text.toLowerCase());
});
},
fieldViewBuilder: (BuildContext context, TextEditingController textEditingController, FocusNode focusNode, VoidCallback onFieldSubmitted) {
return TextFormField(
controller: textEditingController,
focusNode: focusNode,
onFieldSubmitted: (String value) {
onFieldSubmitted();
},
);
},
optionsViewBuilder: (BuildContext context, AutocompleteOnSelected<String> onSelected, Iterable<String> options) {
return Align(
alignment: Alignment.topLeft,
child: Material(
elevation: 4.0,
child: Container(
height: 200.0,
child: ListView.builder(
padding: EdgeInsets.all(8.0),
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final String option = options.elementAt(index);
return GestureDetector(
onTap: () {
onSelected(option);
},
child: ListTile(
title: Text(option),
),
);
},
),
),
),
);
},
);
}
}
The type parameter T represents the type of the options. Most commonly this
is a String, as in the example above. However, it's also possible to use
another type with a toString
method, or a custom displayStringForOption.
Options will be compared using ==
, so it may be beneficial to override
Object.== and Object.hashCode for custom types.
This example is similar to the previous example, but it uses a custom T data
type instead of directly using String.
To create a local project with this code sample, run:
flutter create --sample=widgets.RawAutocomplete.2 mysample
flutter create --sample=widgets.RawAutocomplete.2 mysample
This example is similar to the previous example, but it uses a custom T data
type instead of directly using String.
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
// ...
// An example of a type that someone might want to autocomplete a list of.
class User {
const User({
required this.email,
required this.name,
});
final String email;
final String name;
@override
String toString() {
return '$name, $email';
}
@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType)
return false;
return other is User
&& other.name == name
&& other.email == email;
}
@override
int get hashCode => hashValues(email, name);
}
class AutocompleteCustomTypeExample extends StatelessWidget {
AutocompleteCustomTypeExample({Key? key}) : super(key: key);
static final List<User> _userOptions = <User>[
User(name: 'Alice', email: 'alice@example.com'),
User(name: 'Bob', email: 'bob@example.com'),
User(name: 'Charlie', email: 'charlie123@gmail.com'),
];
static String _displayStringForOption(User option) => option.name;
@override
Widget build(BuildContext context) {
return RawAutocomplete<User>(
optionsBuilder: (TextEditingValue textEditingValue) {
return _userOptions.where((User option) {
// Search based on User.toString, which includes both name and
// email, even though the display string is just the name.
return option.toString().contains(textEditingValue.text.toLowerCase());
});
},
displayStringForOption: _displayStringForOption,
fieldViewBuilder: (BuildContext context, TextEditingController textEditingController, FocusNode focusNode, VoidCallback onFieldSubmitted) {
return TextFormField(
controller: textEditingController,
focusNode: focusNode,
onFieldSubmitted: (String value) {
onFieldSubmitted();
},
);
},
optionsViewBuilder: (BuildContext context, AutocompleteOnSelected<User> onSelected, Iterable<User> options) {
return Align(
alignment: Alignment.topLeft,
child: Material(
elevation: 4.0,
child: Container(
height: 200.0,
child: ListView.builder(
padding: EdgeInsets.all(8.0),
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final User option = options.elementAt(index);
return GestureDetector(
onTap: () {
onSelected(option);
},
child: ListTile(
title: Text(_displayStringForOption(option)),
),
);
},
),
),
),
);
},
);
}
}
This example shows the use of RawAutocomplete in a form.
To create a local project with this code sample, run:
flutter create --sample=widgets.RawAutocomplete.3 mysample
flutter create --sample=widgets.RawAutocomplete.3 mysample
This example shows the use of RawAutocomplete in a form.
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
// ...
class AutocompleteFormExamplePage extends StatefulWidget {
AutocompleteFormExamplePage({Key? key}) : super(key: key);
@override
AutocompleteFormExample createState() => AutocompleteFormExample();
}
class AutocompleteFormExample extends State<AutocompleteFormExamplePage> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _textEditingController = TextEditingController();
String? _dropdownValue;
String? _autocompleteSelection;
final List<String> _options = <String>[
'aardvark',
'bobcat',
'chameleon',
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Autocomplete Form Example'),
),
body: Center(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
DropdownButtonFormField<String>(
value: _dropdownValue,
icon: Icon(Icons.arrow_downward),
hint: const Text('This is a regular DropdownButtonFormField'),
iconSize: 24,
elevation: 16,
style: TextStyle(color: Colors.deepPurple),
onChanged: (String? newValue) {
setState(() {
_dropdownValue = newValue;
});
},
items: <String>['One', 'Two', 'Free', 'Four']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
validator: (String? value) {
if (value == null) {
return 'Must make a selection.';
}
return null;
},
),
TextFormField(
controller: _textEditingController,
decoration: InputDecoration(
hintText: 'This is a regular TextFormField',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Can\'t be empty.';
}
return null;
},
),
RawAutocomplete<String>(
optionsBuilder: (TextEditingValue textEditingValue) {
return _options.where((String option) {
return option.contains(textEditingValue.text.toLowerCase());
});
},
onSelected: (String selection) {
setState(() {
_autocompleteSelection = selection;
});
},
fieldViewBuilder: (BuildContext context, TextEditingController textEditingController, FocusNode focusNode, VoidCallback onFieldSubmitted) {
return TextFormField(
controller: textEditingController,
decoration: InputDecoration(
hintText: 'This is an RawAutocomplete!',
),
focusNode: focusNode,
onFieldSubmitted: (String value) {
onFieldSubmitted();
},
validator: (String? value) {
if (!_options.contains(value)) {
return 'Nothing selected.';
}
return null;
},
);
},
optionsViewBuilder: (BuildContext context, AutocompleteOnSelected<String> onSelected, Iterable<String> options) {
return Align(
alignment: Alignment.topLeft,
child: Material(
elevation: 4.0,
child: Container(
height: 200.0,
child: ListView.builder(
padding: EdgeInsets.all(8.0),
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final String option = options.elementAt(index);
return GestureDetector(
onTap: () {
onSelected(option);
},
child: ListTile(
title: Text(option),
),
);
},
),
),
),
);
},
),
ElevatedButton(
onPressed: () {
FocusScope.of(context).requestFocus(new FocusNode());
if (!_formKey.currentState!.validate()) {
return;
}
showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Successfully submitted'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('DropdownButtonFormField: "$_dropdownValue"'),
Text('TextFormField: "${_textEditingController.text}"'),
Text('RawAutocomplete: "$_autocompleteSelection"'),
],
),
),
actions: <Widget>[
TextButton(
child: Text('Ok'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
},
child: Text('Submit'),
),
],
),
),
),
);
}
}
See also:
- Autocomplete, which is a Material-styled implementation that is based on RawAutocomplete.
- Inheritance
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- RawAutocomplete
Constructors
-
RawAutocomplete({Key? key, required AutocompleteOptionsViewBuilder<
T> optionsViewBuilder, required AutocompleteOptionsBuilder<T> optionsBuilder, AutocompleteOptionToString<T> displayStringForOption: defaultStringForOption, AutocompleteFieldViewBuilder? fieldViewBuilder, FocusNode? focusNode, AutocompleteOnSelected<T> ? onSelected, TextEditingController? textEditingController}) -
Create an instance of RawAutocomplete. [...]
const
Properties
-
displayStringForOption
→ AutocompleteOptionToString<
T> -
Returns the string to display in the field when the option is selected. [...]
final
- fieldViewBuilder → AutocompleteFieldViewBuilder?
-
Builds the field whose input is used to get the options. [...]
final
- focusNode → FocusNode?
-
The FocusNode that is used for the text field. [...]
final
- hashCode → int
-
The hash code for this object. [...]
@nonVirtual, read-only, inherited
- key → Key?
-
Controls how one widget replaces another widget in the tree. [...]
final, inherited
-
onSelected
→ AutocompleteOnSelected<
T> ? -
Called when an option is selected by the user. [...]
final
-
optionsBuilder
→ AutocompleteOptionsBuilder<
T> -
A function that returns the current selectable options objects given the
current TextEditingValue.
final
-
optionsViewBuilder
→ AutocompleteOptionsViewBuilder<
T> -
Builds the selectable options widgets from a list of options objects. [...]
final
- runtimeType → Type
-
A representation of the runtime type of the object.
read-only, inherited
- textEditingController → TextEditingController?
-
The TextEditingController that is used for the text field. [...]
final
Methods
-
createElement(
) → StatefulElement -
Creates a StatefulElement to manage this widget's location in the tree. [...]
inherited
-
createState(
) → _RawAutocompleteState< T> -
Creates the mutable state for this widget at a given location in the tree. [...]
override
-
debugDescribeChildren(
) → List< DiagnosticsNode> -
Returns a list of DiagnosticsNode objects describing this node's
children. [...]
@protected, inherited
-
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node. [...]
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a non-existent method or property is accessed. [...]
inherited
-
toDiagnosticsNode(
{String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode -
Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep. [...]
inherited
-
toString(
{DiagnosticLevel minLevel: DiagnosticLevel.info}) → String -
A string representation of this object. [...]
inherited
-
toStringDeep(
{String prefixLineOne: '', String? prefixOtherLines, DiagnosticLevel minLevel: DiagnosticLevel.debug}) → String -
Returns a string representation of this node and its descendants. [...]
inherited
-
toStringShallow(
{String joiner: ', ', DiagnosticLevel minLevel: DiagnosticLevel.debug}) → String -
Returns a one-line detailed description of the object. [...]
inherited
-
toStringShort(
) → String -
A short, textual description of this widget.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator. [...]
@nonVirtual, inherited
Static Methods
-
defaultStringForOption(
dynamic option) → String - The default way to convert an option to a string in displayStringForOption. [...]
-
onFieldSubmitted<
T extends Object> (GlobalKey< State< key) → voidStatefulWidget> > - Calls AutocompleteFieldViewBuilder's onFieldSubmitted callback for the RawAutocomplete widget indicated by the given GlobalKey. [...]