TypeAheadField<T> class
Flutter TypeAhead
A TypeAhead widget for Flutter, where you can show suggestions to users as they type
Features
- Shows suggestions in an overlay that floats on top of other widgets
- Allows you to specify what the suggestions will look like through a builder function
- Allows you to specify what happens when the user taps a suggestion
- Accepts all the parameters that traditional TextFields accept, like decoration, custom TextEditingController, text styling, etc.
- Provides two versions, a normal version and a FormField version that accepts validation, submitting, etc.
- Provides high customizability; you can customize the suggestion box decoration, the loading bar, the animation, the debounce duration, etc.
Installation
See the installation instructions on pub.
Usage examples
You can import the package with:
import 'package:flutter_typeahead/flutter_typeahead.dart';
and then use it as follows:
Example 1:
TypeAheadField(
textFieldConfiguration: TextFieldConfiguration(
autofocus: true,
style: DefaultTextStyle.of(context).style.copyWith(
fontStyle: FontStyle.italic
),
decoration: InputDecoration(
border: OutlineInputBorder()
)
),
suggestionsCallback: (pattern) async {
return await BackendService.getSuggestions(pattern);
},
itemBuilder: (context, suggestion) {
return ListTile(
leading: Icon(Icons.shopping_cart),
title: Text(suggestion['name']),
subtitle: Text('\$${suggestion['price']}'),
);
},
onSuggestionSelected: (suggestion) {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ProductPage(product: suggestion)
));
},
)
In the code above, the textFieldConfiguration
property allows us to
configure the displayed TextField
as we want. In this example, we are
configuring the autofocus
, style
and decoration
properties.
The suggestionsCallback
is called with the search string that the user
types, and is expected to return a List
of data either synchronously or
asynchronously. In this example, we are calling an asynchronous function
called BackendService.getSuggestions
which fetches the list of
suggestions.
The itemBuilder
is called to build a widget for each suggestion.
In this example, we build a simple ListTile
that shows the name and the
price of the item. Please note that you shouldn't provide an onTap
callback here. The TypeAhead widget takes care of that.
The onSuggestionSelected
is a callback called when the user taps a
suggestion. In this example, when the user taps a
suggestion, we navigate to a page that shows us the information of the
tapped product.
Example 2:
Here's another example, where we use the TypeAheadFormField inside a Form
:
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _typeAheadController = TextEditingController();
String _selectedCity;
...
Form(
key: this._formKey,
child: Padding(
padding: EdgeInsets.all(32.0),
child: Column(
children: [
Text(
'What is your favorite city?'
),
TypeAheadFormField(
textFieldConfiguration: TextFieldConfiguration(
controller: this._typeAheadController,
decoration: InputDecoration(
labelText: 'City'
)
),
suggestionsCallback: (pattern) {
return CitiesService.getSuggestions(pattern);
},
itemBuilder: (context, suggestion) {
return ListTile(
title: Text(suggestion),
);
},
transitionBuilder: (context, suggestionsBox, controller) {
return suggestionsBox;
},
onSuggestionSelected: (suggestion) {
this._typeAheadController.text = suggestion;
},
validator: (value) {
if (value.isEmpty) {
return 'Please select a city';
}
},
onSaved: (value) => this._selectedCity = value,
),
SizedBox(height: 10.0,),
RaisedButton(
child: Text('Submit'),
onPressed: () {
if (this._formKey.currentState.validate()) {
this._formKey.currentState.save();
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('Your Favorite City is ${this._selectedCity}')
));
}
},
)
],
),
),
)
Here, we assign to the controller
property of the textFieldConfiguration
a TextEditingController
that we call _typeAheadController
.
We use this controller in the onSuggestionSelected
callback to set the
value of the TextField
to the selected suggestion.
The validator
callback can be used like any FormField.validator
function. In our example, it checks whether a value has been entered,
and displays an error message if not. The onSaved
callback is used to
save the value of the field to the _selectedCity
member variable.
The transitionBuilder
allows us to customize the animation of the
suggestion box. In this example, we are returning the suggestionsBox
immediately, meaning that we don't want any animation.
Customizations
TypeAhead widgets consist of a TextField and a suggestion box that shows as the user types. Both are highly customizable
Customizing the TextField
You can customize the text field using the textFieldConfiguration
property.
You provide this property with an instance of TextFieldConfiguration
,
which allows you to configure all the usual properties of TextField
, like
decoration
, style
, controller
, focusNode
, autofocus
, enabled
,
etc.
Customizing the Suggestions Box
TypeAhead provides default configurations for the suggestions box. You can, however, override most of them.
Customizing the loader, the error and the "no items found" message
You can use the loadingBuilder, errorBuilder and noItemsFoundBuilder to customize their corresponding widgets. For example, to show a custom error widget:
errorBuilder: (BuildContext context, Object error) =>
Text(
'$error',
style: TextStyle(
color: Theme.of(context).errorColor
)
)
Customizing the animation
You can customize the suggestion box animation through 3 parameters: the
animationDuration
, the animationStart
, and the transitionBuilder
.
The animationDuration
specifies how long the animation should take, while the
animationStart
specified what point (between 0.0 and 1.0) the animation
should start from. The transitionBuilder
accepts the suggestionsBox
and
animationController
as parameters, and should return a widget that uses
the animationController
to animate the display of the suggestionsBox
.
For example:
transitionBuilder: (context, suggestionsBox, animationController) =>
FadeTransition(
child: suggestionsBox,
opacity: CurvedAnimation(
parent: animationController,
curve: Curves.fastOutSlowIn
),
)
This uses FadeTransition
to fade the suggestionsBox
into the view. Note how the
animationController
was provided as the parent of the animation.
In order to fully remove the animation, transitionBuilder
should simply
return the suggestionsBox
. This callback could also be used to wrap the
suggestionsBox
with any desired widgets, not necessarily for animation.
Customizing the debounce duration
The suggestions box does not fire for each character the user types. Instead,
we wait until the user is idle for a duration of time, and then call the
suggestionsCallback
. The duration defaults to 300 milliseconds, but can be
configured using the debounceDuration
parameter.
Customizing the offset of the suggestions box
By default, the suggestions box is displayed 5 pixels below the TextField
.
You can change this by changing the suggestionsBoxVerticalOffset
property.
Customizing the decoration of the suggestions box
You can also customize the decoration of the suggestions box using the
suggestionsBoxDecoration
property. For example, to remove the elevation
of the suggestions box, you can write:
suggestionsBoxDecoration: SuggestionsBoxDecoration(
elevation: 0.0
)
A FormField implementation of TypeAheadField, that allows the value to be saved, validated, etc.
See also:
- TypeAheadField, A TextField that displays a list of suggestions as the user types
- Inheritance
-
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- TypeAheadField
Constructors
-
TypeAheadField({required SuggestionsCallback<
T> suggestionsCallback, required ItemBuilder<T> itemBuilder, IndexedWidgetBuilder? itemSeparatorBuilder, LayoutArchitecture? layoutArchitecture, bool intercepting = false, required SuggestionSelectionCallback<T> onSuggestionSelected, TextFieldConfiguration textFieldConfiguration = const TextFieldConfiguration(), SuggestionsBoxDecoration suggestionsBoxDecoration = const SuggestionsBoxDecoration(), Duration debounceDuration = const Duration(milliseconds: 300), SuggestionsBoxController? suggestionsBoxController, ScrollController? scrollController, WidgetBuilder? loadingBuilder, WidgetBuilder? noItemsFoundBuilder, ErrorBuilder? errorBuilder, AnimationTransitionBuilder? transitionBuilder, double animationStart = 0.25, Duration animationDuration = const Duration(milliseconds: 500), bool getImmediateSuggestions = false, double suggestionsBoxVerticalOffset = 5.0, AxisDirection direction = AxisDirection.down, bool hideOnLoading = false, bool hideOnEmpty = false, bool hideOnError = false, bool hideSuggestionsOnKeyboardHide = true, bool keepSuggestionsOnLoading = true, bool keepSuggestionsOnSuggestionSelected = false, bool autoFlipDirection = false, bool autoFlipListDirection = true, double autoFlipMinHeight = 64.0, bool hideKeyboard = false, int minCharsForSuggestions = 0, void onSuggestionsBoxToggle(bool)?, bool hideKeyboardOnDrag = false, Key? key}) -
Creates a TypeAheadField
const
Properties
- animationDuration → Duration
-
The duration that transitionBuilder animation takes.
final
- animationStart → double
-
The value at which the transitionBuilder animation starts.
final
- autoFlipDirection → bool
-
If set to true, in the case where the suggestions box has less than
_SuggestionsBoxController.minOverlaySpace to grow in the desired direction, the direction axis
will be temporarily flipped if there's more room available in the opposite
direction.
final
- autoFlipListDirection → bool
-
If set to false, suggestion list will not be reversed according to the
autoFlipDirection property.
final
- autoFlipMinHeight → double
-
Minimum height below autoFlipDirection is triggered
final
- debounceDuration → Duration
-
The duration to wait after the user stops typing before calling
suggestionsCallback
final
- direction → AxisDirection
-
Determine the
SuggestionBox
's direction.final - errorBuilder → ErrorBuilder?
-
Called when suggestionsCallback throws an exception.
final
- getImmediateSuggestions → bool
-
If set to true, suggestions will be fetched immediately when the field is
added to the view.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- hideKeyboard → bool
-
final
- hideKeyboardOnDrag → bool
-
If set to true and if the user scrolls through the suggestion list, hide the keyboard automatically.
If set to false, the keyboard remains visible.
Throws an exception, if hideKeyboardOnDrag and hideSuggestionsOnKeyboardHide are both set to true as
they are mutual exclusive.
final
- hideOnEmpty → bool
-
If set to true, nothing will be shown if there are no results.
noItemsFoundBuilder will also be ignored.
final
- hideOnError → bool
-
If set to true, nothing will be shown if there is an error.
errorBuilder will also be ignored.
final
- hideOnLoading → bool
-
If set to true, no loading box will be shown while suggestions are
being fetched. loadingBuilder will also be ignored.
final
- hideSuggestionsOnKeyboardHide → bool
-
If set to false, the suggestions box will stay opened after
the keyboard is closed.
final
-
Allows a bypass of a problem on Flutter 3.7+ with the accessibility through Overlay
that prevents flutter_typeahead to register a click on the list of suggestions properly.
final
- intercepting → bool
-
Used to overcome Flutter issue 98507
Most commonly experienced when placing the TypeAheadFormField on a google map in Flutter Web.
final
-
itemBuilder
→ ItemBuilder<
T> -
Called for each suggestion returned by suggestionsCallback to build the
corresponding widget.
final
- itemSeparatorBuilder → IndexedWidgetBuilder?
-
final
- keepSuggestionsOnLoading → bool
-
If set to false, the suggestions box will show a circular
progress indicator when retrieving suggestions.
final
- keepSuggestionsOnSuggestionSelected → bool
-
If set to true, the suggestions box will remain opened even after
selecting a suggestion.
final
- key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
- layoutArchitecture → LayoutArchitecture?
-
By default, we render the suggestions in a ListView, using
the
itemBuilder
to construct each element of the list. Specify your ownlayoutArchitecture
if you want to be responsible for layinng out the widgets using some other system (like a grid).final - loadingBuilder → WidgetBuilder?
-
Called when waiting for suggestionsCallback to return.
final
- minCharsForSuggestions → int
-
The minimum number of characters which must be entered before
suggestionsCallback is triggered.
final
- noItemsFoundBuilder → WidgetBuilder?
-
Called when suggestionsCallback returns an empty array.
final
- onSuggestionsBoxToggle → void Function(bool)?
-
final
-
onSuggestionSelected
→ SuggestionSelectionCallback<
T> -
Called when a suggestion is tapped.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- scrollController → ScrollController?
-
used to control the scroll behavior of item-builder list
final
- suggestionsBoxController → SuggestionsBoxController?
-
Used to control the
_SuggestionsBox
. Allows manual control to open, close, toggle, or resize the_SuggestionsBox
.final - suggestionsBoxDecoration → SuggestionsBoxDecoration
-
The decoration of the material sheet that contains the suggestions.
final
- suggestionsBoxVerticalOffset → double
-
How far below the text field should the suggestions box be
final
-
suggestionsCallback
→ SuggestionsCallback<
T> -
Called with the search pattern to get the search suggestions.
final
- textFieldConfiguration → TextFieldConfiguration
-
The configuration of the TextField
that the TypeAhead widget displays
final
- transitionBuilder → AnimationTransitionBuilder?
-
Called to display animations when suggestionsCallback returns suggestions
final
Methods
-
createElement(
) → StatefulElement -
Creates a StatefulElement to manage this widget's location in the tree.
inherited
-
createState(
) → State< TypeAheadField< 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.
inherited
-
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent 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.
inherited