Flutter TolyUI 框架#11 | 标签 tolyui_tag

《Flutter TolyUI 框架》系列前言:

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

开源地址: github.com/TolyFx/toly...


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 站 。让我们一起成长,变得更强。我们下次再见~

相关推荐
晚霞的不甘1 小时前
[鸿蒙2025领航者闯关]: Flutter + OpenHarmony 安全开发实战:从数据加密到权限管控的全链路防护
安全·flutter·harmonyos
松☆1 小时前
创建混合工程:OpenHarmony Stage 模型 + Flutter 模块标准结构详解
flutter
梵得儿SHI1 小时前
Vue 核心语法深度解析:生命周期与响应式之计算属性(computed)与侦听器(watch/watchEffect)
前端·javascript·vue.js·计算属性·侦听器·缓存机制·数据派生
小白|1 小时前
【OpenHarmony × Flutter】混合开发高阶实战:如何统一管理跨平台状态?Riverpod + ArkTS 共享数据流架构详解
flutter·架构
anuoua1 小时前
歼20居然是个框架-基于 Signals 信号的前端框架设计
前端·javascript·前端框架
秋天的一阵风1 小时前
翻掘金看到停更的前辈们,突然想聊两句 🤔
前端·vue.js·程序员
中杯可乐多加冰1 小时前
openEuler软件生态体验:快速部署Nginx Web服务器
服务器·前端·nginx
拾忆,想起1 小时前
Dubbo服务降级全攻略:构建韧性微服务系统的守护盾
java·前端·网络·微服务·架构·dubbo
我爱学习_zwj1 小时前
Node.js模块管理:CommonJS vs ESModules
开发语言·前端·javascript