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个样式主题,plain
、light
和dark
,默认情况下为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
相同,导致视图没有正确更新。