Flutter多触发自动补全插件multi_trigger_autocomplete的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter多触发自动补全插件multi_trigger_autocomplete的使用

简介

multi_trigger_autocomplete 是一个用于在Flutter应用中添加基于触发符的自动补全功能的插件。通过此插件,您可以轻松实现类似社交平台的消息输入框中常见的@提及、#话题和:表情符号等功能。

安装

在您的 pubspec.yaml 文件中添加以下依赖,并将 [version] 替换为最新版本号:

dependencies:
  multi_trigger_autocomplete: ^[version]

安装完成后,请确保在项目根目录下运行 flutter pub get 来更新依赖包。

使用方法

要使用这个插件,您需要首先在应用程序的最顶层包裹 Portal 组件,因为该插件依赖于 flutter_portal 包来显示选项视图。以下是基本的使用步骤:

导入包

在 Dart 文件顶部导入必要的库:

import 'package:multi_trigger_autocomplete/multi_trigger_autocomplete.dart';

创建 MultiTriggerAutocomplete 组件

接下来,在需要的地方创建并配置 MultiTriggerAutocomplete 组件。这里提供了一个完整的示例代码,它展示了如何结合聊天界面使用此组件:

import 'package:flutter/material.dart';
import 'package:multi_trigger_autocomplete/multi_trigger_autocomplete.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Portal(
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final TextEditingController _controller = TextEditingController();
  final FocusNode _focusNode = FocusNode();

  @override
  void dispose() {
    _controller.dispose();
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Multi Trigger Autocomplete'),
      ),
      body: Column(
        children: [
          Expanded(child: Container()), // 这里可以放置聊天记录列表
          MultiTriggerAutocomplete(
            optionsAlignment: OptionsAlignment.topStart,
            autocompleteTriggers: [
              AutocompleteTrigger(
                trigger: '@',
                optionsViewBuilder: (context, query, controller) {
                  return ListView.builder(
                    itemCount: users.length,
                    itemBuilder: (context, index) {
                      final user = users[index];
                      if (user.startsWith(query.query)) {
                        return ListTile(
                          title: Text(user),
                          onTap: () {
                            final autocomplete = MultiTriggerAutocomplete.of(context);
                            autocomplete.acceptAutocompleteOption(user);
                          },
                        );
                      } else {
                        return const SizedBox.shrink();
                      }
                    },
                  );
                },
              ),
              AutocompleteTrigger(
                trigger: '#',
                optionsViewBuilder: (context, query, controller) {
                  return ListView.builder(
                    itemCount: hashtags.length,
                    itemBuilder: (context, index) {
                      final hashtag = hashtags[index];
                      if (hashtag.startsWith(query.query)) {
                        return ListTile(
                          title: Text(hashtag),
                          onTap: () {
                            final autocomplete = MultiTriggerAutocomplete.of(context);
                            autocomplete.acceptAutocompleteOption(hashtag);
                          },
                        );
                      } else {
                        return const SizedBox.shrink();
                      }
                    },
                  );
                },
              ),
              AutocompleteTrigger(
                trigger: ':',
                optionsViewBuilder: (context, query, controller) {
                  return GridView.count(
                    crossAxisCount: 5,
                    children: emojis.map((emoji) {
                      if (emoji.startsWith(query.query)) {
                        return GestureDetector(
                          child: Center(child: Text(emoji)),
                          onTap: () {
                            final autocomplete = MultiTriggerAutocomplete.of(context);
                            autocomplete.acceptAutocompleteOption(
                              emoji,
                              keepTrigger: false,
                            );
                          },
                        );
                      } else {
                        return const SizedBox.shrink();
                      }
                    }).toList(),
                  );
                },
              ),
            ],
            fieldViewBuilder: (context, controller, focusNode) {
              return Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextField(
                  controller: controller,
                  focusNode: focusNode,
                  decoration: InputDecoration(
                    labelText: 'Type something...',
                    border: OutlineInputBorder(),
                  ),
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}

// 示例数据
final List<String> users = ['Alice', 'Bob', 'Charlie'];
final List<String> hashtags = ['#flutter', '#dart', '#mobiledev'];
final List<String> emojis = [':)', ':(', ':D', ';)', ':P'];

在这个例子中,我们定义了三个触发字符:@#:,分别对应用户提及、话题标签和表情符号的选择。每个触发字符都有对应的选项视图构建器 (optionsViewBuilder),它决定了当检测到相应触发字符时应该显示哪些内容。

此外,我们还设置了 fieldViewBuilder 属性来自定义文本输入框的外观。在这个例子中,我们简单地使用了 TextField,但您可以根据需求对其进行进一步定制。

请注意,为了使代码更简洁易读,上述示例中的用户、话题和表情符号列表都是静态的。实际应用中,您可能需要从网络或本地数据库获取这些数据。

自定义与扩展

除了基本用法外,MultiTriggerAutocomplete 还提供了许多可配置参数以满足不同场景下的需求。例如,您可以调整选项视图的位置、宽度比例等属性;也可以设置延迟时间来优化性能。有关更多细节,请参阅官方文档。

如果您希望对默认行为进行更大程度上的修改,则可以通过继承 AutocompleteTrigger 类并重写相关方法来实现。这允许您完全控制触发逻辑以及如何呈现和处理用户选择的结果。

总之,multi_trigger_autocomplete 插件为开发者提供了一种强大且灵活的方式来增强Flutter应用中的文本输入体验。无论是在聊天应用还是其他类型的交互式UI设计中,它都能发挥重要作用。


更多关于Flutter多触发自动补全插件multi_trigger_autocomplete的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter多触发自动补全插件multi_trigger_autocomplete的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用multi_trigger_autocomplete插件的示例代码。这个插件允许你在Flutter应用中实现多触发自动补全功能。假设你已经将这个插件添加到了你的pubspec.yaml文件中:

dependencies:
  flutter:
    sdk: flutter
  multi_trigger_autocomplete: ^最新版本号  # 请替换为实际版本号

然后运行flutter pub get来安装插件。

以下是一个完整的示例,展示如何使用multi_trigger_autocomplete

import 'package:flutter/material.dart';
import 'package:multi_trigger_autocomplete/multi_trigger_autocomplete.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Multi Trigger Autocomplete Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<String> suggestions = [
    'Apple',
    'Banana',
    'Cherry',
    'Date',
    'Elderberry',
    'Fig',
    'Grape',
    'Honeydew',
    'Indian Fig',
    'Jackfruit',
  ];

  final TextEditingController controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Multi Trigger Autocomplete Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: [
            MultiTriggerAutocomplete<String>(
              controller: controller,
              suggestions: suggestions,
              onSuggestionSelected: (suggestion) {
                // 当用户选择一个建议时触发
                print('Selected: $suggestion');
              },
              suggestionTriggerMode: AutocompleteSuggestionTriggerMode.alwaysVisible,
              displayStringForOption: (option) => option,
              optionsBuilder: (TextEditingController textEditingController) {
                if (textEditingController.text == "") {
                  return [];
                }
                return suggestions
                    .where((String option) =>
                        option.toLowerCase().contains(
                            textEditingController.text.toLowerCase()))
                    .toList();
              },
              fieldViewBuilder: (
                BuildContext context,
                TextEditingController textEditingController,
                FocusNode focusNode,
                VoidCallback onEditingComplete,
              ) {
                return TextField(
                  controller: textEditingController,
                  focusNode: focusNode,
                  decoration: InputDecoration(
                    prefixIcon: Icon(Icons.search),
                    labelText: 'Search',
                    suffixIcon: IconButton(
                      icon: Icon(Icons.clear),
                      onPressed: () {
                        textEditingController.clear();
                        focusNode.unfocus();
                      },
                    ),
                  ),
                  onEditingComplete: onEditingComplete,
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

代码解释

  1. 依赖项:在pubspec.yaml文件中添加multi_trigger_autocomplete依赖项。

  2. 状态管理:使用StatefulWidget来管理文本编辑器的状态。

  3. 建议列表:定义一个字符串列表suggestions,其中包含自动补全的建议。

  4. 文本编辑器控制器:使用TextEditingController来控制文本输入。

  5. MultiTriggerAutocomplete

    • controller:绑定到文本编辑器控制器。
    • suggestions:提供自动补全的建议列表。
    • onSuggestionSelected:当用户选择一个建议时调用的回调。
    • suggestionTriggerMode:设置建议的触发模式,这里使用alwaysVisible,表示建议始终可见。
    • displayStringForOption:定义如何显示建议项。
    • optionsBuilder:根据用户输入构建过滤后的建议列表。
    • fieldViewBuilder:自定义文本字段视图,包括前缀图标、标签文本和后缀图标(清除按钮)。

这段代码提供了一个基本的实现,你可以根据需要进行进一步的定制和扩展。

回到顶部