Flutter TypeAhead
一个 Flutter 的 TypeAhead (自动完成) 小部件,您可以在其中向用户显示键入时的建议
功能
- 在其他小部件的顶部显示建议,浮动在叠加层中
- 允许您通过构建器函数来指定建议的外观
- 允许您指定用户点击建议时会发生什么
- 接受传统TextField接受的所有参数,例如装饰、自定义TextEditingController、文本样式等。
- 提供两个版本,一个普通版本和一个FormField版本,后者接受验证、提交等。
- 提供高度的可定制性;您可以自定义建议框装饰、加载条、动画、去抖动持续时间等。
安装
请参阅pub上的安装说明。
用法示例
您可以通过以下方式导入包
import 'package:flutter_typeahead/flutter_typeahead.dart';
对于Cupertino用户,请导入
import 'package:flutter_typeahead/cupertino_flutter_typeahead.dart';
像这样使用它
Material示例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)
));
},
)
在上面的代码中,textFieldConfiguration属性允许我们按照需要配置显示的TextField。在此示例中,我们正在配置autofocus、style和decoration属性。
suggestionsCallback会根据用户输入的搜索字符串被调用,并应同步或异步返回数据列表。在此示例中,我们调用一个名为BackendService.getSuggestions的异步函数,该函数获取建议列表。
itemBuilder用于为每个建议构建一个小部件。在此示例中,我们构建一个简单的ListTile,它显示项目的名称和价格。请注意,您不应在此处提供onTap回调。TypeAhead小部件会处理此事。
onSuggestionSelected是用户点击建议时调用的回调。在此示例中,当用户点击建议时,我们会导航到一个显示被点击产品信息的页面。
Material示例2
这是另一个示例,我们在其中将TypeAheadFormField用于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: <Widget>[
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}')
));
}
},
)
],
),
),
)
在这里,我们将textFieldConfiguration的controller属性设置为我们称为_typeAheadController的TextEditingController。我们在onSuggestionSelected回调中使用此控制器来设置TextField的值为选定的建议。
validator回调可以像任何FormField.validator函数一样使用。在我们的示例中,它检查是否输入了值,如果没有则显示错误消息。onSaved回调用于将字段的值保存到_selectedCity成员变量。
transitionBuilder允许我们自定义建议框的动画。在此示例中,我们直接返回suggestionsBox,这意味着我们不希望有任何动画。
Cupertino示例
请参阅示例项目中的Cupertino代码。
已知问题
动画
将TypeAheadField放置在带有动画的小部件中可能会导致建议框的大小调整不正确。由于动画时间是可变的,因此必须在动画结束时手动更正。您需要添加下面描述的SuggestionsBoxController以及以下代码来处理AnimationController。
void Function(AnimationStatus) _statusListener;
@override
void initState() {
super.initState();
_statusListener = (AnimationStatus status) {
if (status == AnimationStatus.completed ||
status == AnimationStatus.dismissed) {
_suggestionsBoxController.resize();
}
};
_animationController.addStatusListener(_statusListener);
}
@override
void dispose() {
_animationController.removeStatusListener(_statusListener);
_animationController.dispose();
super.dispose();
}
对话框
打开对话框时存在一个已知问题,即建议框有时会显得太小。这是由上述动画引起的时序问题。目前,showDialog的动画持续时间为150毫秒。TypeAheadField将延迟170毫秒以弥补此问题。在能够使用上述解决方案正确检测和修复动画结束之前,此临时修复程序在大多数情况下都可以工作。如果建议框太小,关闭并重新打开键盘通常可以解决此问题。
Cupertino
TypeAhead中的Cupertino类仍是新的。Cupertino小部件与Material小部件之间也存在差异。在两者之间移动时,某些行为将不会转移。
自定义
TypeAhead小部件由一个TextField和一个在用户输入时显示的建议框组成。两者都高度可定制
自定义TextField
您可以使用textFieldConfiguration属性来自定义文本字段。您可以为此属性提供TextFieldConfiguration的实例,它允许您配置TextField的所有常规属性,如decoration、style、controller、focusNode、autofocus、enabled等。
自定义建议框
TypeAhead为建议框提供默认配置。但是,您可以覆盖其中大部分。这是通过将SuggestionsBoxDecoration传递给suggestionsBoxDecoration属性来完成的。
使用SuggestionsBoxDecoration中的offsetX属性沿x轴移动建议框。您还可以将BoxConstraints传递给SuggestionsBoxDecoration中的constraints以调整建议框的宽度和高度。将两者结合使用将允许建议框几乎放置在任何地方。
自定义加载器、错误和“未找到项目”消息
您可以使用loadingBuilder、errorBuilder和noItemsFoundBuilder来自定义相应的窗口小部件。例如,要显示自定义错误小部件
errorBuilder: (BuildContext context, Object error) =>
Text(
'$error',
style: TextStyle(
color: Theme.of(context).errorColor
)
)
默认情况下,在检索新建议时,建议框将保留旧建议。要改为在检索期间显示圆形进度指示器,请将keepSuggestionsOnLoading设置为false。
隐藏建议框
在三种情况下可以隐藏建议框。
将hideOnLoading设置为true以在检索建议时隐藏框。这将忽略loadingBuilder。将hideOnEmpty设置为true以在没有建议时隐藏框。这将忽略noItemsFoundBuilder。将hideOnError设置为true以在检索建议时出错时隐藏框。这将忽略errorBuilder。
默认情况下,当键盘隐藏时,建议框会自动隐藏。要更改此行为,请将hideSuggestionsOnKeyboardHide设置为false。
自定义动画
您可以通过3个参数来自定义建议框动画:animationDuration、animationStart和transitionBuilder。
animationDuration指定动画应持续多长时间,而animationStart指定动画应从哪个点(0.0到1.0之间)开始。transitionBuilder接受suggestionsBox和animationController作为参数,并应返回一个使用animationController来为suggestionsBox的显示设置动画的小部件。例如
transitionBuilder: (context, suggestionsBox, animationController) =>
FadeTransition(
child: suggestionsBox,
opacity: CurvedAnimation(
parent: animationController,
curve: Curves.fastOutSlowIn
),
)
这使用FadeTransition将suggestionsBox淡入视图。请注意,animationController如何作为动画的父级提供。
为了完全移除动画,transitionBuilder应该只返回suggestionsBox。此回调还可以用于用任何所需的窗口小部件包装suggestionsBox,而不一定是用于动画。
自定义去抖动持续时间
建议框不会为用户输入的每个字符触发。相反,我们等到用户空闲一段时间,然后调用suggestionsCallback。持续时间默认为300毫秒,但可以使用debounceDuration参数进行配置。
自定义建议框的偏移量
默认情况下,建议框显示在TextField下方5像素处。您可以通过更改suggestionsBoxVerticalOffset属性来更改此设置。
自定义建议框的装饰
您还可以使用suggestionsBoxDecoration属性来自定义建议框的装饰。例如,要删除建议框的阴影,您可以编写
suggestionsBoxDecoration: SuggestionsBoxDecoration(
elevation: 0.0
)
自定义建议列表的生长方向
默认情况下,列表向底部生长。但是,您可以使用direction属性将生长方向自定义为AxisDirection.down或AxisDirection.up之一,后者将导致列表向上生长,其中第一个建议位于列表底部,最后一个建议位于列表顶部。
将autoFlipDirection设置为true,以允许建议列表在检测到当前方向没有足够空间时自动翻转方向。这对于TypeAheadField位于可滚动小部件中或开发人员希望确保列表始终可见(尽管用户屏幕尺寸不同)的情况很有用。
控制建议框
可以通过创建SuggestionsBoxController的实例并将其传递给suggestionsBoxController属性来实现建议框的手动控制。这将允许您手动打开、关闭、切换或调整建议框的大小。
更多信息
访问API文档
团队
| AbdulRahman AlHamali | S McDowall | Kenneth Liang |
感谢各位贡献者!
本项目是各位贡献者共同努力的结果,他们通过提交拉取请求、报告问题和回答问题来积极参与。感谢您的积极主动,我们希望flutter_typeahead能让您的生活至少轻松一点!
