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相同,导致视图没有正确更新。

相关推荐
Victor3561 小时前
Netty(20)如何实现基于Netty的WebSocket服务器?
后端
缘不易1 小时前
Springboot 整合JustAuth实现gitee授权登录
spring boot·后端·gitee
Kiri霧1 小时前
Range循环和切片
前端·后端·学习·golang
WizLC2 小时前
【Java】各种IO流知识详解
java·开发语言·后端·spring·intellij idea
Victor3562 小时前
Netty(19)Netty的性能优化手段有哪些?
后端
爬山算法2 小时前
Netty(15)Netty的线程模型是什么?它有哪些线程池类型?
java·后端
白宇横流学长2 小时前
基于SpringBoot实现的冬奥会科普平台设计与实现【源码+文档】
java·spring boot·后端
Python编程学习圈3 小时前
Asciinema - 终端日志记录神器,开发者的福音
后端
bing.shao3 小时前
Golang 高并发秒杀系统踩坑
开发语言·后端·golang
壹方秘境3 小时前
一款方便Java开发者在IDEA中抓包分析调试接口的插件
后端