From 342879088ae6b8cd4b2d35e8c131007f58ee1436 Mon Sep 17 00:00:00 2001 From: violinday Date: Tue, 4 Jan 2022 15:18:32 +0800 Subject: [PATCH 1/2] =?UTF-8?q?[null-safe]:=20BrnStateTag=E3=80=81BrnTagCu?= =?UTF-8?q?stom=E3=80=81BrnSelectTag=E3=80=81BrnDeleteTag=20=E7=A9=BA?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/tag/select_tag_example.dart | 5 +- lib/src/components/tag/brn_state_tag.dart | 14 +-- lib/src/components/tag/brn_tag_custom.dart | 63 ++++------ .../tag/tagview/brn_delete_tag.dart | 108 ++++++++---------- .../tag/tagview/brn_select_tag.dart | 81 ++++++------- 5 files changed, 114 insertions(+), 157 deletions(-) diff --git a/example/lib/sample/components/tag/select_tag_example.dart b/example/lib/sample/components/tag/select_tag_example.dart index 56f56e24..7961a2c3 100644 --- a/example/lib/sample/components/tag/select_tag_example.dart +++ b/example/lib/sample/components/tag/select_tag_example.dart @@ -152,8 +152,7 @@ class SelectTagExamplePageState extends State { double _getTagWidth(context, {int rowCount: 4}) { double leftRightPadding = 40; double rowSpace = 12; - return MediaQuery.of(context).size.width - - leftRightPadding - - rowSpace * (rowCount - 1) / rowCount; + return (MediaQuery.of(context).size.width - leftRightPadding - rowSpace * (rowCount - 1)) / + rowCount; } } diff --git a/lib/src/components/tag/brn_state_tag.dart b/lib/src/components/tag/brn_state_tag.dart index 384f37af..5b6f806b 100644 --- a/lib/src/components/tag/brn_state_tag.dart +++ b/lib/src/components/tag/brn_state_tag.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'package:bruno/src/components/tag/brn_tag_custom.dart'; import 'package:flutter/material.dart'; @@ -17,17 +15,17 @@ import 'package:flutter/material.dart'; /// class BrnStateTag extends StatelessWidget { final String tagText; - final Color backgroundColor; - final Color textColor; final TagState tagState; + final Color? backgroundColor; + final Color? textColor; //默认为等待状态,黄色 const BrnStateTag( - {Key key, - this.tagText, + {Key? key, + required this.tagText, + this.tagState = TagState.waiting, this.backgroundColor, - this.textColor, - this.tagState = TagState.waiting}) + this.textColor,}) : super(key: key); @override diff --git a/lib/src/components/tag/brn_tag_custom.dart b/lib/src/components/tag/brn_tag_custom.dart index d273f36e..6a8381db 100644 --- a/lib/src/components/tag/brn_tag_custom.dart +++ b/lib/src/components/tag/brn_tag_custom.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:flutter/material.dart'; @@ -22,10 +20,10 @@ class BrnTagCustom extends StatelessWidget { final String tagText; /// 标签的背景颜色 默认主题色 - final Color backgroundColor; + final Color? backgroundColor; /// 标签的文本颜色 默认F4的反白颜色 - final Color textColor; + final Color? textColor; /// 标签的圆角 默认为2 /// 如果同时设置了borderRadius、tagBorderRadius字段,优先使用tagBorderRadius字段设置圆角 @@ -44,15 +42,15 @@ class BrnTagCustom extends StatelessWidget { final double maxWidth; /// 标签边框 - final Border border; + final Border? border; BrnTagCustom({ - Key key, - this.tagText, + Key? key, + required this.tagText, this.textColor, this.backgroundColor, - this.tagBorderRadius, - this.textPadding, + this.tagBorderRadius = const BorderRadius.all(Radius.circular(2)), + this.textPadding = const EdgeInsets.only(bottom: 0.5, left: 3, right: 3, top: 0), this.border, this.fontSize = 11, this.fontWeight = FontWeight.normal, @@ -61,61 +59,46 @@ class BrnTagCustom extends StatelessWidget { ///快捷方式生成边框标签 BrnTagCustom.buildBorderTag({ - Key key, + Key? key, + required this.tagText, this.backgroundColor = Colors.transparent, - this.tagText = "", - this.textPadding = - const EdgeInsets.only(bottom: 3, left: 3, right: 3, top: 0), + this.textPadding = const EdgeInsets.only(bottom: 3, left: 3, right: 3, top: 0), this.fontSize = 11, this.fontWeight = FontWeight.normal, - this.tagBorderRadius, - Color textColor, - Color borderColor, + this.tagBorderRadius = const BorderRadius.all(Radius.circular(2)), + Color? textColor, + Color? borderColor, double borderWidth = 1, - double borderRadius = 3, }) : this.maxWidth = double.infinity, this.border = Border.all( - color: borderColor ?? - BrnThemeConfigurator.instance - .getConfig() - .commonConfig - .brandPrimary, - width: borderWidth ?? 1, + color: borderColor ?? BrnThemeConfigurator.instance.getConfig().commonConfig.brandPrimary, + width: borderWidth, ), - this.textColor = textColor ?? - BrnThemeConfigurator.instance.getConfig().commonConfig.brandPrimary, + this.textColor = + textColor ?? BrnThemeConfigurator.instance.getConfig().commonConfig.brandPrimary, super(key: key); @override Widget build(BuildContext context) { - BorderRadius bRadius = - tagBorderRadius ?? BorderRadius.all(Radius.circular(2)); return Container( constraints: BoxConstraints( maxWidth: maxWidth, ), decoration: BoxDecoration( color: backgroundColor ?? - BrnThemeConfigurator.instance - .getConfig() - .commonConfig - .brandPrimary, + BrnThemeConfigurator.instance.getConfig().commonConfig.brandPrimary, shape: BoxShape.rectangle, - borderRadius: bRadius, + borderRadius: tagBorderRadius, border: border), - padding: textPadding ?? - EdgeInsets.only(bottom: 0.5, left: 3, right: 3, top: 0), + padding: textPadding, child: Text( - tagText ?? "", + tagText, textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, style: TextStyle( - fontSize: fontSize ?? 11, + fontSize: fontSize, color: textColor ?? - BrnThemeConfigurator.instance - .getConfig() - .commonConfig - .colorTextBaseInverse, + BrnThemeConfigurator.instance.getConfig().commonConfig.colorTextBaseInverse, fontWeight: fontWeight, ), )); diff --git a/lib/src/components/tag/tagview/brn_delete_tag.dart b/lib/src/components/tag/tagview/brn_delete_tag.dart index 609a3fa0..bf92d7f5 100644 --- a/lib/src/components/tag/tagview/brn_delete_tag.dart +++ b/lib/src/components/tag/tagview/brn_delete_tag.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'package:bruno/src/constants/brn_asset_constants.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:bruno/src/utils/brn_tools.dart'; @@ -17,31 +15,31 @@ class BrnDeleteTag extends StatefulWidget { final List tags; /// 标签控制器,用于主动添加和删除标签,如果使用场景只需要删除标签并进行回调可以不传控制器 - final BrnDeleteTagController controller; + final BrnDeleteTagController? controller; /// 点击删除某个标签后的回调,参数包含 /// 剩余的标签集合 /// 被删除的标签内容 /// 被删除的标签索引 - final Function(List, String, int) onTagDelete; + final Function(List, String?, int)? onTagDelete; /// 垂直方向的间距 - final double verticalSpacing; + final double? verticalSpacing; /// 水平方向的间距 - final double horizontalSpacing; + final double? horizontalSpacing; /// 标签的字体颜色 - final TextStyle tagTextStyle; + final TextStyle? tagTextStyle; /// 标签的圆角 - final ShapeBorder shape; + final OutlinedBorder? shape; /// 标签背景色 - final Color backgroundColor; + final Color? backgroundColor; /// 删除图标的颜色 - final Color deleteIconColor; + final Color? deleteIconColor; /// true 流式展示,false 横向滑动展示,默认 true final bool softWrap; @@ -50,14 +48,14 @@ class BrnDeleteTag extends StatefulWidget { final EdgeInsets padding; /// 主题配置信息,包含标签背景色、文本颜色等字段,非必传 - BrnTagConfig themeData; + BrnTagConfig? themeData; /// delete Icon Size,不传默认使用 内置删除 icon 图片的的大小, - final Size deleteIconSize; + final Size? deleteIconSize; BrnDeleteTag( - {Key key, - this.tags, + {Key? key, + required this.tags, this.controller, this.onTagDelete, this.verticalSpacing, @@ -68,15 +66,15 @@ class BrnDeleteTag extends StatefulWidget { this.deleteIconColor, this.deleteIconSize, this.softWrap = true, - this.padding, + this.padding = const EdgeInsets.fromLTRB(20, 0, 20, 0), this.themeData}) : super(key: key) { themeData ??= BrnTagConfig(); - themeData = themeData.merge(BrnTagConfig( + themeData = themeData!.merge(BrnTagConfig( tagBackgroundColor: this.backgroundColor, tagTextStyle: BrnTextStyle.withStyle(tagTextStyle))); themeData = BrnThemeConfigurator.instance - .getConfig(configId: themeData.configId) + .getConfig(configId: themeData!.configId) .tagConfig .merge(themeData); } @@ -86,20 +84,19 @@ class BrnDeleteTag extends StatefulWidget { } class _BrnDeleteTagState extends State { - BrnDeleteTagController _controller; + late BrnDeleteTagController _controller; @override void initState() { super.initState(); - _controller = - widget.controller ?? BrnDeleteTagController(initTags: widget.tags); + _controller = widget.controller ?? BrnDeleteTagController(initTags: widget.tags); } @override Widget build(BuildContext context) { return Container( color: Colors.white, - child: ValueListenableBuilder( + child: ValueListenableBuilder>( valueListenable: _controller.notifier, builder: (context, value, _) { return _buildContent(value); @@ -109,8 +106,8 @@ class _BrnDeleteTagState extends State { /// 根据标签集合构建标签 UI Widget _buildContent(List tags) { - if (tags == null || tags.isEmpty) { - return Container(); + if (tags.isEmpty) { + return SizedBox.shrink(); } List itemList = []; @@ -120,28 +117,25 @@ class _BrnDeleteTagState extends State { tags[i], _deleteTag, deleteIconSize: widget.deleteIconSize, - style: widget.themeData.tagTextStyle?.generateTextStyle(), + style: widget.themeData!.tagTextStyle.generateTextStyle(), shape: widget.shape, - backgroundColor: widget.themeData?.tagBackgroundColor, + backgroundColor: widget.themeData!.tagBackgroundColor, deleteIconColor: widget.deleteIconColor, themeData: widget.themeData, )); } Widget result; - if (widget.softWrap ?? true) { + if (widget.softWrap) { result = Wrap( spacing: widget.horizontalSpacing ?? 10, - runSpacing: - widget.verticalSpacing != null ? widget.verticalSpacing - 16 : -6, + runSpacing: widget.verticalSpacing != null ? widget.verticalSpacing! - 16 : -6, alignment: WrapAlignment.start, children: itemList, ); } else { int tagIdx = 0; var finalTagList = itemList.map((tag) { - double rightPadding = (tagIdx == itemList.length - 1) - ? 0 - : widget.horizontalSpacing ?? 12; + double rightPadding = (tagIdx == itemList.length - 1) ? 0 : widget.horizontalSpacing ?? 12; var padding = Padding( child: tag, padding: EdgeInsets.only(right: rightPadding), @@ -160,7 +154,7 @@ class _BrnDeleteTagState extends State { return Container( color: Colors.white, - padding: widget.padding ?? EdgeInsets.fromLTRB(20, 0, 20, 0), + padding: widget.padding, alignment: Alignment.centerLeft, child: result, ); @@ -168,9 +162,9 @@ class _BrnDeleteTagState extends State { /// 删除指定 index 下标的标签,并且回调通知外部使用者 void _deleteTag(int index) { - String result = _controller.deleteForIndex(index); + String? result = _controller.deleteForIndex(index); if (widget.onTagDelete != null) { - widget.onTagDelete(_controller.tags, result, index); + widget.onTagDelete!(_controller.tags, result, index); } } } @@ -181,12 +175,12 @@ class DeleteTagItemWidget extends StatelessWidget { final int index; final String title; final Function(int) didDeleted; - final Size deleteIconSize; - final TextStyle style; - final ShapeBorder shape; - final Color backgroundColor; - final Color deleteIconColor; - BrnTagConfig themeData; + final Size? deleteIconSize; + final TextStyle? style; + final OutlinedBorder? shape; + final Color? backgroundColor; + final Color? deleteIconColor; + final BrnTagConfig? themeData; DeleteTagItemWidget(this.index, this.title, this.didDeleted, {this.deleteIconSize, @@ -201,20 +195,17 @@ class DeleteTagItemWidget extends StatelessWidget { return Chip( padding: EdgeInsets.fromLTRB(10, 0, -3, 0), labelPadding: EdgeInsets.fromLTRB(0, 0, -3, 0), - backgroundColor: themeData.tagBackgroundColor, + backgroundColor: themeData!.tagBackgroundColor, label: Text(this.title, - overflow: TextOverflow.ellipsis, - style: themeData?.tagTextStyle?.generateTextStyle()), + overflow: TextOverflow.ellipsis, style: themeData!.tagTextStyle.generateTextStyle()), shape: shape ?? - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(themeData?.tagRadius)), + RoundedRectangleBorder(borderRadius: BorderRadius.circular(themeData!.tagRadius)), //删除图标 deleteIcon: deleteIconSize != null ? BrunoTools.getAssetSizeImage( - BrnAsset.ICON_CLOSE, deleteIconSize.width, deleteIconSize.height, + BrnAsset.ICON_CLOSE, deleteIconSize!.width, deleteIconSize!.height, color: deleteIconColor) - : BrunoTools.getAssetImageWithColor( - BrnAsset.ICON_CLOSE, deleteIconColor), + : BrunoTools.getAssetImageWithColor(BrnAsset.ICON_CLOSE, deleteIconColor), onDeleted: () { debugPrint('$index'); didDeleted(index); @@ -225,14 +216,14 @@ class DeleteTagItemWidget extends StatelessWidget { /// 标签控制器,用于主动添加和删除标签 class BrnDeleteTagController { - ValueNotifier> notifier; + late ValueNotifier> notifier; /// 控制器中存储的标签数据 - List _tags = List(); + List _tags = []; List get tags => notifier.value; - BrnDeleteTagController({List initTags}) { + BrnDeleteTagController({required List initTags}) { _tags = initTags; notifier = ValueNotifier(_tags); } @@ -262,8 +253,8 @@ class BrnDeleteTagController { } /// 删除指定 index 的标签,并返回其内容 - String deleteForIndex(int index) { - if (_tags != null && _tags.length > index) { + String? deleteForIndex(int index) { + if (_tags.length > index) { String result = _tags.removeAt(index); _asyncData(); return result; @@ -273,17 +264,14 @@ class BrnDeleteTagController { /// 删除某个具体内容的标签,成功返回 true,失败返回 false bool deleteForTag(String tag) { - if (_tags != null) { - bool result = _tags.remove(tag); - _asyncData(); - return result; - } else - return false; + bool result = _tags.remove(tag); + _asyncData(); + return result; } void _asyncData() { // notifier 中的 value 引用是 _tags 所以直接赋值 _tags 不会触发回调 - List values = List(); + List values = []; _tags.forEach((e) => values.add(e)); notifier.value = values; } diff --git a/lib/src/components/tag/tagview/brn_select_tag.dart b/lib/src/components/tag/tagview/brn_select_tag.dart index dd25b988..62f01fe4 100644 --- a/lib/src/components/tag/tagview/brn_select_tag.dart +++ b/lib/src/components/tag/tagview/brn_select_tag.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'dart:math'; import 'package:bruno/src/theme/base/brn_text_style.dart'; @@ -15,11 +13,10 @@ import 'package:flutter/material.dart'; /// ignore: must_be_immutable class BrnSelectTag extends StatefulWidget { /// 展示的标签列表 - @required final List tags; /// 选择tag的回调,返回选中 tag 的位置 - final void Function(List) onSelect; + final void Function(List)? onSelect; /// 水平间距,默认 12 final double spacing; @@ -28,22 +25,22 @@ class BrnSelectTag extends StatefulWidget { final double verticalSpacing; /// 普通标签的样式 - final TextStyle tagTextStyle; + final TextStyle? tagTextStyle; /// 选中的标签样式 - final TextStyle selectedTagTextStyle; + final TextStyle? selectedTagTextStyle; /// 普通标签背景色,默认 F0Color - final Color tagBackgroundColor; + final Color? tagBackgroundColor; /// 选中的标签背景色,默认 B0Color - final Color selectedTagBackgroundColor; + final Color? selectedTagBackgroundColor; - /// 标签宽度。默认 75 - final double tagWidth; + /// 标签宽度。默认全局配置宽度 75 + final double? tagWidth; - /// 标签高度。默认 34 - final double tagHeight; + /// 标签高度。默认全局配置高度 34 + final double? tagHeight; /// true 流式展示,false 横向滑动展示,默认 true final bool softWrap; @@ -58,13 +55,13 @@ class BrnSelectTag extends StatefulWidget { final bool isSingleSelect; /// 多选时的初始状态数组 - final List initTagState; + final List? initTagState; - BrnTagConfig themeData; + BrnTagConfig? themeData; BrnSelectTag({ - Key key, - @required this.tags, + Key? key, + required this.tags, this.onSelect, this.spacing = 12, this.verticalSpacing = 10, @@ -80,13 +77,12 @@ class BrnSelectTag extends StatefulWidget { this.alignment = Alignment.centerLeft, this.fixWidthMode = true, this.themeData, - }) : assert(tags != null), - super(key: key) { + }) : super(key: key) { if (isSingleSelect == true) { - assert(initTagState == null || (initTagState.length <= 1)); + assert(initTagState == null || (initTagState!.length <= 1)); } this.themeData ??= BrnTagConfig(); - this.themeData = this.themeData.merge(BrnTagConfig( + this.themeData = this.themeData!.merge(BrnTagConfig( tagBackgroundColor: this.tagBackgroundColor, tagTextStyle: BrnTextStyle.withStyle(this.tagTextStyle), selectTagTextStyle: BrnTextStyle.withStyle(this.selectedTagTextStyle), @@ -94,7 +90,7 @@ class BrnSelectTag extends StatefulWidget { tagHeight: this.tagHeight, selectedTagBackgroundColor: this.selectedTagBackgroundColor)); this.themeData = BrnThemeConfigurator.instance - .getConfig(configId: this.themeData.configId) + .getConfig(configId: this.themeData!.configId) .tagConfig .merge(this.themeData); } @@ -104,17 +100,15 @@ class BrnSelectTag extends StatefulWidget { } class _BrnSelectTagState extends State { - List _tagState; + List _tagState = []; @override void initState() { super.initState(); _tagState = widget.tags.map((name) => false).toList(); if (widget.initTagState != null) { - for (int index = 0; - index < min(widget.initTagState.length, widget.tags.length); - index++) { - _tagState[index] = widget.initTagState[index]; + for (int index = 0; index < min(widget.initTagState!.length, widget.tags.length); index++) { + _tagState[index] = widget.initTagState![index]; } } } @@ -122,7 +116,7 @@ class _BrnSelectTagState extends State { @override Widget build(BuildContext context) { Widget content; - if (widget.softWrap ?? true) { + if (widget.softWrap) { content = Wrap( runSpacing: widget.verticalSpacing, spacing: widget.spacing, @@ -159,13 +153,13 @@ class _BrnSelectTagState extends State { } List _tagWidgetList(context) { - List list = List(); + List list = []; for (int nameIndex = 0; nameIndex < widget.tags.length; nameIndex++) { Widget tagWidget = _tagWidgetAtIndex(nameIndex); GestureDetector gdt = GestureDetector( child: tagWidget, onTap: () { - if (widget.isSingleSelect ?? true) { + if (widget.isSingleSelect) { bool selected = _tagState[nameIndex]; if (selected) { return; @@ -185,7 +179,7 @@ class _BrnSelectTagState extends State { for (int index = 0; index < _tagState.length; index++) { if (_tagState[index]) _selectedIndexes.add(index); } - widget.onSelect(_selectedIndexes); + widget.onSelect!(_selectedIndexes); } }); list.add(gdt); @@ -201,15 +195,14 @@ class _BrnSelectTagState extends State { overflow: TextOverflow.ellipsis, ); Container container = Container( - constraints: BoxConstraints(minWidth: widget.themeData.tagMinWidth), + constraints: BoxConstraints(minWidth: widget.themeData!.tagMinWidth), decoration: BoxDecoration( color: selected - ? (widget.themeData?.selectedTagBackgroundColor - ?.withOpacity(0.12)) - : (widget.themeData?.tagBackgroundColor), - borderRadius: BorderRadius.circular(widget.themeData?.tagRadius)), - width: widget.fixWidthMode ? widget.themeData?.tagWidth : null, - height: widget.themeData?.tagHeight, + ? (widget.themeData!.selectedTagBackgroundColor.withOpacity(0.12)) + : (widget.themeData!.tagBackgroundColor), + borderRadius: BorderRadius.circular(widget.themeData!.tagRadius)), + width: widget.fixWidthMode ? widget.themeData!.tagWidth : null, + height: widget.themeData!.tagHeight, padding: EdgeInsets.only(left: 8, right: 8), child: Center(widthFactor: 1, child: tx), ); @@ -217,28 +210,24 @@ class _BrnSelectTagState extends State { } TextStyle _tagTextStyle() { - return widget.themeData?.tagTextStyle?.generateTextStyle(); + return widget.themeData!.tagTextStyle.generateTextStyle(); } TextStyle _selectedTextStyle() { - return widget.themeData?.selectTagTextStyle?.generateTextStyle(); + return widget.themeData!.selectTagTextStyle.generateTextStyle(); } @override void didUpdateWidget(BrnSelectTag oldWidget) { super.didUpdateWidget(oldWidget); // 如果两个数组不相等,重置选中状态 - if (!sameList(oldWidget.tags, widget.tags)) - _tagState = List.filled(widget.tags.length, false); + if (!sameList(oldWidget.tags, widget.tags)) _tagState = List.filled(widget.tags.length, false); } /// 比较两个数组内容是否一致,如果一致,返回 true,否则 false bool sameList(List first, List second) { - if (first == null || second == null || first.length != second.length) - return false; + if (first.length != second.length) return false; int index = 0; - return first.firstWhere((item) => item != second[index++], - orElse: () => null) == - null; + return first.firstWhere((item) => item != second[index++], orElse: () => '') == ''; } } From d28743ec1bda0940a520725ff5d85e0a1dd62349 Mon Sep 17 00:00:00 2001 From: violinday Date: Tue, 4 Jan 2022 17:51:44 +0800 Subject: [PATCH 2/2] perf: BrnDeleteTag null-safe --- lib/src/components/tag/tagview/brn_delete_tag.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/components/tag/tagview/brn_delete_tag.dart b/lib/src/components/tag/tagview/brn_delete_tag.dart index bf92d7f5..b83819fd 100644 --- a/lib/src/components/tag/tagview/brn_delete_tag.dart +++ b/lib/src/components/tag/tagview/brn_delete_tag.dart @@ -223,8 +223,8 @@ class BrnDeleteTagController { List get tags => notifier.value; - BrnDeleteTagController({required List initTags}) { - _tags = initTags; + BrnDeleteTagController({List? initTags}) { + _tags = initTags ?? []; notifier = ValueNotifier(_tags); }