Flutter芯片输入自动完成插件chips_input_autocomplete的使用
Flutter芯片输入自动完成插件 chips_input_autocomplete
的使用
🚀 特性
- 动态芯片创建: 用户可以输入来动态创建芯片。适用于标签、联系人或任何分类。
- 自动完成建议: 根据预定义选项提供用户输入时的建议。
- 可定制外观: 完全控制芯片的外观,包括背景色、边框和文本颜色。
- 表单集成: 轻松与表单集成,允许验证和提交芯片数据。
- 广泛自定义: 除了样式,还可以自定义行为,如选择时添加芯片、限制选择等。
🏁 入门
要开始使用 chips_input_autocomplete
,请查看 安装 和 使用方法。详细的文档可以在 API 参考 中找到。
🛠️ 使用方法
要在 Flutter 项目中使用 chips_input_autocomplete
,请按照以下步骤操作:
基本芯片输入
此示例演示如何创建一个基本的芯片输入字段,用户可以输入来动态创建芯片。
const List<String> yourOptionsList = ['Option 1', 'Option 2', 'Option 3'];
ChipsInputAutocomplete(
options: yourOptionsList,
)
验证输入
仅允许匹配预定义选项的芯片。此示例使用验证方法确保只有有效选项被添加为芯片。
ChipsInputAutocomplete(
options: yourOptionsList,
validateInputMethod: (String? input) {
if (yourOptionsList.contains(input)) {
return null; // 输入有效
} else {
return '仅允许预定义的选项'; // 输入无效
}
},
)
获取芯片数据
使用控制器获取选中的芯片数据。
final ChipsAutocompleteController controller = ChipsAutocompleteController();
ChipsInputAutocomplete(
controller: controller,
)
// 获取选中的芯片数据
List<String> selectedChips = controller.chips; // selectedChips = ['Chiptext 1', 'Chiptext 2']
异步获取选项
使用控制器管理异步选项。此示例从 API 获取选项并设置在控制器中。
final ChipsAutocompleteController controller = ChipsAutocompleteController();
@override
void initState() {
getTagsOptions();
super.initState();
}
Future<void> getTagsOptions() async {
controller.options = await fetchTags();
}
ChipsInputAutocomplete(
controller: controller,
)
更多详细示例和用法,请参阅 pub.dev 示例。
⚙️ 使用示例
以下是 chips_input_autocomplete
小部件的各种配置和行为示例。当前的外观请参阅 pub.dev 示例。
🧷 参数
基本配置
controller
: 管理芯片、自动完成选项和文本字段。options
: 自动完成选项的字符串列表。也可以通过控制器设置。createCharacter
: 触发芯片创建的字符。默认为,
。placeChipsSectionAbove
: 确定芯片部分是否位于文本字段上方/左侧或下方/右侧。
芯片外观
secondaryTheme
: 当为true
时,使用次级主题的芯片。基于 Material Design 3 的选定芯片主题。chipTheme
: 芯片的主题。默认为 Material Design 3。更多详情请参阅 ChipThemeData。deleteIcon
: 删除芯片的图标。默认为关闭图标。可以设置为null
以移除。chipClipBehavior
: 芯片的裁剪行为。默认为Clip.none
。deleteButtonTooltipMessage
: 删除按钮的提示消息。默认为Delete
。
文本字段外观和配置
focusNode
: 文本字段的FocusNode
。decorationTextField
: 文本字段的样式。keyboardType
: 文本字段的键盘类型。enableSuggestions
: 是否显示建议。showCursor
: 是否显示光标。cursorWidth
: 光标的宽度。cursorColor
: 光标的颜色。cursorRadius
: 光标的半径。cursorHeight
: 光标的高度。
容器外观
widgetContainerDecoration
: 主小部件容器的装饰。paddingInsideWidgetContainer
: 主小部件容器内的填充。spacing
: 芯片之间的间距。默认为5.0
。runSpacing
: 芯片行之间的间距。如果未设置,默认为spacing
。optionsMaxWidth
: 选项视图的最大宽度。默认为文本字段的宽度。
其他配置
initialChips
: 初始显示的芯片。autoFocus
: 小部件是否自动聚焦。formKey
: 用于访问或验证表单外部的小部件的表单键。validateInputMethod
: 验证方法,返回字符串表示输入无效。null
表示始终有效。validateChipsMethod
: 验证方法,返回字符串表示所有芯片无效。null
表示始终有效。autovalidateMode
: 表单的自动验证模式。默认为AutovalidateMode.disabled
。enabled
: 小部件和文本字段是否启用。addChipOnSelection
: 选择选项时添加芯片。如果为false
,则将选项添加到文本字段。showClearButton
: 是否显示清除IconButton
。clearWithConfirm
: 清除所有芯片时是否显示确认对话框。eraseKeyLabel
: 用于删除芯片的键标签。默认为退格键。showOnlyUnselectedOptions
: 是否仅显示未选择的选项。默认为true
。
回调和事件处理
onChanged
: 芯片值更改时的回调。onChangedTextField
: 文本字段更改时的回调。onEditingComplete
: 编辑完成时的回调。onSaved
: 表单保存时的回调。onChipDeleted
: 芯片删除时的回调,包含芯片内容和索引。onChipAdded
: 芯片添加时的回调,包含芯片内容。onChipsCleared
: 所有芯片清除时的回调。useDefaultOnChipDeleted
: 是否使用默认的onChipDeleted
方法。可以设置为false
以实现不同的逻辑。例如,当芯片从不同来源更新时。useDefaultOnChipAdded
: 是否使用默认的onChipAdded
方法。可以设置为false
以实现不同的逻辑。例如,当芯片从不同来源更新时。useDefaultOnChipsCleared
: 是否使用默认的onChipsCleared
方法。可以设置为false
以实现不同的逻辑。例如,当芯片从不同来源更新时。
🧑💻 作者
示例代码
以下是一个完整的示例代码,展示了如何在 Flutter 应用中使用 chips_input_autocomplete
插件。
/*
@Author: Johannes Pauli
@License: MIT
*/
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:chips_input_autocomplete/chips_input_autocomplete.dart';
void main() {
runApp(const FlutterDemo());
}
class FlutterDemo extends StatelessWidget {
const FlutterDemo({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final ChipsAutocompleteController controllerExampleBasic =
ChipsAutocompleteController();
String chipsOutputExampleBasic = '';
final ChipsAutocompleteController controllerExampleSecondaryTheme =
ChipsAutocompleteController();
String chipsOutputExampleSecondaryTheme = '';
final ChipsAutocompleteController controllerExampleInsertOnSelect =
ChipsAutocompleteController();
String chipsOutputExampleInsertOnSelect = '';
final ChipsAutocompleteController controllerExampleOnlyOptions =
ChipsAutocompleteController();
String chipsOutputExampleOnlyOptions = '';
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
controllerExampleBasic.addListener(() {
setState(() {
chipsOutputExampleBasic = controllerExampleBasic.chips.join(', ');
});
});
controllerExampleSecondaryTheme.addListener(() {
setState(() {
chipsOutputExampleSecondaryTheme =
controllerExampleSecondaryTheme.chips.join(', ');
});
});
controllerExampleInsertOnSelect.addListener(() {
setState(() {
chipsOutputExampleInsertOnSelect =
controllerExampleInsertOnSelect.chips.join(', ');
});
});
controllerExampleOnlyOptions.addListener(() {
setState(() {
chipsOutputExampleOnlyOptions =
controllerExampleOnlyOptions.chips.join(', ');
});
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Chips Input Autocomplete Demo'),
),
body: Center(
child: SingleChildScrollView(
child: Column(
children: [
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 500),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: Text(
'Basic Example',
style: Theme.of(context).textTheme.titleLarge,
),
),
),
Text('Options: ${options.join(', ')}'),
ChipsInputAutocomplete(
controller: controllerExampleBasic,
options: options,
),
Text('Selected: $chipsOutputExampleBasic'),
],
),
),
),
),
const SizedBox(height: 16),
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 500),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: Text(
'Secondary Theme',
style: Theme.of(context).textTheme.titleLarge,
),
),
),
Text('Options: ${options.join(', ')}'),
ChipsInputAutocomplete(
controller: controllerExampleSecondaryTheme,
options: options,
secondaryTheme: true,
),
Text('Selected: $chipsOutputExampleSecondaryTheme'),
],
),
),
),
),
const SizedBox(height: 16),
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 500),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: Text(
'Add on selection',
style: Theme.of(context).textTheme.titleLarge,
),
),
),
Text('Options: ${options.join(', ')}'),
ChipsInputAutocomplete(
controller: controllerExampleInsertOnSelect,
options: options,
addChipOnSelection: true,
),
Text('Selected: $chipsOutputExampleInsertOnSelect'),
],
),
),
),
),
const SizedBox(height: 16),
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 500),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: Text(
'Only options allowed',
style: Theme.of(context).textTheme.titleLarge,
),
),
),
Text('Options: ${options.join(', ')}'),
ChipsInputAutocomplete(
controller: controllerExampleOnlyOptions,
options: options,
validateInputMethod: (String? input) {
if (options.contains(input)) {
return null; // 输入有效
} else {
return '仅允许预定义的选项'; // 输入无效
}
},
),
Text('Selected: $chipsOutputExampleOnlyOptions'),
],
),
),
),
),
const SizedBox(height: 16),
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 500),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: Text(
'Async fetched options',
style: Theme.of(context).textTheme.titleLarge,
),
),
),
FutureBuilder<List<String>>(
future: fetchTags(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return ChipsInputAutocomplete(
controller: controllerExampleBasic,
options: snapshot.data ?? [],
);
}
},
),
],
),
),
),
),
],
),
),
),
);
}
Future<List<String>> fetchTags() async {
// 模拟从 API 获取选项
await Future.delayed(Duration(seconds: 2));
return ['Option 1', 'Option 2', 'Option 3'];
}
}
希望这些示例和说明能帮助你更好地理解和使用 chips_input_autocomplete
插件!如果有任何问题或需要进一步的帮助,请随时提问。
更多关于Flutter芯片输入自动完成插件chips_input_autocomplete的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter芯片输入自动完成插件chips_input_autocomplete的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,我可以为你提供一个关于如何在Flutter中使用chips_input_autocomplete
插件的示例代码。这个插件允许你在Flutter应用中实现带有自动完成功能的芯片输入(chips input)。
首先,你需要在你的pubspec.yaml
文件中添加这个插件的依赖:
dependencies:
flutter:
sdk: flutter
chips_input_autocomplete: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter应用中,你可以按照以下方式使用这个插件:
import 'package:flutter/material.dart';
import 'package:chips_input_autocomplete/chips_input_autocomplete.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Chips Input Autocomplete Example',
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',
'Kiwi',
'Lemon'
];
List<String> chips = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Chips Input Autocomplete Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: ChipsInputAutocomplete<String>(
decoration: InputDecoration(
labelText: 'Select fruits',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.text,
suggestions: suggestions,
onChipSubmitted: (chip) {
setState(() {
chips.add(chip);
});
},
onChipDeleted: (chip, index) {
setState(() {
chips.removeAt(index);
});
},
chipBuilder: (context, state, chip) {
return Chip(
label: Text(chip),
onDelete: () => state.deleteChip(chip),
);
},
initialValue: chips,
findSuggestions: (String query) {
if (query.isEmpty) {
return [];
}
return suggestions.where((p) => p.toLowerCase().contains(query.toLowerCase())).toList();
},
),
),
);
}
}
这个示例代码展示了如何使用chips_input_autocomplete
插件来实现一个带有自动完成功能的芯片输入组件。以下是代码的关键点:
- 依赖项:在
pubspec.yaml
文件中添加chips_input_autocomplete
插件的依赖项。 - 状态管理:在
_MyHomePageState
类中管理芯片列表的状态。 - 芯片输入组件:使用
ChipsInputAutocomplete
组件来创建芯片输入区域。 - 建议列表:通过
suggestions
属性提供自动完成的建议列表。 - 提交和删除芯片:通过
onChipSubmitted
和onChipDeleted
回调函数来处理芯片的提交和删除。 - 芯片构建:使用
chipBuilder
属性来定制芯片的外观。 - 自动完成逻辑:通过
findSuggestions
回调函数来实现自动完成的逻辑。
希望这个示例代码能帮助你更好地理解如何在Flutter中使用chips_input_autocomplete
插件。