前语

在许多 App 中,当用户输入查找内容时,往往会主动匹配一些候选查找内容,以便让用户快速完成查找内容的输入。一起,也能够在候选的查找内容中依据用户偏好“加塞”广告,前进成交转化率。比方在淘宝查找“苹果”这个词时,就会出现苹果相关的候选选项。相似这样的功能就需求用到输入内容的主动填充。

淘宝App的搜索推荐如何用Flutter实现?

这种功能能够自己去写两个独立的组件,比方一个查找框,一个候选内容弹层,通过内容联动来实现。不过,Flutter 中其实有自带的组件,叫做 AutoComplete

AutoComplete 简介

AutoComplete是一个泛型类,组件界说如下。

class Autocomplete<T extends Object> extends StatelessWidget {
  const Autocomplete({
    super.key,
    required this.optionsBuilder,
    this.displayStringForOption = RawAutocomplete.defaultStringForOption,
    this.fieldViewBuilder = _defaultFieldViewBuilder,
    this.onSelected,
    this.optionsMaxHeight = 200.0,
    this.optionsViewBuilder,
    this.initialValue,
  });
  //……

其中泛型指的是候选内容目标的类型,最简单的便是 String 类型,可是咱们后台返回的或许会是一个完整的目标,这个时分咱们就能够界说为后台目标对应的实体类。详细的参数说明如下:

  • optionsBuilder:选项结构器,实际上便是匹配的规则,咱们能够依据用户输入的内容去做二次处理,比方含糊匹配用户输入的内容。
  • displayStringForOption:后续内容怎么显现,一般会显现称号、标题之类的内容,也能够依据需求自界说显现内容,例如地址就能够将省市区和详细地址拼接起来。
  • fieldViewBuilder:输入框的构建函数,这个函数需求返回一个输入框供用户输入,输入框款式能够自界说。
  • onSelected:选中候选内容项的回调,一般咱们会在这个办法里触发查找恳求。
  • optionsMaxHeight:候选项弹层的最大高度,超越这个高度后能够翻滚。
  • optionsViewBuilder:候选项的弹层组件的构建函数,默许是运用 Material 风格的下拉列表视图组件,也能够自界说候选弹层的组件。
  • initialValue:初始值,比方依据用户近期阅读记载引荐一个候选的初始值。

实际使用

下面咱们以一个输入国家检索的使用为例,咱们准备了一个Country类,其中有idname字段。当检测到国家称号匹配用户输入的文字时,就会挑选出候选的国家,然后简化用户的输入进程。例如,用户输入“中”字,就会把“我国”这个候选项挑选出来。相似的场景也能够用于产品查找引荐、支持输入的下拉框等等。实现的作用如下图所示。

淘宝App的搜索推荐如何用Flutter实现?

示例代码如下:

class AutoCompleteDemo extends StatefulWidget {
  const AutoCompleteDemo({super.key});
  @override
  // ignore: library_private_types_in_public_api
  _AutoCompleteDemoState createState() => _AutoCompleteDemoState();
}
class _AutoCompleteDemoState extends State<AutoCompleteDemo> {
  final List<Country> countries = [
    Country(id: 1, name: '我国'),
    Country(id: 2, name: '美国'),
    Country(id: 3, name: '印度'),
    Country(id: 4, name: '俄罗斯'),
    Country(id: 5, name: '英国'),
    Country(id: 6, name: '巴西'),
    Country(id: 7, name: '法国'),
    Country(id: 8, name: '德国'),
  ];
  var selectedCountry = '';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('AutoComplete Demo'),
      ),
      body: Center(
        child: Autocomplete<Country>(
          optionsBuilder: (TextEditingValue textEditingValue) {
            return Future.delayed(const Duration(milliseconds: 2000), () {
              return countries
                  .where(
                      (country) => country.name.contains(textEditingValue.text))
                  .toList();
            });
          },
          onSelected: (Country country) {
            selectedCountry = country.name;
          },
          fieldViewBuilder: (BuildContext context,
              TextEditingController textEditingController,
              FocusNode focusNode,
              VoidCallback onFieldSubmitted) {
            return TextField(
              controller: textEditingController,
              focusNode: focusNode,
              onChanged: (text) {
                selectedCountry = text;
              },
              decoration: const InputDecoration(
                labelText: '国家',
              ),
            );
          },
          displayStringForOption: (Country country) =>
              '[${country.id}] ${country.name}',
          initialValue: TextEditingValue(text: selectedCountry),
        ),
      ),
    );
  }
}
class Country {
  final int id;
  final String name;
  Country({required this.id, required this.name});
}

这儿咱们运用了Country这个类作为AutoComplete的泛型参数,这样就能够支持对Country列表数据进行处理了。详细的逻辑说明如下:

  • optionsBuilder:咱们采用了一个Future延时来模仿后台数据恳求,当然,如果选项数据是固定的,能够进入页面的时分一次恳求好就行。如果是要后台合作查找的,那么每次输入都能够恳求匹配的候选数据。这儿实际处理便是挑选出国家称号中包含用户输入内容的列表。
  • onSelected:选中后的操作,这儿仅仅更新选项值,实际如果是查找产品就能够直接携带查找关键词跳转到查找结果页面。
  • fieldViewBuilder:这儿用于构建一个输入框,输入框的款式能够依据自己需求界说。如果要单独控制输入框,比方输入内容,获取焦点等,能够界说一个TextEditingController目标和FocusNode目标来存储回调函数的textEditingControllerfocusNode。这两个参数是在AutoComplete类里边界说的。
  • displayStringForOption:候选项的显现(包含选中后的文本框),这种能够用于将一个目标的几个字符串拼接起来,例如前面讲到的地址,这儿咱们演示是将idname拼接起来了。
  • initialValue:输入框的初始值,如果是产品查找,能够依据用户近期的阅读记载(或广告追踪记载)展示引荐的查找内容,这个在电商App经常看到。

我是岛上码农,微信公众号同名。如有问题能够加本人微信沟通,微信号:island-coder

:觉得有收成请点个赞鼓舞一下!

:保藏文章,便利回看哦!

:评论沟通,相互前进!