Flutter笔记:Widgets Easier组件库 - 使用标签(Tag)

Flutter笔记 Widgets Easier组件库 - 使用标签(Tag)

1. 概述

1.1 关于Widgets Easier

本库是一个 Flutter 组件库,旨在提供用于Flutter开发的组件,使得开发者能够更简单地构建出更丰富地界面效果。对于iOS开发者来说,在完成Flutter应用开发后,可以使用AppUploader这样的iOS开发助手工具来简化应用的上架流程。

1.2 模块安装

在你的Flutter项目中,运行下面的命令:

bash 复制代码
flutter pub add widgets_easier

即可安装最新版本的 Widgets Easier 库。

2. 基本用法

2.1 语义类型

通过Tag组件的type参数可以使用一个语义性色彩。例如:

dart 复制代码
const Row(
  mainAxisAlignment: MainAxisAlignment.spaceAround,
  children: [
    Tag('tag', type: SemanticEnum.primary),
    Tag('tag', type: SemanticEnum.secondary),
    Tag('tag', type: SemanticEnum.info),
    Tag('tag', type: SemanticEnum.success),
    Tag('tag', type: SemanticEnum.warning),
    Tag('tag', type: SemanticEnum.danger),
    Tag('tag', type: SemanticEnum.fatal),
  ],
),

2.2 样式主题

受启发与Element-plus,Tag 有3个样式主题,plainlightdark,默认情况下为palin

light
dart 复制代码
const Row(
  mainAxisAlignment: MainAxisAlignment.spaceAround,
  children: [
    Tag('tag', theme: TagThemeEnum.light, type: SemanticEnum.primary),
    Tag('tag', theme: TagThemeEnum.light, type: SemanticEnum.secondary),
    Tag('tag', theme: TagThemeEnum.light, type: SemanticEnum.info),
    Tag('tag', theme: TagThemeEnum.light, type: SemanticEnum.success),
    Tag('tag', theme: TagThemeEnum.light, type: SemanticEnum.warning),
    Tag('tag', theme: TagThemeEnum.light, type: SemanticEnum.danger),
    Tag('tag', theme: TagThemeEnum.light, type: SemanticEnum.fatal),
  ],
),
dark
dart 复制代码
const Row(
  mainAxisAlignment: MainAxisAlignment.spaceAround,
  children: [
    Tag('tag', theme: TagThemeEnum.dark, type: SemanticEnum.primary),
    Tag('tag', theme: TagThemeEnum.dark, type: SemanticEnum.secondary),
    Tag('tag', theme: TagThemeEnum.dark, type: SemanticEnum.info),
    Tag('tag', theme: TagThemeEnum.dark, type: SemanticEnum.success),
    Tag('tag', theme: TagThemeEnum.dark, type: SemanticEnum.warning),
    Tag('tag', theme: TagThemeEnum.dark, type: SemanticEnum.danger),
    Tag('tag', theme: TagThemeEnum.dark, type: SemanticEnum.fatal),
  ],
),

2.3 圆角

默认有一个大小为4的圆角,若要手动修改可以通过指定radius参数。radius参数接受一个double值。例如,设置radius为0则没有圆角:

dart 复制代码
Tag('radius: 0', radius: 0),

2.4 尺寸

枚举尺寸

例如:

dart 复制代码
Tag('SizeEnum.small', size: SizeEnum.small),
Tag('SizeEnum.defaultSize', size: SizeEnum.defaultSize),
Tag('SizeEnum.large', size: SizeEnum.large),
数值尺寸

通过height参数可以指定数值作为尺寸。height一经指定,则size失效。例如,指定高度为50:

dart 复制代码
Tag('hignt=50', height: 50),
收缩属性

通过指定shrink属性为flase,可以使一个标签尽可能占满一行,例如:

dart 复制代码
Tag('shrink: false', shrink: false)

2.5 可关闭标签

通过指定 closable: true,将展示一个关闭图标。例如:

dart 复制代码
const Row(
  mainAxisAlignment: MainAxisAlignment.spaceAround,
  children: [
    Tag('tag', closable: true, type: SemanticEnum.primary),
    Tag('tag', closable: true, type: SemanticEnum.secondary),
    Tag('tag', closable: true, type: SemanticEnum.info),
    Tag('tag', closable: true, type: SemanticEnum.success),
    Tag('tag', closable: true, type: SemanticEnum.warning),
    Tag('tag', closable: true, type: SemanticEnum.danger),
    Tag('tag', closable: true, type: SemanticEnum.fatal),
  ],
),

2.6 动态编辑标签示例

可以通过点击标签关闭按钮后触发的 onClose 事件来实现动态编辑标签。例如:

dart 复制代码
import 'package:flutter/material.dart';
import 'package:widgets_easier/widgets_easier.dart';

class DynamicTagsExample extends StatefulWidget {
  const DynamicTagsExample({super.key});

  @override
  State<DynamicTagsExample> createState() => _DynamicTagsExampleState();
}

class _DynamicTagsExampleState extends State<DynamicTagsExample> {
  final List<String> _tags = ['Tag 1', 'Tag 2', 'Tag 3'];
  final String _newTagButtonText = '+ 添加 Tag';

  void _handleClose(int index) {
    setState(() {
      _tags.removeAt(index);
    });
  }

  void _handleSubmitted(String value) {
    if (value.isNotEmpty) {
      setState(() {
        _tags.add(value);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Wrap(
      spacing: 8,
      runSpacing: 8,
      children: [
        Text('$_tags'),
        for (int index = 0; index < _tags.length; index++)
          Tag(
            key: UniqueKey(), // 重要
            _tags[index],
            type: SemanticEnum.primary,
            theme: TagThemeEnum.light,
            closable: true,
            onClose: (_) {
              _handleClose(index);
            },
          ),
        Tag(
          _newTagButtonText,
          type: SemanticEnum.danger,
          editable: true,
          restoreAfterSubmitted: true,
          onSubmitted: _handleSubmitted,
        ),
      ],
    );
  }
}

这个例子恰好是一定要指定key的例子,顺便说一下一种错误情况。

在没有使用 key 的情况下,Flutter 在构建组件树时,会根据组件的位置来匹配新旧组件。当删除一个 Tag 时,其后面的 Tag 会向前移动,占据被删除的 Tag 的位置。但是,Flutter 并不知道这种位置的变化,它仍然认为在原来的位置上的 Tag 与之前的 Tag相同,导致视图没有正确更新。

相关推荐
why1516 小时前
腾讯(QQ浏览器)后端开发
开发语言·后端·golang
浪裡遊6 小时前
跨域问题(Cross-Origin Problem)
linux·前端·vue.js·后端·https·sprint
声声codeGrandMaster6 小时前
django之优化分页功能(利用参数共存及封装来实现)
数据库·后端·python·django
呼Lu噜7 小时前
WPF-遵循MVVM框架创建图表的显示【保姆级】
前端·后端·wpf
bing_1587 小时前
为什么选择 Spring Boot? 它是如何简化单个微服务的创建、配置和部署的?
spring boot·后端·微服务
学c真好玩7 小时前
Django创建的应用目录详细解释以及如何操作数据库自动创建表
后端·python·django
Asthenia04127 小时前
GenericObjectPool——重用你的对象
后端
Piper蛋窝7 小时前
Go 1.18 相比 Go 1.17 有哪些值得注意的改动?
后端
excel7 小时前
招幕技术人员
前端·javascript·后端
盖世英雄酱581368 小时前
什么是MCP
后端·程序员