
《Flutter TolyUI 框架》系列前言:
TolyUI 是 张风捷特烈 打造的 Fluter 全平台应用开发 UI 框架。具备 全平台 、组件化 、源码开放 、响应式 四大特点。可以帮助开发者迅速构建具有响应式全平台应用软件:

1. 标签组件的设计动机
在应用开发中,标签是一种常见的界面元素,用于分类标记、状态展示、筛选条件等场景。一个好的标签组件不仅要有美观的视觉效果,更要提供灵活的交互能力。从简单的静态展示到复杂的动态管理,从单一的样式到多样的变体,标签组件承载着丰富的功能需求。

TolyUI 的 tolyui_tag 模块正是为此而设计。它不仅提供了基础的标签展示能力,还支持可关闭、可选择、动态添加等高级功能。通过合理的 API 设计和灵活的配置选项,让开发者能够轻松应对各种标签使用场景。其中包含两个核心组件:
- TolyTag 展示独立的标签,可以设置标签类型、是否可关闭等。
- TolyTagGroup 展示标签组,可以支持单选、多选等功能。
使用者可以独立引入模块包,或者使用 tolyui 全家桶:
yaml
# 仅使用 tolyui_tag
dependencies:
tolyui_tag: ^last_version
# 使用 tolyui 全家桶
dependencies:
tolyui: ^last_version
下面来介绍相关组件的具体用法。
2. 基础标签展示
最基本的用法是使用 Tag 组件展示静态标签。组件支持不同的颜色和变体样式,通过简单的配置就能实现丰富的视觉效果。
第一行展示了不同颜色的标签效果,通过 color 属性可以快速设置标签的主题色。第二行展示了四种变体样式:填充、边框、实心、虚线。每种样式都有其独特的视觉特征,适用于不同的使用场景。

dart
// 不同颜色的标签
TolyTag(child: Text('默认样式'))
TolyTag(color: Colors.red, child: Text('红色 red'))
TolyTag(color: Colors.purple, child: Text('紫色 purple'))
TolyTag(color: Colors.green, child: Text('绿色 green'))
// 不同变体的标签
TolyTag(variant: TagVariant.filled, color: Colors.blue, child: Text('填充 filled'))
TolyTag(variant: TagVariant.outlined, color: Colors.green, child: Text('边框 outlined'))
TolyTag(variant: TagVariant.solid, color: Colors.orange, child: Text('实心 TolyTag'))
TolyTag(variant: TagVariant.dashed, color: Colors.grey, child: Text('虚线 dashed'))
通过颜色和样式的组合,可以灵活应用于分类标记、状态展示、标签管理等场景。
3. 可关闭标签
在实际应用中,标签往往需要支持动态删除。Tag 组件通过 closable 属性提供了关闭功能,配合 onClose 回调可以实现完整的删除交互。

基于数据驱动的方式,可以轻松实现标签的动态管理。每个标签都可以独立关闭删除,点击关闭按钮后标签从列表中移除并显示提示信息。当有标签被删除时,右侧会出现重置标签,点击可恢复所有已删除的标签。
dart
class _TagDemo2State extends State<TagDemo2> {
final List<TagData> _initialTags = [
TagData(label: '编程技术', variant: TagVariant.outlined),
TagData(label: '拍摄影像', icon: Icons.camera, color: Colors.green),
TagData(label: 'Dart语言', icon: Icons.code, variant: TagVariant.outlined),
TagData(label: '禁用状态', variant: TagVariant.filled, disabled: true),
];
late List<TagData> tags;
@override
void initState() {
super.initState();
tags = List.from(_initialTags);
}
@override
Widget build(BuildContext context) {
return Wrap(
spacing: 8,
runSpacing: 8,
children: [
...tags.map((tag) {
return TolyTag(
variant: tag.variant,
closable: true,
disabled: tag.disabled,
color: tag.color,
icon: tag.icon != null ? Icon(tag.icon, size: 14) : null,
onClose: () {
setState(() => tags.remove(tag));
$message.success(message: '已删除: ${tag.label}');
},
child: Text(tag.label),
);
}),
if (tags.length < _initialTags.length)
GestureDetector(
onTap: () {
setState(() => tags = List.from(_initialTags));
$message.success(message: '已重置所有标签');
},
child: TolyTag(
variant: TagVariant.filled,
color: Colors.blue,
icon: Icon(Icons.refresh, size: 14),
child: Text('重置'),
),
),
],
);
}
}
这种数据驱动的模式让标签管理变得简单而优雅,示例包含了不同样式、颜色、图标的标签组合,以及禁用状态的展示,适用于标签管理、筛选条件、关键词编辑等需要动态增删的交互场景。
4. 动态添加标签
除了删除,标签的动态添加也是常见需求。通过结合输入框和标签组件,可以实现完整的标签增删功能。

用户可以通过关闭按钮删除已有标签,也可以点击虚线边框的添加按钮创建新标签。点击添加后会出现输入框,输入内容并回车或失焦即可完成添加。新标签会自动去重和去除空白,确保标签列表的整洁性。
dart
class _TagDemo3State extends State<TagDemo3> {
List<String> tags = ['上进', '努力', '成功', '创新', '热情'];
bool _isAdding = false;
final TextEditingController _tagInputController = TextEditingController();
final FocusNode _tagInputFocusNode = FocusNode();
void _handleSubmitted(String value) {
setState(() {
final newTag = value.trim();
if (newTag.isNotEmpty && !tags.contains(newTag)) {
tags.add(newTag);
}
_isAdding = false;
_tagInputController.clear();
});
}
@override
Widget build(BuildContext context) {
return Wrap(
spacing: 8,
runSpacing: 8,
children: [
...tags.map((tag) {
return TolyTag(
closable: true,
color: Colors.blue,
onClose: () => setState(() => tags.remove(tag)),
child: Text(tag),
);
}),
if (_isAdding)
SizedBox(
width: 90,
height: 24,
child: TextField(
controller: _tagInputController,
focusNode: _tagInputFocusNode,
onSubmitted: _handleSubmitted,
),
)
else
Tag(
variant: TagVariant.dashed,
onTap: () {
setState(() => _isAdding = true);
_tagInputFocusNode.requestFocus();
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.add, size: 14),
SizedBox(width: 4),
Text('添加标签'),
],
),
),
],
);
}
}
这种交互模式常用于个人信息编辑、兴趣标签管理、技能标签设置等需要用户自定义标签内容的场景。
5. 可选择标签
对于筛选和分类场景,标签需要支持选择功能。TolyUI 提供了 TolyTagGroup 组件,支持单选和多选两种模式。

单选模式下,点击标签会取消其他标签的选中状态,只保留当前选中项。多选模式下,可以同时选中多个标签。每个模式都实时显示当前选中的内容,提供直观的视觉反馈。
dart
class _TagDemo4State extends State<TagDemo4> {
String? selectedCategory;
List<String> selectedTags = [];
@override
Widget build(BuildContext context) {
const TextStyle style = TextStyle(fontSize: 14,fontWeight: FontWeight.bold);
const TextStyle greyStyle = TextStyle(fontSize: 12,color: Colors.grey);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Wrap(
children: [
const Text('单选模式:',style: style),
const SizedBox(height: 8),
Text('已选择:${selectedCategory ?? "无"}',style: greyStyle),
],
),
const SizedBox(height: 8),
TolyTagGroup<String>(
options: const [
TagOption(value: 'frontend', label: Text('前端')),
TagOption(value: 'backend', label: Text('后端')),
TagOption(value: 'mobile', label: Text('移动端')),
TagOption(value: 'ai', label: Text('人工智能')),
],
value: selectedCategory,
onChange: (value) => setState(() => selectedCategory = value),
),
const SizedBox(height: 24),
Wrap(
children: [
const Text('多选模式:',style: style),
const SizedBox(height: 8),
Text('已选择:${selectedTags.isEmpty ? "无" : selectedTags.join(", ")}',style: greyStyle),
],
),
const SizedBox(height: 8),
TolyTagGroup<String>(
multiple: true,
options: const [
TagOption(value: 'flutter', label: Text('Flutter')),
TagOption(value: 'react', label: Text('React')),
TagOption(value: 'vue', label: Text('Vue')),
TagOption(value: 'angular', label: Text('Angular')),
TagOption(value: 'nodejs', label: Text('Node.js')),
],
values: selectedTags,
onChangeMultiple: (values) => setState(() => selectedTags = values),
),
],
);
}
}
示例中单选用于技术方向选择,多选用于技术栈选择。这种交互模式广泛应用于筛选器、分类选择、问卷调查、偏好设置等需要用户选择的场景。
6. 状态标签
在系统中,标签常用于展示各种状态信息。通过不同的颜色和图标组合,可以直观地传达状态含义。

TolyUI 的 TolyTag 组件支持自定义图标,配合合适的颜色,可以创建出语义明确的状态标签。示例包含六种常见状态:成功、错误、警告、信息、等待中、处理中。每个状态都采用了符合直觉的颜色和图标搭配,特别是处理中状态使用了动态的加载指示器,提供更生动的视觉反馈。
dart
const TolyTag(
icon: Icon(Icons.check_circle, size: 12, color: Colors.green),
color: Colors.green,
child: Text('成功'),
)
const TolyTag(
icon: Icon(Icons.error, size: 12, color: Colors.red),
color: Colors.red,
child: Text('错误'),
)
const TolyTag(
icon: Icon(Icons.warning, size: 12, color: Colors.orange),
color: Colors.orange,
child: Text('警告'),
)
const TolyTag(
icon: Icon(Icons.info, size: 12, color: Colors.blue),
color: Colors.blue,
child: Text('信息'),
)
const TolyTag(
icon: Icon(Icons.schedule, size: 12, color: Colors.grey),
color: Colors.grey,
child: Text('等待中'),
)
const TolyTag(
icon: CupertinoActivityIndicator(color: Colors.purple, radius: 6),
color: Colors.purple,
child: Text('处理中'),
)
这种模式广泛应用于任务状态跟踪、审批流程、订单状态、系统通知等需要明确状态表达的场景。
尾声
toly_tag 模块为 Flutter 应用提供了完整的标签展示和交互能力。从基础的静态展示到动态的增删管理,从单一的样式配置到丰富的状态表达,它都能够胜任。无论你是在构建内容管理系统,还是开发社交应用,这个组件都能帮助你创建出既美观又实用的标签界面。
随着 tolyui 的逐步迭代,越来越多的新功能将会支持。感谢你关注 tolyui 的成长,如果喜欢,也希望你能在 github 中点赞支持~
github 开源地址: github.com/TolyFx/toly...
更多文章和视频知识资讯,大家可以关注我的公众号、掘金和 B 站 。让我们一起成长,变得更强。我们下次再见~