【Flutter 组件集录】Autocomplete 自动填充

这篇博客详细介绍了Flutter框架内的Autocomplete组件,包括其基本功能、选项构建、自定义样式以及泛型使用。通过示例代码展示了如何实现输入时的关键字联想、高亮显示和自定义输入框样式。此外,还探讨了Autocomplete组件的源码,揭示其依赖于RawAutocomplete组件,并提供了默认的视图构建器。最后,文章指出Autocomplete适用于快速实现搜索联想功能。

简单来说,Autocomplete 意为 自动填充 。其作用就是在输入时,进行 关键字联想。在输入框下方展示列表,如下所示:注意,这是目前 Flutter 框架内部的组件,非三方组件。

FlutterUnit 中输入时联想效果

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


1. 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);
} 

2. 自定义 Autocomplete 组件内容

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uaNszeVF-1653037333760)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fe5e956baeee40ec826f6d220f7f0dc3~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image)]


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

如下,代码中通过 _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 构建时,你可以指定自己需要的装饰。

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


3.关于 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 组件,对条目进行显示。


4、Autocomplete 源码简看

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


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


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

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



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

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

文末

我总结了一些Android核心知识点,以及一些最新的大厂面试题、知识脑图和视频资料解析。

需要的直接点击文末小卡片可以领取哦!我免费分享给你,以后的路也希望我们能一起走下去。(谢谢大家一直以来的支持,需要的自己领取)

Android学习PDF+架构视频+面试文档+源码笔记

部分资料一览:

  • 330页PDF Android学习核心笔记(内含8大板块)

  • Android学习的系统对应视频

  • Android进阶的系统对应学习资料

  • Android BAT大厂面试题(有解析)

领取地址:

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值