Flutter 组件: Autocomplete 自动填充 | 开发者说·DTalk

2022 年 10 月 28 日 谷歌开发者

本文原作者: 张风捷特烈,原文发布于: 编程之王


简单来说, Autocomplete 意为 自动填充 。其作用就是在输入时,进行 关键字联想 。在输入框下方展示列表,如下所示: 注意,这是目前 Flutter 框架内部的组件,非三方组件。目前已收录入 FlutterUnit,下面效果的源码详见之,大家可以更新查看体验: 

FlutterUnit 中

输入时联想效果

下面是动态搜索的效果展示:



Autocomplete 组件最简代码


我们先一步步来了解 Autocomplete 组件,先实现如下的最简代码: 

使用 Autocomplete 时,必须提供的是 optionsBuilder 参数,另外可以通过 onSelected 回调来监听选中的条目。


Autocomplete<String>(    optionsBuilder: buildOptions,    onSelected: onSelected,)

optionsBuilder 是一个 AutocompleteOptionsBuilder<T> 类型的函数,从下面的定义中可以发现,该函数会回调 TextEditingValue 对象,且返回 FutureOr<Iterable<T>>。这说明这个函数是一个异步函数,我们可以在此进行网络请求,数据库查询等工作,来返回一个 Iterable<T> 的可迭代对象。


用脚指头想一下也知道,这个可迭代对象,就决定着输入框下面的联想词是哪些。
final AutocompleteOptionsBuilder<T> optionsBuilder;
typedef AutocompleteOptionsBuilder<T extends Object> =     FutureOr<Iterable<T>> Function(TextEditingValue textEditingValue);

比如下面通过 searchByArgs 模拟网络请求,通过 args 参数搜索数据: 
Future<Iterable<String>> searchByArgs(String args) async{  // 模拟网络请求  await Future.delayed(const Duration(milliseconds: 200));  const List<String> data =  [    'toly''toly49''toly42''toly56'    'card''ls''alex''fan sha',  ]; return data.where((String name) => name.contains(args));}


这样,buildOptions 的逻辑如下,这就完成了输入--> 搜索 --> 展示联想词的流程。这也是 Autocomplete 组件最简单的使用。

Future<Iterable<String>> buildOptions( TextEditingValue textEditingValue ) async {  if (textEditingValue.text == '') {    return const Iterable<String>.empty();  }  return searchByArgs(textEditingValue.text);}



自定义 Autocomplete 组件内容


其实上面那样的默认样式很丑,而且没有提供直接的属性设置样式。所以了解如何自定义是非常关键的,否则只是一个玩具罢了。如下,我们先来实现搜索高亮显示的自定义,其中也包括对输入框的自定义。


Autocomplete 中提供了 fieldViewBuilder optionsViewBuilder 分别用于构造 输入框 浮层面板

如下,代码中通过 _buildOptionsView _buildFieldView 进行相应组件构造: 
Autocomplete<String>(  optionsBuilder: buildOptions,  onSelected: onSelected,  optionsViewBuilder: _buildOptionsView,  fieldViewBuilder: _buildFieldView,);


如下是 _buildOptionsView 方法的实现,其中会回调 onSelected 回调函数,和 options 数据,我们需要做的就是依靠数据,构建组件进行展示即可。另外,默认浮层面板和输入框底部平齐,可以通过 Padding 进行下移。另外,由于是浮层,展示文字时,上面需要嵌套 Material 组件。

至于高亮某个关键字,下面是我封装的一个小方法,拿来即用: 
---->[高亮某些文字]----final TextStyle lightTextStyle = const TextStyle(  color: Colors.blue,  fontWeight: FontWeight.bold,);InlineSpan formSpan(String src, String pattern) {  List<TextSpan> span = [];  List<String> parts = src.split(pattern);  if (parts.length > 1) {    for (int i = 0; i < parts.length; i++) {      span.add(TextSpan(text: parts[i]));      if (i != parts.length - 1) {        span.add(TextSpan(text: pattern, style: lightTextStyle));      }    }  } else {    span.add(TextSpan(text: src));  }  return TextSpan(children: span);}


另外,对于输入框的构建,通过如下的 _buildFieldView 实现,其中有 _controller 记录一下 TextEditingController,是因为 optionsViewBuilder 回调中并没有回调输入的 arg 字符,所以想要输入的关键字高亮,只能出此下策。这样,在 TextFormField 构建时,您可以指定自己需要的装饰。

到此,我们就实现了上面,输入过程中,浮层面板内容关键字高亮显示的效果。



关于 Autocomplete 中的泛型


泛型的作用非常明显,它最主要的是对浮层面板的构建,如果浮层中的条目不止是 String,我们就需要使用泛型,来提供某个的数据类型。比如下面的效果,其中浮层面板的条目是可以显示更多的信息: 

先定义一个数据类 User ,记录信息: 
class User {  final String name;  final bool man;  final String image;
  const User(this.name, this.man, this.image);
  @override  String toString() {    return 'User{name: $name, man: $man, image: $image}';  }}


然后在 Autocomplete 的泛型中使用 User 即可。

这样在 _buildOptionsView 中,回调的就是 User 的可迭代对象。如下,封装一个 _UserItem 组件,对条目进行显示。



Autocomplete 源码简看


Autocomplete 本质上依赖于 RawAutocomplete 组件进行构建,可见它是一层简单的封装,简化使用。为我们提供了默认的 optionsViewBuilderfieldViewBuilder,显示一个很丑的界面。也就是说,如果您了解如何定制这两部分内容,您也就会了 RawAutocomplete 组件。

我们先看一下 AutocompleteoptionsViewBuilder 提供的默认显示,其返回的是 _AutocompleteOptions 组件。如下,其实和我们自己实现的也没有太大的区别,只是个默认存在,方便使用的小玩意而已。

另外,对于输入框的构建,使用 _defaultFieldViewBuilder 静态方法完成。

该方法,返回 _AutocompleteField 组件,本质上也就是构建了一个 TextFormField 组件。


Autocomplete 来说,只是 RawAutocomplete 套了个马甲,本质上的功能还是在 RawAutocomplete 的状态类中完成的。如下是 _RawAutocompleteState 的部分代码,可以看出这里的浮层面板,是通过 Overlay 实现的,另外通过 CompositedTransformTargetCompositedTransformFollower 对浮层进行定位。

那本文就这样,如果想简单地实现搜索联想词,Autocomplete 是一个很不错的选择。




长按右侧二维码

查看更多开发者精彩分享




"开发者说·DTalk" 面向中国开发者们征集 Google 移动应用 (apps & games) 相关的产品/技术内容。欢迎大家前来分享您对移动应用的行业洞察或见解、移动开发过程中的心得或新发现、以及应用出海的实战经验总结和相关产品的使用反馈等。我们由衷地希望可以给这些出众的中国开发者们提供更好展现自己、充分发挥自己特长的平台。我们将通过大家的技术内容着重选出优秀案例进行谷歌开发技术专家 (GDE) 的推荐。



 

 点击屏末 |  | 即刻报名参与 "开发者说·DTalk" 




登录查看更多
0

相关内容

联想集团有限公司,是中国一家总部设在北京市和美国北卡罗莱纳州罗利市的跨国科技公司,成立于1984年,由中国科学院计算技术研究所投资20万元人民币、11名科技人员创办,当时称为“中国科学院计算所新技术发展公司”。1989年,更名为“北京联想计算机集团公司”。 维基百科
JCIM丨DRlinker:深度强化学习优化片段连接设计
专知会员服务
6+阅读 · 2022年12月9日
【2022新书】流畅C语言:原理,实践与模式,427页pdf
专知会员服务
66+阅读 · 2022年10月28日
专知会员服务
22+阅读 · 2021年9月20日
【2020新书】C++20快速语法参考,第4版,209页pdf
专知会员服务
71+阅读 · 2020年8月5日
流畅的Python 中英文版 PDF 高清电子书
专知会员服务
80+阅读 · 2020年8月2日
【电子书】Flutter实战305页PDF免费下载
专知会员服务
22+阅读 · 2019年11月7日
Flutter 组件集录: AppBar 的使用 | 开发者说·DTalk
谷歌开发者
0+阅读 · 2022年11月11日
探索 Flutter 模拟事件触发 | 开发者说·DTalk
谷歌开发者
5+阅读 · 2022年4月7日
如何理解 Flutter 路由源码设计?| 开发者说·DTalk
谷歌开发者
1+阅读 · 2022年1月28日
Flutter 如何与 Native (Android) 进行交互 | 开发者说·DTalk
Flutter 之美 | 开发者说·DTalk
谷歌开发者
1+阅读 · 2021年12月23日
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
2+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2011年12月31日
国家自然科学基金
0+阅读 · 2010年12月31日
国家自然科学基金
1+阅读 · 2009年12月31日
Arxiv
0+阅读 · 2022年12月19日
Arxiv
0+阅读 · 2022年12月16日
Arxiv
0+阅读 · 2022年12月15日
Arxiv
0+阅读 · 2022年12月13日
已删除
Arxiv
32+阅读 · 2020年3月23日
VIP会员
相关VIP内容
相关资讯
相关基金
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
2+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2011年12月31日
国家自然科学基金
0+阅读 · 2010年12月31日
国家自然科学基金
1+阅读 · 2009年12月31日
相关论文
Top
微信扫码咨询专知VIP会员