From 5065fdbac8e8b9b32ed84988327ccc6248610242 Mon Sep 17 00:00:00 2001 From: zhoujuanjuan <15143015732@163.com> Date: Thu, 20 Oct 2022 18:05:13 +0800 Subject: [PATCH 01/15] expend BrnMultiSelectListPicker data --- .../components/picker/expend_multi_item.dart | 19 ++++++++++ .../components/picker/picker_entry_page.dart | 35 +++++++++++++++++++ .../brn_multi_select_list_picker.dart | 24 ++++++------- .../date_picker/brn_date_picker.dart | 4 +-- 4 files changed, 68 insertions(+), 14 deletions(-) create mode 100644 example/lib/sample/components/picker/expend_multi_item.dart diff --git a/example/lib/sample/components/picker/expend_multi_item.dart b/example/lib/sample/components/picker/expend_multi_item.dart new file mode 100644 index 00000000..17631ba7 --- /dev/null +++ b/example/lib/sample/components/picker/expend_multi_item.dart @@ -0,0 +1,19 @@ +import 'package:bruno/bruno.dart'; + +class ExpendMultiSelectBottomPickerItem extends BrnMultiSelectBottomPickerItem { + final String? attribute1; + final String? attribute2; + final String? attribute3; + String code; //选项编号 + String content; //选项内容 + bool isChecked; //是否选中 + + ExpendMultiSelectBottomPickerItem( + this.code, + this.content, { + this.attribute1, + this.attribute2, + this.attribute3, + this.isChecked = false, + }) : super(code, content, isChecked: isChecked); +} \ No newline at end of file diff --git a/example/lib/sample/components/picker/picker_entry_page.dart b/example/lib/sample/components/picker/picker_entry_page.dart index ea5a3e0b..9539e05d 100644 --- a/example/lib/sample/components/picker/picker_entry_page.dart +++ b/example/lib/sample/components/picker/picker_entry_page.dart @@ -9,6 +9,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'date_picker_example.dart'; +import 'expend_multi_item.dart'; import 'multi_picker_example.dart'; class PickerEntryPage extends StatelessWidget { @@ -56,6 +57,13 @@ class PickerEntryPage extends StatelessWidget { _showBottomMultiSelectPicker(context); }, ), + ListItem( + title: "Picker/多选/勾选(MultiSelectBottomPicker)", + describe: '底部多选弹框(自定义数据协议)', + onPressed: () { + _showExpandBottomMultiSelectPicker(context); + }, + ), ListItem( title: "Picker/多选/勾选(MultiSelectBottomPicker)", describe: '底部多选弹框(实现限制选择个数)', @@ -157,6 +165,33 @@ class PickerEntryPage extends StatelessWidget { ); } + ///多选弹框自定义数据协议 + void _showExpandBottomMultiSelectPicker(BuildContext context) { + List items = []; + items.add(new ExpendMultiSelectBottomPickerItem("100", "这里是标题1",attribute1: "第一条自定义参数1")); + items.add(new ExpendMultiSelectBottomPickerItem("101", "这里是标题2",attribute1: "第二条自定义参数2")); + items.add( + new ExpendMultiSelectBottomPickerItem("102", "这里是标题3", isChecked: true,attribute1: "第三条自定义参数3")); + items.add( + new ExpendMultiSelectBottomPickerItem("103", "这里是标题4", isChecked: true)); + items.add(new ExpendMultiSelectBottomPickerItem("104", "这里是标题5")); + items.add(new ExpendMultiSelectBottomPickerItem("104", "这里是标题6")); + BrnMultiSelectListPicker.show( + context, + items: items, + pickerTitleConfig: BrnPickerTitleConfig(titleContent: "多选 Picker"), + onSubmit: (List data) { + var str = ""; + data.forEach((item) { + String attribute = item.attribute1 ?? ""; + str = str + attribute; + }); + BrnToast.show(str, context); + Navigator.of(context).pop(); + }, + ); + } + /// 实现限制选择数量的情况 void _showCountLimitBottomMultiSelectPicker(BuildContext context) { List items = []; diff --git a/lib/src/components/picker/multi_select_bottom_picker/brn_multi_select_list_picker.dart b/lib/src/components/picker/multi_select_bottom_picker/brn_multi_select_list_picker.dart index fcf0e698..1521d013 100644 --- a/lib/src/components/picker/multi_select_bottom_picker/brn_multi_select_list_picker.dart +++ b/lib/src/components/picker/multi_select_bottom_picker/brn_multi_select_list_picker.dart @@ -13,8 +13,8 @@ import 'package:flutter/material.dart'; /// 点击确定时的回调 /// [checkedItems] 被选中的 item 集合 -typedef BrnMultiSelectListPickerSubmit = void Function( - List checkedItems); +typedef BrnMultiSelectListPickerSubmit = void Function( + List checkedItems); /// item 被点击时的回调 /// [index] item 的索引 @@ -23,18 +23,18 @@ typedef BrnMultiSelectListPickerItemClick = void Function( /// 多选列表 Picker -class BrnMultiSelectListPicker extends StatefulWidget { +class BrnMultiSelectListPicker extends StatefulWidget { final String? title; - final List items; - final BrnMultiSelectListPickerSubmit? onSubmit; + final List items; + final BrnMultiSelectListPickerSubmit? onSubmit; final VoidCallback? onCancel; final BrnMultiSelectListPickerItemClick? onItemClick; final BrnPickerTitleConfig pickerTitleConfig; - static void show( + static void show( BuildContext context, { - required List items, - BrnMultiSelectListPickerSubmit? onSubmit, + required List items, + BrnMultiSelectListPickerSubmit? onSubmit, VoidCallback? onCancel, BrnMultiSelectListPickerItemClick? onItemClick, BrnPickerTitleConfig pickerTitleConfig = BrnPickerTitleConfig.Default, @@ -45,7 +45,7 @@ class BrnMultiSelectListPicker extends StatefulWidget { isDismissible: isDismissible, backgroundColor: Colors.transparent, builder: (BuildContext dialogContext) { - return BrnMultiSelectListPicker( + return BrnMultiSelectListPicker( items: items, onSubmit: onSubmit, onCancel: onCancel, @@ -68,11 +68,11 @@ class BrnMultiSelectListPicker extends StatefulWidget { @override State createState() { - return MultiSelectDialogWidgetState(); + return MultiSelectDialogWidgetState(); } } -class MultiSelectDialogWidgetState extends State { +class MultiSelectDialogWidgetState extends State> { @override Widget build(BuildContext context) { return BrnPickerClipRRect( @@ -99,7 +99,7 @@ class MultiSelectDialogWidgetState extends State { child: BrnPickerTitle( pickerTitleConfig: widget.pickerTitleConfig, onConfirm: () { - List selectedItems = []; + List selectedItems = []; if (widget.onSubmit != null) { for (int i = 0; i < widget.items.length; i++) { if (widget.items[i].isChecked) { diff --git a/lib/src/components/picker/time_picker/date_picker/brn_date_picker.dart b/lib/src/components/picker/time_picker/date_picker/brn_date_picker.dart index db374f50..9c549da2 100755 --- a/lib/src/components/picker/time_picker/date_picker/brn_date_picker.dart +++ b/lib/src/components/picker/time_picker/date_picker/brn_date_picker.dart @@ -71,13 +71,13 @@ class BrnDatePicker { /// 点击【取消】回调给调用方的回调事件 DateVoidCallback? onCancel, - /// 点击【完成】回调给调用方的数据 + /// 点击【关闭】回调给调用方的数据 DateVoidCallback? onClose, /// 时间滚动选择时候的回调事件 DateValueCallback? onChange, - /// 弹框点击外围消失的回调事件 + /// 点击【完成】回调给调用方的数据 DateValueCallback? onConfirm, BrnPickerConfig? themeData, }) { From ccea5b237bf7a2a36d9145210b1a93335efeffa9 Mon Sep 17 00:00:00 2001 From: zhoujuanjuan <15143015732@163.com> Date: Thu, 20 Oct 2022 18:10:55 +0800 Subject: [PATCH 02/15] fix showDatePicker notes --- .../picker/time_picker/date_picker/brn_date_picker.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/components/picker/time_picker/date_picker/brn_date_picker.dart b/lib/src/components/picker/time_picker/date_picker/brn_date_picker.dart index 9c549da2..c2804c38 100755 --- a/lib/src/components/picker/time_picker/date_picker/brn_date_picker.dart +++ b/lib/src/components/picker/time_picker/date_picker/brn_date_picker.dart @@ -71,7 +71,7 @@ class BrnDatePicker { /// 点击【取消】回调给调用方的回调事件 DateVoidCallback? onCancel, - /// 点击【关闭】回调给调用方的数据 + /// 弹框点击外围消失的回调事件 DateVoidCallback? onClose, /// 时间滚动选择时候的回调事件 From 88cd753bc255c65b57a08704e3393a4a6e544b7c Mon Sep 17 00:00:00 2001 From: zhoujuanjuan <15143015732@163.com> Date: Tue, 1 Nov 2022 14:37:34 +0800 Subject: [PATCH 03/15] add yDialMax > yDialMin limit --- .../charts/broken_line/brn_line_painter.dart | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/src/components/charts/broken_line/brn_line_painter.dart b/lib/src/components/charts/broken_line/brn_line_painter.dart index a4506970..ace50f5f 100644 --- a/lib/src/components/charts/broken_line/brn_line_painter.dart +++ b/lib/src/components/charts/broken_line/brn_line_painter.dart @@ -108,6 +108,7 @@ class BrnLinePainter extends BrnBasePainter { '折线${i - 1}和$i条线的节点数不一致'); } } + assert(yDialMax > yDialMin, "yDialMax 应该大于 yDialMin"); } Point selectedPoint(int lineIndex, int pointIndex) { @@ -198,10 +199,13 @@ class BrnLinePainter extends BrnBasePainter { ((item.points[i].x - xDialMin!) / (xDialMax! - xDialMin!) * _fixedWidth); - var yPosition = _startY - - ((item.points[i].y - yDialMin) / - (yDialMax - yDialMin) * - _fixedHeight); + var yPosition = _startY; + if (yDialMax != yDialMin) { + yPosition = _startY - + ((item.points[i].y - yDialMin) / + (yDialMax - yDialMin) * + _fixedHeight); + } pointArr.add(Point(xPosition, yPosition)); } } else { From 6b90cbdc560f051098a3309c904aea7b48d9b497 Mon Sep 17 00:00:00 2001 From: zhoujuanjuan <15143015732@163.com> Date: Thu, 17 Nov 2022 18:16:49 +0800 Subject: [PATCH 04/15] fix setting orign mode overflow --- .../components/tabbar/brn_tab_example.dart | 5 - .../components/tabbar/normal/brn_tab_bar.dart | 152 +++++++++--------- 2 files changed, 79 insertions(+), 78 deletions(-) diff --git a/example/lib/sample/components/tabbar/brn_tab_example.dart b/example/lib/sample/components/tabbar/brn_tab_example.dart index 28171f91..5e58e413 100644 --- a/example/lib/sample/components/tabbar/brn_tab_example.dart +++ b/example/lib/sample/components/tabbar/brn_tab_example.dart @@ -125,11 +125,6 @@ class _BrnTabExampleState extends State tabs.add(BadgeTab(text: "业务二", badgeNum: 22)); tabs.add(BadgeTab(text: "业务三", badgeNum: 11)); tabs.add(BadgeTab(text: "业务四", showRedBadge: true)); - tabs.add(BadgeTab(text: "业务五", badgeNum: 12)); - tabs.add(BadgeTab(text: "业务六", badgeNum: 30)); - tabs.add(BadgeTab(text: "业务七")); - tabs.add(BadgeTab(text: "业务八", badgeNum: 23)); - tabs.add(BadgeTab(text: "业务九")); TabController tabController = TabController(length: tabs.length, vsync: this); return BrnTabBar( diff --git a/lib/src/components/tabbar/normal/brn_tab_bar.dart b/lib/src/components/tabbar/normal/brn_tab_bar.dart index 619ef439..2fa01466 100644 --- a/lib/src/components/tabbar/normal/brn_tab_bar.dart +++ b/lib/src/components/tabbar/normal/brn_tab_bar.dart @@ -14,6 +14,7 @@ import 'package:flutter/material.dart'; typedef BrnTabBarOnTap = Function(BrnTabBarState state, int index); const double _tagDefaultSize = 75.0; +const int _scrollableLimitTabLength = 4; /// 带小红点的Tabbar // ignore: must_be_immutable @@ -141,16 +142,16 @@ class BrnTabBar extends StatefulWidget { .tabBarConfig .merge(this.themeData); this.themeData = this.themeData!.merge(BrnTabBarConfig( - backgroundColor: backgroundcolor, - tabHeight: tabHeight, - indicatorHeight: indicatorWeight, - indicatorWidth: indicatorWidth, - labelStyle: BrnTextStyle.withStyle(labelStyle), - unselectedLabelStyle: BrnTextStyle.withStyle(unselectedLabelStyle), - tagSpacing: tagSpacing, - preLineTagCount: preLineTagCount, - tagHeight: tagHeight, - )); + backgroundColor: backgroundcolor, + tabHeight: tabHeight, + indicatorHeight: indicatorWeight, + indicatorWidth: indicatorWidth, + labelStyle: BrnTextStyle.withStyle(labelStyle), + unselectedLabelStyle: BrnTextStyle.withStyle(unselectedLabelStyle), + tagSpacing: tagSpacing, + preLineTagCount: preLineTagCount, + tagHeight: tagHeight, + )); } @override @@ -246,26 +247,27 @@ class BrnTabBarState extends State { color: widget.themeData!.backgroundColor, child: widget.showMore ? Row( - children: [ - Container( - width: MediaQuery.of(context).size.width - _moreSpacing, - child: _buildTabBar(), - ), - showMoreWidget(context) - ], - ) + children: [ + Container( + width: MediaQuery.of(context).size.width - _moreSpacing, + child: _buildTabBar(), + ), + showMoreWidget(context) + ], + ) : _buildTabBar(), ); } // 构建TabBar样式 TabBar _buildTabBar() { + bool _isScrollable = widget.tabs!.length > _scrollableLimitTabLength || + widget.tabWidth != null || + widget.isScroll; return TabBar( - tabs: fillWidgetByDataList(), + tabs: fillWidgetByDataList(_isScrollable), controller: widget.controller, - isScrollable: widget.tabs!.length > 4 || - widget.tabWidth != null || - widget.isScroll, + isScrollable: _isScrollable, labelColor: widget.labelColor ?? widget.themeData!.labelStyle.color, labelStyle: widget.labelStyle ?? widget.themeData!.labelStyle.generateTextStyle(), @@ -346,7 +348,7 @@ class BrnTabBarState extends State { }); } - List fillWidgetByDataList() { + List fillWidgetByDataList(bool isScrollable) { List widgets = []; List? tabList = widget.tabs; if (tabList != null && tabList.isNotEmpty) { @@ -357,7 +359,7 @@ class BrnTabBarState extends State { double tabUseWidth = widget.showMore ? MediaQuery.of(context).size.width - _moreSpacing : MediaQuery.of(context).size.width; - if (tabList.length <= 4) { + if (tabList.length <= _scrollableLimitTabLength) { minWidth = tabUseWidth / tabList.length; } else { minWidth = tabUseWidth / 4.5; @@ -369,7 +371,8 @@ class BrnTabBarState extends State { widgets.add( _wrapAverageWidget(badgeTab, minWidth, i == tabList.length - 1)); } else { - widgets.add(_wrapOriginWidget(badgeTab, i == tabList.length - 1)); + widgets.add(_wrapOriginWidget( + badgeTab, i == tabList.length - 1, isScrollable)); } } } @@ -377,53 +380,56 @@ class BrnTabBarState extends State { } // 原始的自适应的tab样式 - Widget _wrapOriginWidget(BadgeTab badgeTab, bool lastElement) { + Widget _wrapOriginWidget( + BadgeTab badgeTab, bool lastElement, bool isScrollable) { caculateBadgeParams(badgeTab); - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - alignment: Alignment.center, - height: 47, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Visibility( - visible: widget.hasIndex && badgeTab.topText != null, - child: Text( - badgeTab.topText ?? "", - maxLines: 1, - overflow: TextOverflow.ellipsis, - )), - Badge( - showBadge: (badgeTab.badgeNum != null - ? badgeTab.badgeNum! > 0 - : false) || + var _contentWidget = Container( + alignment: Alignment.center, + height: 47, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Visibility( + visible: widget.hasIndex && badgeTab.topText != null, + child: Text( + badgeTab.topText ?? "", + maxLines: 1, + overflow: TextOverflow.ellipsis, + )), + Badge( + showBadge: + (badgeTab.badgeNum != null ? badgeTab.badgeNum! > 0 : false) || badgeTab.showRedBadge || (badgeTab.badgeText != null ? badgeTab.badgeText!.isNotEmpty : false), - badgeContent: Text( - _badgeText, - style: TextStyle( - color: Color(0xFFFFFFFF), fontSize: 10, height: 1), - ), - shape: _badgeShape, - elevation: 0, - toAnimate: false, - borderRadius: _borderRadius, - alignment: Alignment.topLeft, - padding: _badgePadding, - position: - BadgePosition.topEnd(top: _paddingTop, end: _paddingRight), - child: Text(badgeTab.text!, - maxLines: 1, - softWrap: true, - overflow: TextOverflow.ellipsis), - ) - ], - ), - ), + badgeContent: Text( + _badgeText, + style: + TextStyle(color: Color(0xFFFFFFFF), fontSize: 10, height: 1), + ), + shape: _badgeShape, + elevation: 0, + toAnimate: false, + borderRadius: _borderRadius, + alignment: Alignment.topLeft, + padding: _badgePadding, + position: + BadgePosition.topEnd(top: _paddingTop, end: _paddingRight), + child: Text(badgeTab.text!, + maxLines: 1, softWrap: true, overflow: TextOverflow.ellipsis), + ) + ], + ), + ); + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + isScrollable + ? _contentWidget + : Expanded( + child: _contentWidget, + ), Visibility( visible: widget.hasDivider && !lastElement, child: Container( @@ -788,12 +794,12 @@ class _TabBarOverlayWidgetState extends State<_TabBarOverlayWidget> { class BadgeTab { BadgeTab( {this.key, - this.text, - this.badgeNum, - this.topText, - this.badgeText, - this.showRedBadge = false, - this.isAutoDismiss = true}); + this.text, + this.badgeNum, + this.topText, + this.badgeText, + this.showRedBadge = false, + this.isAutoDismiss = true}); final Key? key; From 3115f02508ef6f8fef3909b69166d2a5982a7138 Mon Sep 17 00:00:00 2001 From: zhoujuanjuan <15143015732@163.com> Date: Mon, 12 Dec 2022 18:19:10 +0800 Subject: [PATCH 05/15] fix gif image show error --- lib/src/constants/brn_asset_constants.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/src/constants/brn_asset_constants.dart b/lib/src/constants/brn_asset_constants.dart index 456376e9..5a924259 100644 --- a/lib/src/constants/brn_asset_constants.dart +++ b/lib/src/constants/brn_asset_constants.dart @@ -163,15 +163,15 @@ class BrnAsset { 'assets/images/icon_appraise_surprise_default.png'; static const String iconAppraiseBadSelected = - 'assets/images/icon_appraise_bad_selected.png'; + 'assets/images/icon_appraise_bad_selected.gif'; static const String iconAppraiseNotGoodSelected = - 'assets/images/icon_appraise_not_good_selected.png'; + 'assets/images/icon_appraise_not_good_selected.gif'; static const String iconAppraiseOkSelected = - 'assets/images/icon_appraise_ok_selected.png'; + 'assets/images/icon_appraise_ok_selected.gif'; static const String iconAppraiseGoodSelected = - 'assets/images/icon_appraise_good_selected.png'; + 'assets/images/icon_appraise_good_selected.gif'; static const String iconAppraiseSurpriseSelected = - 'assets/images/icon_appraise_surprise_selected.png'; + 'assets/images/icon_appraise_surprise_selected.gif'; static const String iconQuestion = "icons/icon_question.png"; /// 录入项icon From 6e0e92f4580e61b4bc7e105406e5553b29250c49 Mon Sep 17 00:00:00 2001 From: WHOAMI <50095011+echo-LuGuang@users.noreply.github.com> Date: Wed, 14 Dec 2022 11:07:52 +0800 Subject: [PATCH 06/15] =?UTF-8?q?brn=5Ftext=5Finput=5Fitem=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E4=BD=BF=E7=94=A8textInputAction=E5=B1=9E=E6=80=A7=20?= =?UTF-8?q?(#367)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * brn_text_input_item使用textInputAction属性 * 添加obscureText原生属性 --- .../components/form/items/general/brn_text_input_item.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/src/components/form/items/general/brn_text_input_item.dart b/lib/src/components/form/items/general/brn_text_input_item.dart index 1be47869..6f7ab230 100644 --- a/lib/src/components/form/items/general/brn_text_input_item.dart +++ b/lib/src/components/form/items/general/brn_text_input_item.dart @@ -51,6 +51,9 @@ class BrnTextInputFormItem extends StatefulWidget { /// 录入项 是否可编辑 final bool isEdit; + /// 录入项 是否模糊文本(输入后*代替文本,常用于密码框) 默认值:false + final bool obscureText; + /// 录入项不可编辑时(isEdit: false) "+"、"-"号是否可点击 /// true: 可点击回调 false: 不可点击回调 /// 默认值: false @@ -106,6 +109,7 @@ class BrnTextInputFormItem extends StatefulWidget { this.prefixIconType = BrnPrefixIconType.normal, this.error = "", this.isEdit = true, + this.obscureText = false, this.isRequire = false, this.isPrefixIconEnabled = false, this.onAddTap, @@ -195,7 +199,9 @@ class BrnTextInputFormItemState extends State { autofocus: widget.autofocus, focusNode: widget.focusNode, keyboardType: BrnFormUtil.getInputType(widget.inputType), + textInputAction: textInputAction, enabled: widget.isEdit, + obscureText: widget.obscureText, maxLines: 1, maxLength: widget.maxCharCount, style: BrnFormUtil.getIsEditTextStyle( From 1cd04ab9e756e04d9baa6add8acf36c5f45aa7c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=20v?= Date: Wed, 14 Dec 2022 11:10:25 +0800 Subject: [PATCH 07/15] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E5=8C=96=E8=83=BD=E5=8A=9B=20(#279)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feature: i10n、组件优化 * feature: 添加部分函数注释 * [feature]: 翻译统计词条,并替换组件词条 * [feature]: 翻译统计词条,并替换组件词条 * [fix]: 修复 merge 带来的问题 * Update brn_empty_status.dart --- example/lib/main.dart | 41 +- .../empty/abnormal_state_example.dart | 8 +- example/lib/sample/home/home.dart | 29 + example/lib/sample/l10n/l10n.dart | 24 + lib/bruno.dart | 4 + .../actionsheet/brn_common_action_sheet.dart | 3 +- .../brn_selected_list_action_sheet.dart | 7 +- .../actionsheet/brn_share_action_sheet.dart | 7 +- lib/src/components/appraise/brn_appraise.dart | 22 +- .../appraise/brn_appraise_bottom_picker.dart | 17 +- .../appraise/brn_appraise_config.dart | 5 +- .../brn_appraise_emoji_list_view.dart | 15 +- .../appraise/brn_mulit_select_tags.dart | 3 +- .../button/brn_big_ghost_button.dart | 7 +- .../button/brn_big_main_button.dart | 7 +- .../button/brn_big_outline_button.dart | 7 +- .../button/brn_small_main_button.dart | 9 +- .../button/brn_small_outline_button.dart | 9 +- .../brn_multiple_bottom_button.dart | 5 +- .../collection/brn_text_button_panel.dart | 3 +- .../calendar/brn_calendar_view.dart | 27 +- .../content_card/brn_pair_info_table.dart | 5 +- .../dialog/brn_enhance_operation_dialog.dart | 9 +- .../dialog/brn_middle_input_diaolg.dart | 13 +- .../dialog/brn_multi_select_dialog.dart | 7 +- .../components/dialog/brn_share_dialog.dart | 5 +- .../components/dialog/brn_single_select.dart | 7 +- .../components/empty/brn_empty_status.dart | 13 +- .../general/brn_quick_select_input_item.dart | 7 +- .../items/general/brn_range_input_item.dart | 13 +- .../items/general/brn_ratio_input_item.dart | 7 +- .../general/brn_text_block_input_item.dart | 7 +- .../items/general/brn_text_input_item.dart | 7 +- .../items/general/brn_text_select_item.dart | 15 +- .../general/brn_title_select_input_item.dart | 7 +- .../gallery/config/brn_bottom_card.dart | 5 +- .../gallery/page/brn_gallery_detail_page.dart | 3 +- .../page/brn_gallery_summary_page.dart | 3 +- .../components/guide/brn_flutter_guide.dart | 2 +- lib/src/components/guide/brn_tip_widget.dart | 29 +- lib/src/components/input/brn_input_text.dart | 7 +- lib/src/components/loading/brn_loading.dart | 51 +- lib/src/components/navbar/brn_search_bar.dart | 9 +- .../picker/base/brn_picker_title.dart | 10 +- .../picker/base/brn_picker_title_config.dart | 6 +- .../components/picker/brn_bottom_picker.dart | 7 +- .../picker/brn_bottom_write_picker.dart | 35 +- .../picker/brn_mulit_select_tags_picker.dart | 3 +- .../brn_select_tags_with_input_picker.dart | 11 +- .../picker/brn_tags_common_picker.dart | 10 +- .../picker/brn_tags_picker_config.dart | 39 -- .../brn_multi_column_list.dart | 3 +- .../time_picker/brn_date_time_formatter.dart | 49 +- .../date_picker/brn_date_picker.dart | 7 - .../date_picker/brn_date_widget.dart | 5 +- .../date_picker/brn_datetime_widget.dart | 5 +- .../date_picker/brn_time_widget.dart | 5 +- .../brn_date_range_picker.dart | 5 - .../brn_date_range_side_widget.dart | 4 +- .../brn_date_range_widget.dart | 6 +- .../brn_time_range_side_widget.dart | 4 +- .../brn_time_range_widget.dart | 6 +- .../brn_single_select_city_page.dart | 11 +- .../selection/brn_flat_selection.dart | 3 +- .../selection/brn_more_selection.dart | 9 +- .../widget/brn_flat_selection_item.dart | 16 +- .../widget/brn_layer_more_selection_page.dart | 7 +- .../brn_selection_date_range_item_widget.dart | 15 +- .../widget/brn_selection_list_widget.dart | 5 +- .../widget/brn_selection_menu_widget.dart | 8 +- .../brn_selection_more_item_widget.dart | 18 +- ...brn_selection_range_input_item_widget.dart | 7 +- .../brn_selection_range_tag_widget.dart | 5 +- .../widget/brn_selection_range_widget.dart | 9 +- .../brn_selection_single_list_widget.dart | 5 +- .../components/sugsearch/brn_search_text.dart | 5 +- .../components/text/brn_expandable_text.dart | 5 +- lib/src/constants/brn_constants.dart | 13 - lib/src/constants/brn_strings_constants.dart | 9 +- lib/src/l10n/brn_intl.dart | 166 +++++ lib/src/l10n/brn_resources.dart | 579 ++++++++++++++++++ lib/src/utils/i18n/brn_date_picker_i18n.dart | 86 --- lib/src/utils/i18n/brn_strings_zh_cn.dart | 56 -- 83 files changed, 1178 insertions(+), 569 deletions(-) create mode 100644 example/lib/sample/l10n/l10n.dart create mode 100644 lib/src/l10n/brn_intl.dart create mode 100644 lib/src/l10n/brn_resources.dart delete mode 100755 lib/src/utils/i18n/brn_strings_zh_cn.dart diff --git a/example/lib/main.dart b/example/lib/main.dart index af9a7870..15adecb0 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,21 +1,46 @@ - - +import 'package:bruno/bruno.dart'; +import 'sample/l10n/l10n.dart'; import 'package:example/sample/home/home.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; void main() { + BrnIntl.add(ResourceDe.locale, ResourceDe()); runApp(MyApp()); } -class MyApp extends StatelessWidget { +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Example', - theme: ThemeData( - primarySwatch: Colors.blue, + return NotificationListener( + onNotification: (_) { + setState(() {}); + return true; + }, + child: MaterialApp( + locale: ChangeLocalEvent.locale, + localizationsDelegates: [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + BrnLocalizationDelegate.delegate, + ], + supportedLocales: [ + Locale('en', 'US'), + Locale('zh', 'CN'), + Locale('de', 'DE'), + ], + title: 'Flutter Example', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: HomePage(), ), - home: HomePage(), ); } } diff --git a/example/lib/sample/components/empty/abnormal_state_example.dart b/example/lib/sample/components/empty/abnormal_state_example.dart index 68fe5911..2e626589 100644 --- a/example/lib/sample/components/empty/abnormal_state_example.dart +++ b/example/lib/sample/components/empty/abnormal_state_example.dart @@ -27,11 +27,11 @@ class AbnomalStateExample extends StatelessWidget { scale: 3.0, ), isCenterVertical: true, - title: BrnStrings.getDateFailed, - operateTexts: [BrnStrings.clickPageRetry], + title: "获取数据失败,请重试", + operateTexts: ["请点击页面重试"], operateAreaType: OperateAreaType.textButton, action: (index) { - BrnToast.show(BrnStrings.getDateFailed, context); + BrnToast.show("获取数据失败,请重试", context); }, ); break; @@ -42,7 +42,7 @@ class AbnomalStateExample extends StatelessWidget { 'assets/image/no_data.png', scale: 3.0, ), - title: '暂无数据', + title: BrnIntl.of(context).localizedResource.noDataTip, ); break; case 2: diff --git a/example/lib/sample/home/home.dart b/example/lib/sample/home/home.dart index 5e5b2132..9216c2cc 100644 --- a/example/lib/sample/home/home.dart +++ b/example/lib/sample/home/home.dart @@ -5,8 +5,11 @@ import 'package:example/sample/home/card_data_config.dart'; import 'package:example/sample/home/group_card.dart'; import 'package:flutter/material.dart'; +import '../l10n/l10n.dart'; /// 主页面 class HomePage extends StatelessWidget { + GlobalKey _moreKey = GlobalKey(); + @override Widget build(BuildContext context) { return Scaffold( @@ -14,6 +17,32 @@ class HomePage extends StatelessWidget { title: 'UI组件', leading: null, automaticallyImplyLeading: false, + actions: [ + GestureDetector( + child: Icon( + Icons.more_horiz, + key: _moreKey, + color: Colors.black54, + ), + onTap: () { + BrnPopupListWindow.showPopListWindow(context, _moreKey, data: ['切换语言', '测试动态增加语言'], + onItemClick: (int index, item) { + if(index == 0) { + ChangeLocalEvent.locale = ChangeLocalEvent.locale.languageCode == 'zh' + ? Locale('en', 'US') + : Locale('zh', 'CN'); + ChangeLocalEvent()..dispatch(context); + } else { + ChangeLocalEvent.locale = ChangeLocalEvent.locale.languageCode == 'zh' + ? Locale('de', 'DE') + : Locale('zh', 'CN'); + ChangeLocalEvent()..dispatch(context); + } + return false; + }); + }, + ) + ], ), body: _buildBodyWidget(), ); diff --git a/example/lib/sample/l10n/l10n.dart b/example/lib/sample/l10n/l10n.dart new file mode 100644 index 00000000..a98fcaa5 --- /dev/null +++ b/example/lib/sample/l10n/l10n.dart @@ -0,0 +1,24 @@ +import 'package:bruno/bruno.dart'; +import 'package:flutter/cupertino.dart'; + +class ChangeLocalEvent extends Notification{ + static Locale locale = Locale('zh', 'CN'); +} + +class ResourceDe extends BrnResourceEn { + + static Locale locale = Locale('de', 'DE'); + + @override + String get cancel => 'Abbrechen'; + + @override + String get confirm => 'bestätigen'; + + @override + String get loading => 'Wird geladen'; + + @override + String get ok => 'Ok'; + +} \ No newline at end of file diff --git a/lib/bruno.dart b/lib/bruno.dart index d8deab8b..fa29cf7a 100644 --- a/lib/bruno.dart +++ b/lib/bruno.dart @@ -3,6 +3,10 @@ library bruno; // 主题 export 'src/theme/brn_theme.dart'; +// l10n +export 'src/l10n/brn_intl.dart'; +export 'src/l10n/brn_resources.dart'; + //工具类 和 资源 export 'src/components/toast/brn_toast.dart'; export 'src/utils/brn_tools.dart'; diff --git a/lib/src/components/actionsheet/brn_common_action_sheet.dart b/lib/src/components/actionsheet/brn_common_action_sheet.dart index e0158a45..a07914ef 100644 --- a/lib/src/components/actionsheet/brn_common_action_sheet.dart +++ b/lib/src/components/actionsheet/brn_common_action_sheet.dart @@ -1,5 +1,6 @@ import 'dart:ui'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_action_sheet_config.dart'; import 'package:flutter/material.dart'; @@ -285,7 +286,7 @@ class BrnCommonActionSheet extends StatelessWidget { padding: EdgeInsets.only(top: 12, bottom: 12), child: Center( child: Text( - cancelTitle ?? "取消", + cancelTitle ?? BrnIntl.of(context).localizedResource.cancel, style: this.themeData!.cancelStyle.generateTextStyle(), ), ), diff --git a/lib/src/components/actionsheet/brn_selected_list_action_sheet.dart b/lib/src/components/actionsheet/brn_selected_list_action_sheet.dart index 6fe2a758..8da869a1 100644 --- a/lib/src/components/actionsheet/brn_selected_list_action_sheet.dart +++ b/lib/src/components/actionsheet/brn_selected_list_action_sheet.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'package:bruno/src/components/dialog/brn_dialog.dart'; import 'package:bruno/src/components/line/brn_line.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:flutter/material.dart'; @@ -328,7 +329,7 @@ class _BrnActionSheetSelectedItemListState // 如果没有实现 onClear,执行默认弹窗并删除的逻辑 this.dismissContent(true); BrnDialogManager.showConfirmDialog(context, - title: "确定要清空已选列表吗?", cancel: '取消', confirm: '确定', onConfirm: () { + title: BrnIntl.of(context).localizedResource.confirmClearSelectedList, cancel: BrnIntl.of(context).localizedResource.cancel, confirm: BrnIntl.of(context).localizedResource.ok, onConfirm: () { if (widget.itemWidget.onClearConfirmed != null) { widget.itemWidget.onClearConfirmed!(); } @@ -367,7 +368,7 @@ class _BrnActionSheetSelectedItemListState String title = (widget.itemWidget.title != null && widget.itemWidget.title!.isNotEmpty) ? widget.itemWidget.title! - : '已选列表'; + : BrnIntl.of(context).localizedResource.selectedList; TextStyle titleStyle = const TextStyle( fontSize: 18, color: Color(0xff222222), @@ -391,7 +392,7 @@ class _BrnActionSheetSelectedItemListState }, child: Padding( padding: const EdgeInsets.fromLTRB(0, 20, 20, 15), - child: Text("清空", + child: Text(BrnIntl.of(context).localizedResource.clear, textAlign: TextAlign.right, style: TextStyle( fontSize: 16, diff --git a/lib/src/components/actionsheet/brn_share_action_sheet.dart b/lib/src/components/actionsheet/brn_share_action_sheet.dart index d681a7f4..190a679e 100644 --- a/lib/src/components/actionsheet/brn_share_action_sheet.dart +++ b/lib/src/components/actionsheet/brn_share_action_sheet.dart @@ -1,5 +1,6 @@ import 'package:bruno/src/components/line/brn_line.dart'; import 'package:bruno/src/constants/brn_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:flutter/material.dart'; @@ -119,7 +120,7 @@ class BrnShareActionSheet extends StatelessWidget { // 判断是否为自定义标题 title = (channel.shareType == BrnShareItemConstants.shareCustom) ? (channel.customTitle ?? "") - : BrnShareItemConstants.shareItemTitleList[channel.shareType]; + : BrnIntl.of(context).localizedResource.shareChannels[channel.shareType]; // 判断是否为自定义,如果不是自定义图标,则判断是否可点击(决定是否使用置灰图标) image = (channel.shareType == BrnShareItemConstants.shareCustom) ? channel.customImage @@ -208,7 +209,7 @@ class BrnShareActionSheet extends StatelessWidget { alignment: Alignment.centerLeft, padding: EdgeInsets.only(top: 16, left: 20), child: Text( - mainTitle ?? "分享至", + mainTitle ?? BrnIntl.of(context).localizedResource.shareTo, maxLines: 1, textAlign: TextAlign.left, style: TextStyle( @@ -268,7 +269,7 @@ class BrnShareActionSheet extends StatelessWidget { padding: EdgeInsets.only(left: 61, right: 61, top: 12, bottom: 12), child: Center( child: Text( - cancelTitle ?? "取消", + cancelTitle ?? BrnIntl.of(context).localizedResource.cancel, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: textColor), ), diff --git a/lib/src/components/appraise/brn_appraise.dart b/lib/src/components/appraise/brn_appraise.dart index b10d8be3..338f6d3b 100644 --- a/lib/src/components/appraise/brn_appraise.dart +++ b/lib/src/components/appraise/brn_appraise.dart @@ -6,6 +6,7 @@ import 'package:bruno/src/components/button/brn_big_main_button.dart'; import 'package:bruno/src/components/input/brn_input_text.dart'; import 'package:bruno/src/components/picker/brn_tags_picker_config.dart'; import 'package:bruno/src/components/appraise/brn_appraise_config.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:flutter/material.dart'; import 'package:bruno/src/components/appraise/brn_appraise_interface.dart'; @@ -17,7 +18,7 @@ import 'package:bruno/src/components/appraise/brn_appraise_interface.dart'; /// 4. 可以用在页面里面也可以使用在弹窗里面,使用在底部弹窗的参考[BrnAppraiseBottomPicker] /// /// /// /// /// /// /// /// /// / -const BrnAppraiseConfig cConfig = BrnAppraiseConfig(); +const BrnAppraiseConfig cConfig = const BrnAppraiseConfig(); class BrnAppraise extends StatefulWidget { /// 标题 @@ -38,7 +39,7 @@ class BrnAppraise extends StatefulWidget { /// 自定义文案 /// 若评分组件为表情,则list长度为5,不足5个时请在对应位置补空字符串 /// 若评分组件为星星,则list长度不能比count小 - final List iconDescriptions; + List? iconDescriptions; /// 标签 final List? tags; @@ -52,21 +53,12 @@ class BrnAppraise extends StatefulWidget { /// 评价组件的配置项 final BrnAppraiseConfig config; - /// 评价组建每个评分对应的默认文案 - static const List _defaultIconDescriptions = [ - '不好', - '还行', - '满意', - '很棒', - '超惊喜' - ]; - BrnAppraise( {Key? key, this.title = '', this.headerType = BrnAppraiseHeaderType.spaceBetween, this.type = BrnAppraiseType.star, - this.iconDescriptions = _defaultIconDescriptions, + this.iconDescriptions, this.tags, this.inputHintText = '', this.onConfirm, @@ -148,7 +140,7 @@ class _BrnAppraiseState extends State { if (widget.type == BrnAppraiseType.emoji) { return BrnAppraiseEmojiListView( indexes: widget.config.indexes, - titles: widget.iconDescriptions, + titles: widget.iconDescriptions ?? BrnIntl.of(context).localizedResource.appriseLevel, onTap: (index) { setState(() { _appraiseIndex = index; @@ -161,7 +153,7 @@ class _BrnAppraiseState extends State { } else { return BrnAppraiseStarListView( count: widget.config.count, - titles: widget.iconDescriptions, + titles: widget.iconDescriptions ?? BrnIntl.of(context).localizedResource.appriseLevel, hint: widget.config.starAppraiseHint, onTap: (index) { setState(() { @@ -236,7 +228,7 @@ class _BrnAppraiseState extends State { return Padding( padding: EdgeInsets.symmetric(horizontal: 16), child: BrnBigMainButton( - title: widget.config.confirmButtonText, + title: widget.config.confirmButtonText ?? BrnIntl.of(context).localizedResource.submit, isEnable: _enable ?? _appraiseIndex != -1, onTap: () { if (_enable ?? _appraiseIndex != -1) { diff --git a/lib/src/components/appraise/brn_appraise_bottom_picker.dart b/lib/src/components/appraise/brn_appraise_bottom_picker.dart index 9d6d18da..10344ce7 100644 --- a/lib/src/components/appraise/brn_appraise_bottom_picker.dart +++ b/lib/src/components/appraise/brn_appraise_bottom_picker.dart @@ -1,3 +1,4 @@ +import 'package:bruno/bruno.dart'; import 'package:bruno/src/components/appraise/brn_appraise.dart'; import 'package:bruno/src/components/appraise/brn_appraise_header.dart'; import 'package:bruno/src/components/appraise/brn_appraise_config.dart'; @@ -20,7 +21,7 @@ class BrnAppraiseBottomPicker extends StatefulWidget { /// 自定义文案 /// 若评分组件为表情,则list长度为5,不足5个时请在对应位置补空字符串 /// 若评分组件为星星,则list长度不能比count小 - final List iconDescriptions; + final List? iconDescriptions; /// 标签 final List? tags; @@ -34,21 +35,12 @@ class BrnAppraiseBottomPicker extends StatefulWidget { /// 评价组件的配置项 final BrnAppraiseConfig config; - /// 评价组建每个评分对应的默认文案 - static const List _defaultIconDescriptions = [ - '不好', - '还行', - '满意', - '很棒', - '超惊喜' - ]; - BrnAppraiseBottomPicker({ Key? key, this.title = '', this.headerType = BrnAppraiseHeaderType.spaceBetween, this.type = BrnAppraiseType.star, - this.iconDescriptions = _defaultIconDescriptions, + this.iconDescriptions, this.tags, this.inputHintText = '', this.onConfirm, @@ -72,7 +64,8 @@ class _BrnAppraiseBottomPickerState extends State { title: widget.title, headerType: widget.headerType, type: widget.type, - iconDescriptions: widget.iconDescriptions, + iconDescriptions: + widget.iconDescriptions ?? BrnIntl.of(context).localizedResource.appriseLevel, tags: widget.tags, inputHintText: widget.inputHintText, onConfirm: (index, list, input) { diff --git a/lib/src/components/appraise/brn_appraise_config.dart b/lib/src/components/appraise/brn_appraise_config.dart index 5309e308..7a416d5d 100644 --- a/lib/src/components/appraise/brn_appraise_config.dart +++ b/lib/src/components/appraise/brn_appraise_config.dart @@ -1,3 +1,4 @@ +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:flutter/material.dart'; import 'package:bruno/src/components/input/brn_input_text.dart'; import 'package:bruno/src/components/appraise/brn_appraise_interface.dart'; @@ -49,7 +50,7 @@ class BrnAppraiseConfig { final bool showConfirmButton; /// 确认按钮的文案,默认 '提交' - final String confirmButtonText; + final String? confirmButtonText; /// 外部控制提交button的enable状态,null有效,不设置默认值 final bool? isConfirmButtonEnabled; @@ -79,7 +80,7 @@ class BrnAppraiseConfig { this.inputDefaultText, this.inputMaxHeight = 120, this.showConfirmButton = true, - this.confirmButtonText = '提交', + this.confirmButtonText, this.isConfirmButtonEnabled, this.iconClickCallback, this.inputTextChangeCallback, diff --git a/lib/src/components/appraise/brn_appraise_emoji_list_view.dart b/lib/src/components/appraise/brn_appraise_emoji_list_view.dart index b3e57b2b..bf0c9f24 100644 --- a/lib/src/components/appraise/brn_appraise_emoji_list_view.dart +++ b/lib/src/components/appraise/brn_appraise_emoji_list_view.dart @@ -1,5 +1,6 @@ import 'package:bruno/src/components/appraise/brn_appraise_emoji_item.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:flutter/material.dart'; import 'package:bruno/src/components/appraise/brn_appraise_interface.dart'; @@ -12,21 +13,21 @@ class BrnAppraiseEmojiListView extends StatefulWidget { final List indexes; /// 自定义文案,list长度为5,不足5个时请在对应位置补空字符串 - final List titles; + List? titles; /// 点击回调 final BrnAppraiseIconClick? onTap; - static const List _defaultTitles = ['不好', '还行', '满意', '很棒', '超惊喜']; - BrnAppraiseEmojiListView( {Key? key, this.indexes = const [0, 1, 2, 3, 4], - this.titles = _defaultTitles, + this.titles, this.onTap}) : assert(indexes.isNotEmpty), - assert(titles.length == 5), - super(key: key); + super(key: key) { + titles ??= BrnIntl.currentResource.appriseLevel; + assert(titles != null && titles!.length == 5); + } @override _BrnAppraiseEmojiListViewState createState() => @@ -79,7 +80,7 @@ class _BrnAppraiseEmojiListViewState extends State { padding: EdgeInsets.symmetric(horizontal: 7.0 * (6 - widget.indexes.length)), selectedIndex: _selectedIndex, - title: widget.titles[widget.indexes[i]], + title: widget.titles![widget.indexes[i]], onTap: (index) { _selectedIndex = index; if (widget.onTap != null) { diff --git a/lib/src/components/appraise/brn_mulit_select_tags.dart b/lib/src/components/appraise/brn_mulit_select_tags.dart index eb8db051..b580b925 100644 --- a/lib/src/components/appraise/brn_mulit_select_tags.dart +++ b/lib/src/components/appraise/brn_mulit_select_tags.dart @@ -1,4 +1,5 @@ import 'package:bruno/src/components/picker/brn_tags_picker_config.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:flutter/material.dart'; @@ -98,7 +99,7 @@ class _BrnMultiSelectTagsState extends State { Container( height: 200, child: Center( - child: Text('未配置tags数据'), + child: Text(BrnIntl.of(context).localizedResource.noTagDataTip), ), ); } diff --git a/lib/src/components/button/brn_big_ghost_button.dart b/lib/src/components/button/brn_big_ghost_button.dart index c75d2369..0d707316 100644 --- a/lib/src/components/button/brn_big_ghost_button.dart +++ b/lib/src/components/button/brn_big_ghost_button.dart @@ -1,6 +1,7 @@ import 'package:bruno/src/components/button/brn_normal_button.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:flutter/material.dart'; @@ -21,7 +22,7 @@ import 'package:flutter/material.dart'; class BrnBigGhostButton extends StatelessWidget { ///按钮文案,默认'确认' - final String title; + final String? title; ///文案颜色 final Color? titleColor; @@ -38,7 +39,7 @@ class BrnBigGhostButton extends StatelessWidget { const BrnBigGhostButton({ Key? key, - this.title = '确认', + this.title, this.titleColor, this.bgColor, this.onTap, @@ -62,7 +63,7 @@ class BrnBigGhostButton extends StatelessWidget { defaultThemeConfig.commonConfig.brandPrimary.withOpacity(0.05), onTap: onTap, alignment: Alignment.center, - text: title, + text: title ?? BrnIntl.of(context).localizedResource.confirm, textColor: titleColor ?? defaultThemeConfig.commonConfig.brandPrimary, fontSize: defaultThemeConfig.bigButtonFontSize, ); diff --git a/lib/src/components/button/brn_big_main_button.dart b/lib/src/components/button/brn_big_main_button.dart index 0a4cc049..ce091f34 100644 --- a/lib/src/components/button/brn_big_main_button.dart +++ b/lib/src/components/button/brn_big_main_button.dart @@ -1,3 +1,4 @@ +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:flutter/material.dart'; import 'brn_normal_button.dart'; @@ -29,7 +30,7 @@ import 'brn_normal_button.dart'; class BrnBigMainButton extends StatelessWidget { ///按钮显示文案,默认'确认' - final String title; + final String? title; ///是否可用,false 是置灰效果 final bool isEnable; @@ -47,7 +48,7 @@ class BrnBigMainButton extends StatelessWidget { const BrnBigMainButton({ Key? key, - this.title = '确认', + this.title, this.width, this.isEnable = true, this.onTap, @@ -69,7 +70,7 @@ class BrnBigMainButton extends StatelessWidget { height: defaultThemeConfig.bigButtonHeight), alignment: Alignment.center, isEnable: isEnable, - text: title, + text: title ?? BrnIntl.of(context).localizedResource.confirm, borderRadius: BorderRadius.all(Radius.circular(defaultThemeConfig.bigButtonRadius)), fontSize: defaultThemeConfig.bigButtonFontSize, backgroundColor: bgColor ?? defaultThemeConfig.commonConfig.brandPrimary, diff --git a/lib/src/components/button/brn_big_outline_button.dart b/lib/src/components/button/brn_big_outline_button.dart index b6b6804d..c383cb31 100644 --- a/lib/src/components/button/brn_big_outline_button.dart +++ b/lib/src/components/button/brn_big_outline_button.dart @@ -2,6 +2,7 @@ import 'package:bruno/src/components/button/brn_big_ghost_button.dart'; import 'package:bruno/src/components/button/brn_normal_button.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:flutter/material.dart'; @@ -33,7 +34,7 @@ const double _BBorderWith = 1; class BrnBigOutlineButton extends StatelessWidget { ///按钮显示文案,默认'确认' - final String title; + final String? title; ///边框的颜色 final Color? lineColor; @@ -53,7 +54,7 @@ class BrnBigOutlineButton extends StatelessWidget { const BrnBigOutlineButton({ Key? key, - this.title = '确认', + this.title, this.lineColor, this.textColor, this.isEnable = true, @@ -76,7 +77,7 @@ class BrnBigOutlineButton extends StatelessWidget { return BrnNormalButton.outline( borderWith: _BBorderWith, radius: defaultThemeConfig.bigButtonRadius, - text: title, + text: title ?? BrnIntl.of(context).localizedResource.confirm, disableLineColor: _lineColor, lineColor: _lineColor, textColor: textColor ?? defaultThemeConfig.commonConfig.colorTextBase, diff --git a/lib/src/components/button/brn_small_main_button.dart b/lib/src/components/button/brn_small_main_button.dart index 5e56228c..17e13090 100644 --- a/lib/src/components/button/brn_small_main_button.dart +++ b/lib/src/components/button/brn_small_main_button.dart @@ -2,6 +2,7 @@ import 'dart:math'; import 'package:bruno/src/components/button/brn_normal_button.dart'; import 'package:bruno/src/constants/brn_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:flutter/material.dart'; @@ -26,7 +27,7 @@ const double _BMinWidth = 84; class BrnSmallMainButton extends StatelessWidget { /// 按钮显示文案,默认'确认' - final String title; + final String? title; ///点击回调 final VoidCallback? onTap; @@ -47,7 +48,7 @@ class BrnSmallMainButton extends StatelessWidget { /// 传入属性优先级最高,未传入的走默认配置,更多请看[BrnSmallMainButtonConfig.defaultConfig] const BrnSmallMainButton({ Key? key, - this.title = '确认', + this.title, this.onTap, this.isEnable = true, this.bgColor, @@ -81,7 +82,7 @@ class BrnSmallMainButton extends StatelessWidget { color: textColor, ); textPainter.textDirection = TextDirection.ltr; - textPainter.text = TextSpan(text: title, style: style); + textPainter.text = TextSpan(text: title ?? BrnIntl.of(context).localizedResource.confirm, style: style); textPainter.layout(maxWidth: con.maxWidth); double textWidth = textPainter.width; //按钮本身大小 @@ -111,7 +112,7 @@ class BrnSmallMainButton extends StatelessWidget { maxWidth: this.width ?? _maxWidth, ), alignment: Alignment.center, - text: title, + text: title ?? BrnIntl.of(context).localizedResource.confirm, backgroundColor: bgColor ?? defaultThemeConfig.commonConfig.brandPrimary, disableBackgroundColor: Color(0xFFCCCCCC), diff --git a/lib/src/components/button/brn_small_outline_button.dart b/lib/src/components/button/brn_small_outline_button.dart index 4c0c4f92..95df829d 100644 --- a/lib/src/components/button/brn_small_outline_button.dart +++ b/lib/src/components/button/brn_small_outline_button.dart @@ -4,6 +4,7 @@ import 'dart:math'; import 'package:bruno/src/components/button/brn_normal_button.dart'; import 'package:bruno/src/constants/brn_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:flutter/material.dart'; @@ -27,7 +28,7 @@ const double _BBorderWith = 1; class BrnSmallOutlineButton extends StatelessWidget { /// 按钮显示文案,默认'确认 - final String title; + final String? title; /// 点击的回调 final VoidCallback? onTap; @@ -59,7 +60,7 @@ class BrnSmallOutlineButton extends StatelessWidget { /// 传入属性优先级最高,未传入的走默认配置,更多请看[BrnSmallSecondaryOutlineButtonConfig.defaultConfig] const BrnSmallOutlineButton({ Key? key, - this.title = '确认', + this.title, this.onTap, this.isEnable = true, this.lineColor, @@ -94,7 +95,7 @@ class BrnSmallOutlineButton extends StatelessWidget { ); textPainter.textDirection = TextDirection.ltr; - textPainter.text = TextSpan(text: title, style: style); + textPainter.text = TextSpan(text: title ?? BrnIntl.of(context).localizedResource.confirm, style: style); textPainter.layout(maxWidth: con.maxWidth); double textWidth = textPainter.width; double _maxWidth = textWidth + @@ -116,7 +117,7 @@ class BrnSmallOutlineButton extends StatelessWidget { ), borderWith: _BBorderWith, radius: defaultThemeConfig.smallButtonRadius, - text: title, + text: title ?? BrnIntl.of(context).localizedResource.confirm, disableLineColor: defaultThemeConfig.commonConfig.borderColorBase, lineColor: lineColor ?? defaultThemeConfig.commonConfig.borderColorBase, textColor: textColor ?? defaultThemeConfig.commonConfig.colorTextBase, diff --git a/lib/src/components/button/collection/brn_multiple_bottom_button.dart b/lib/src/components/button/collection/brn_multiple_bottom_button.dart index 5cb5dcbc..adcfdf15 100644 --- a/lib/src/components/button/collection/brn_multiple_bottom_button.dart +++ b/lib/src/components/button/collection/brn_multiple_bottom_button.dart @@ -2,6 +2,7 @@ import 'package:bruno/src/components/radio/brn_checkbox.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:flutter/material.dart'; @@ -130,7 +131,7 @@ class _BrnMultipleBottomButtonState extends State { Container( padding: EdgeInsets.only(left: 4, right: 8), child: Text( - '全选', + BrnIntl.of(context).localizedResource.selectAll, style: TextStyle(color: Color(0XFF222222), fontSize: 16), ), ), @@ -174,7 +175,7 @@ class _BrnMultipleBottomButtonState extends State { child: Row( children: [ Text( - '已选', + BrnIntl.of(context).localizedResource.selected, style: TextStyle(color: Color(0XFF222222), fontSize: 16), ), ValueListenableBuilder( diff --git a/lib/src/components/button/collection/brn_text_button_panel.dart b/lib/src/components/button/collection/brn_text_button_panel.dart index 63e20acb..2d6864e0 100644 --- a/lib/src/components/button/collection/brn_text_button_panel.dart +++ b/lib/src/components/button/collection/brn_text_button_panel.dart @@ -1,5 +1,6 @@ import 'package:bruno/src/components/popup/brn_popup_window.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/utils/brn_multi_click_util.dart'; import 'package:bruno/src/utils/brn_tools.dart'; @@ -128,7 +129,7 @@ class _BrnTextButtonPanelState extends State { } Text tx = Text( - _isExpanded ? '收起' : '更多', + _isExpanded ? BrnIntl.of(context).localizedResource.collapse : BrnIntl.of(context).localizedResource.more, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( diff --git a/lib/src/components/calendar/brn_calendar_view.dart b/lib/src/components/calendar/brn_calendar_view.dart index 7fdfae0d..58c8b8b9 100644 --- a/lib/src/components/calendar/brn_calendar_view.dart +++ b/lib/src/components/calendar/brn_calendar_view.dart @@ -1,4 +1,5 @@ import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:flutter/material.dart'; @@ -16,17 +17,15 @@ enum DisplayMode { week, month } /// 时间选择模式,单个时间,时间范围 enum SelectMode { single, range } -const List _defaultWeekNames = ['日', '一', '二', '三', '四', '五', '六']; - /// 日历组件 包括月视图,周视图、日期单选、日期范围选等功能。 /// 1、点击不同月份日期,自动切换到最新选中日期所在月份。 /// 2、日历组件支持时间范围展示,仅展示范围内的日历视图,范围外日期置灰不可点击。日期范围边界后不可再翻页。 class BrnCalendarView extends StatefulWidget { - const BrnCalendarView( + BrnCalendarView( {Key? key, this.selectMode = SelectMode.single, this.displayMode = DisplayMode.month, - this.weekNames = _defaultWeekNames, + this.weekNames, this.showControllerBar = true, this.initStartSelectedDate, this.initEndSelectedDate, @@ -35,15 +34,14 @@ class BrnCalendarView extends StatefulWidget { this.rangeDateChange, this.minDate, this.maxDate}) - : assert(weekNames.length == 7), - assert(selectMode == SelectMode.single && dateChange != null || + : assert(selectMode == SelectMode.single && dateChange != null || selectMode == SelectMode.range && rangeDateChange != null), super(key: key); - const BrnCalendarView.single( + BrnCalendarView.single( {Key? key, this.displayMode = DisplayMode.month, - this.weekNames = _defaultWeekNames, + this.weekNames, this.showControllerBar = true, this.initStartSelectedDate, this.initEndSelectedDate, @@ -53,13 +51,12 @@ class BrnCalendarView extends StatefulWidget { this.maxDate}) : this.selectMode = SelectMode.single, this.rangeDateChange = null, - assert(weekNames.length == 7), super(key: key); - const BrnCalendarView.range( + BrnCalendarView.range( {Key? key, this.displayMode = DisplayMode.month, - this.weekNames = _defaultWeekNames, + this.weekNames, this.showControllerBar = true, this.initStartSelectedDate, this.initEndSelectedDate, @@ -69,7 +66,6 @@ class BrnCalendarView extends StatefulWidget { this.maxDate}) : this.selectMode = SelectMode.range, this.dateChange = null, - assert(weekNames.length == 7), super(key: key); /// 展示模式, Week, Month @@ -98,7 +94,7 @@ class BrnCalendarView extends StatefulWidget { final bool showControllerBar; /// 自定义星期的名称 - final List weekNames; + List? weekNames; /// 初始展示月份 /// @@ -124,6 +120,7 @@ class _CustomCalendarViewState extends State { @override void initState() { + assert(widget.weekNames != null && widget.weekNames!.length == 7); _displayMode = widget.displayMode; _currentDate = widget.initDisplayDate ?? DateTime.now(); _minDate = widget.minDate ?? DateTime(1970); @@ -226,7 +223,7 @@ class _CustomCalendarViewState extends State { Expanded( child: Center( child: Text( - DateFormat('yyyy年MM月').format(_currentDate), + DateFormat(BrnIntl.of(context).localizedResource.dateFormate_yyyy_MM).format(_currentDate), style: TextStyle( fontWeight: FontWeight.w600, fontSize: 16, @@ -627,6 +624,6 @@ class _CustomCalendarViewState extends State { } String _getChinaWeekName(int weekOfDay) { - return widget.weekNames[weekOfDay]; + return (widget.weekNames ?? BrnIntl.of(context).localizedResource.weekMinName)[weekOfDay]; } } diff --git a/lib/src/components/card/content_card/brn_pair_info_table.dart b/lib/src/components/card/content_card/brn_pair_info_table.dart index 55a90339..41ad6a57 100644 --- a/lib/src/components/card/content_card/brn_pair_info_table.dart +++ b/lib/src/components/card/content_card/brn_pair_info_table.dart @@ -2,6 +2,7 @@ import 'dart:math'; import 'dart:ui' as ui; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:bruno/src/utils/brn_rich_text.dart'; import 'package:bruno/src/utils/brn_tools.dart'; @@ -287,7 +288,7 @@ class _BrnPairInfoTableState extends State { Padding( padding: EdgeInsets.only(right: 4), child: Text( - '展开', + BrnIntl.of(context).localizedResource.expand, style: TextStyle( fontSize: 14, color: themeData.commonConfig.colorTextSecondary, @@ -346,7 +347,7 @@ class _BrnPairInfoTableState extends State { Padding( padding: EdgeInsets.only(right: 4), child: Text( - '收起', + BrnIntl.of(context).localizedResource.collapse, style: TextStyle( fontSize: 14, color: themeData.commonConfig.colorTextSecondary, diff --git a/lib/src/components/dialog/brn_enhance_operation_dialog.dart b/lib/src/components/dialog/brn_enhance_operation_dialog.dart index 24263dcc..70f41138 100644 --- a/lib/src/components/dialog/brn_enhance_operation_dialog.dart +++ b/lib/src/components/dialog/brn_enhance_operation_dialog.dart @@ -1,6 +1,7 @@ import 'package:bruno/src/components/button/brn_big_main_button.dart'; import 'package:bruno/src/components/dialog/brn_dialog.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_dialog_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; @@ -47,7 +48,7 @@ class BrnEnhanceOperationDialog extends StatelessWidget { final String? descText; /// 主要按钮文本 - final String mainButtonText; + final String? mainButtonText; /// 次要按钮文案,为空则不显示次要按钮 final String? secondaryButtonText; @@ -67,7 +68,7 @@ class BrnEnhanceOperationDialog extends StatelessWidget { required this.context, this.titleText, this.descText, - this.mainButtonText = '确认', + this.mainButtonText, this.secondaryButtonText, this.onMainButtonClick, this.onSecondaryButtonClick, @@ -151,9 +152,9 @@ class BrnEnhanceOperationDialog extends StatelessWidget { return Container( padding: EdgeInsets.only(left: 20, right: 20), child: BrnBigMainButton( - title: mainButtonText, + title: mainButtonText ?? BrnIntl.of(context).localizedResource.confirm, onTap: () { - Navigator.of(context).pop(mainButtonText); + Navigator.of(context).pop(mainButtonText ?? BrnIntl.of(context).localizedResource.confirm); }, ), ); diff --git a/lib/src/components/dialog/brn_middle_input_diaolg.dart b/lib/src/components/dialog/brn_middle_input_diaolg.dart index f188e41f..259c2d5b 100644 --- a/lib/src/components/dialog/brn_middle_input_diaolg.dart +++ b/lib/src/components/dialog/brn_middle_input_diaolg.dart @@ -1,3 +1,4 @@ +import 'package:bruno/bruno.dart'; import 'package:bruno/src/components/dialog/brn_dialog.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:flutter/material.dart'; @@ -18,10 +19,10 @@ class BrnMiddleInputDialog { final int maxLength; /// 取消操作标题,默认 '取消' - final String cancelText; + final String? cancelText; /// 确定操作标题,默认 '确定' - final String confirmText; + final String? confirmText; /// 点击确定时的回调,参数为输入框中的字符 final void Function(String value)? onConfirm; @@ -74,8 +75,8 @@ class BrnMiddleInputDialog { this.inputEditingController, this.inputFormatters, this.textInputAction = TextInputAction.newline, - this.cancelText = '取消', - this.confirmText = '确定', + this.cancelText, + this.confirmText, this.onConfirm, this.onCancel, this.dismissOnActionsTap = true, @@ -177,8 +178,8 @@ class BrnMiddleInputDialog { ), )); return BrnDialogManager.showConfirmDialog(context, - cancel: cancelText, - confirm: confirmText, + cancel: cancelText ?? BrnIntl.of(context).localizedResource.cancel, + confirm: confirmText ?? BrnIntl.of(context).localizedResource.ok, title: title, barrierDismissible: barrierDismissible, themeData: themeData, diff --git a/lib/src/components/dialog/brn_multi_select_dialog.dart b/lib/src/components/dialog/brn_multi_select_dialog.dart index 18a80dcb..0cdd2481 100644 --- a/lib/src/components/dialog/brn_multi_select_dialog.dart +++ b/lib/src/components/dialog/brn_multi_select_dialog.dart @@ -1,6 +1,7 @@ import 'package:bruno/src/components/dialog/brn_content_export_dialog.dart'; import 'package:bruno/src/components/line/brn_line.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:flutter/material.dart'; @@ -44,7 +45,7 @@ class BrnMultiSelectDialog extends Dialog { final List conditions; /// 操作按钮文案 - final String submitText; + final String? submitText; /// 点击操作按钮 final BrnMultiSelectDialogClickSubmitCallback? onSubmitClick; @@ -72,7 +73,7 @@ class BrnMultiSelectDialog extends Dialog { this.messageWidget, this.customWidget, this.isCustomFollowScroll = true, - this.submitText = "提交", + this.submitText, this.submitBgColor, this.onSubmitClick, this.onItemClick, @@ -89,7 +90,7 @@ class BrnMultiSelectDialog extends Dialog { customWidget: customWidget, isCustomFollowScroll: isCustomFollowScroll, conditions: conditions, - submitText: submitText, + submitText: submitText ?? BrnIntl.of(context).localizedResource.submit, onSubmitClick: onSubmitClick, onItemClick: onItemClick, submitBgColor: submitBgColor ?? diff --git a/lib/src/components/dialog/brn_share_dialog.dart b/lib/src/components/dialog/brn_share_dialog.dart index 6900bf60..07a4e489 100644 --- a/lib/src/components/dialog/brn_share_dialog.dart +++ b/lib/src/components/dialog/brn_share_dialog.dart @@ -2,6 +2,7 @@ import 'package:bruno/src/components/dialog/brn_dialog.dart'; import 'package:bruno/src/components/dialog/brn_dialog_utils.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; import 'package:bruno/src/constants/brn_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_dialog_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; @@ -184,7 +185,7 @@ class BrnShareDialog extends StatelessWidget { color: Color(0xffffffff), padding: EdgeInsets.only(left: 6, right: 6), child: Text( - separatorText ?? "你可以通过以下方式分享给客户", + separatorText ?? BrnIntl.of(context).localizedResource.shareWayTip, style: TextStyle(fontSize: 12, color: shareTextColor), ), ), @@ -211,7 +212,7 @@ class BrnShareDialog extends StatelessWidget { } } else { // 获取自预设channel信息 - title = BrnShareItemConstants.shareItemTitleList[shareChannels[index]]; + title = BrnIntl.of(context).localizedResource.shareChannels[shareChannels[index]]; image = BrunoTools.getAssetImage( BrnShareItemConstants.shareItemImagePathList[shareChannels[index]]); } diff --git a/lib/src/components/dialog/brn_single_select.dart b/lib/src/components/dialog/brn_single_select.dart index 563192e8..6aab2cdd 100644 --- a/lib/src/components/dialog/brn_single_select.dart +++ b/lib/src/components/dialog/brn_single_select.dart @@ -1,6 +1,7 @@ import 'package:bruno/src/components/dialog/brn_dialog_utils.dart'; import 'package:bruno/src/components/line/brn_line.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_dialog_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; @@ -30,7 +31,7 @@ class BrnSingleSelectDialog extends Dialog { final List conditions; /// 确定/提交 按钮文案,默认 '提交' - final String submitText; + final String? submitText; /// 提交按钮点击回调 final BrnSingleSelectOnSubmitCallback? onSubmitClick; @@ -62,7 +63,7 @@ class BrnSingleSelectDialog extends Dialog { this.messageText, this.messageWidget, required this.conditions, - this.submitText: "提交", + this.submitText, this.submitBgColor, this.onSubmitClick, this.onItemClick, @@ -80,7 +81,7 @@ class BrnSingleSelectDialog extends Dialog { messageText: messageText, messageWidget: messageWidget, conditions: conditions, - submitText: submitText, + submitText: submitText ?? BrnIntl.of(context).localizedResource.submit, onSubmitClick: onSubmitClick, onItemClick: onItemClick, submitBgColor: submitBgColor, diff --git a/lib/src/components/empty/brn_empty_status.dart b/lib/src/components/empty/brn_empty_status.dart index afb69f27..9defb005 100644 --- a/lib/src/components/empty/brn_empty_status.dart +++ b/lib/src/components/empty/brn_empty_status.dart @@ -1,5 +1,6 @@ import 'package:bruno/src/constants/brn_asset_constants.dart'; import 'package:bruno/src/constants/brn_strings_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_abnormal_state_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; @@ -29,22 +30,22 @@ class BrnAbnormalStateUtils { {Image? img, BrnEmptyStatusIndexedActionClickCallback? action}) { if (AbnormalState.getDataFailed == status) { return BrnAbnormalStateWidget( - img: img ?? BrunoTools.getAssetImage(BrnAsset.contentFailed), - title: BrnStrings.getDateFailed, - operateTexts: [BrnStrings.clickPageRetry], + img: img ?? BrunoTools.getAssetImage(BrnAsset.noData), + title: BrnIntl.of(context).localizedResource.fetchErrorAndRetry, + operateTexts: [BrnIntl.of(context).localizedResource.clickPageAndRetry], action: action, ); } else if (AbnormalState.networkConnectError == status) { return BrnAbnormalStateWidget( img: img ?? BrunoTools.getAssetImage(BrnAsset.networkError), - title: BrnStrings.networkConnectError, - operateTexts: [BrnStrings.clickPageRetry], + title: BrnIntl.of(context).localizedResource.netErrorAndRetryLater, + operateTexts: [BrnIntl.of(context).localizedResource.clickPageAndRetry], action: action, ); } else if (AbnormalState.noData == status) { return BrnAbnormalStateWidget( img: img ?? BrunoTools.getAssetImage(BrnAsset.noData), - title: BrnStrings.noData, + title: BrnIntl.of(context).localizedResource.noDataTip ); } else { return const SizedBox.shrink(); diff --git a/lib/src/components/form/items/general/brn_quick_select_input_item.dart b/lib/src/components/form/items/general/brn_quick_select_input_item.dart index 9fa73013..99249f68 100644 --- a/lib/src/components/form/items/general/brn_quick_select_input_item.dart +++ b/lib/src/components/form/items/general/brn_quick_select_input_item.dart @@ -2,6 +2,7 @@ import 'package:bruno/src/components/form/base/brn_form_item_type.dart'; import 'package:bruno/src/components/form/utils/brn_form_util.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_form_config.dart'; import 'package:bruno/src/constants/brn_fonts_constants.dart'; @@ -63,7 +64,7 @@ class BrnTextQuickSelectFormItem extends StatefulWidget { final ValueChanged? onBtnSelectChanged; /// 录入项 hint 提示 - final String hint; + final String? hint; /// 录入项 值 String? value; @@ -101,7 +102,7 @@ class BrnTextQuickSelectFormItem extends StatefulWidget { this.onAddTap, this.onRemoveTap, this.onTip, - this.hint: "请选择", + this.hint, this.value, this.btnsTxt, this.selectBtnList, @@ -230,7 +231,7 @@ class BrnTextQuickSelectFormItemState ); } else { return Text( - widget.hint, + widget.hint ?? BrnIntl.of(context).localizedResource.pleaseChoose, textAlign: TextAlign.end, style: BrnFormUtil.getHintTextStyle(widget.themeData!), ); diff --git a/lib/src/components/form/items/general/brn_range_input_item.dart b/lib/src/components/form/items/general/brn_range_input_item.dart index ca08cb56..15fa1fa5 100644 --- a/lib/src/components/form/items/general/brn_range_input_item.dart +++ b/lib/src/components/form/items/general/brn_range_input_item.dart @@ -2,6 +2,7 @@ import 'package:bruno/src/components/form/base/brn_form_item_type.dart'; import 'package:bruno/src/components/form/utils/brn_form_util.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_form_config.dart'; import 'package:bruno/src/constants/brn_fonts_constants.dart'; @@ -62,10 +63,10 @@ class BrnRangeInputFormItem extends StatefulWidget { final VoidCallback? onTip; /// 最小值提示语 - final String hintMin; + String? hintMin; /// 最大值提示语 - final String hintMax; + String? hintMax; /// 最小值单位 final String? minUnit; @@ -113,8 +114,8 @@ class BrnRangeInputFormItem extends StatefulWidget { this.onAddTap, this.onRemoveTap, this.onTip, - this.hintMin: '最小', - this.hintMax: '最大', + this.hintMin, + this.hintMax, this.minUnit, this.maxUnit, this.leftMaxCount, @@ -212,7 +213,7 @@ class BrnRangeInputFormItemState extends State { border: InputBorder.none, hintStyle: BrnFormUtil.getHintTextStyle(widget.themeData!), - hintText: widget.hintMin, + hintText: widget.hintMin ?? BrnIntl.of(context).localizedResource.min, counterText: "", contentPadding: EdgeInsets.all(0), isDense: true, @@ -267,7 +268,7 @@ class BrnRangeInputFormItemState extends State { border: InputBorder.none, hintStyle: BrnFormUtil.getHintTextStyle(widget.themeData!), - hintText: widget.hintMax, + hintText: widget.hintMax ?? BrnIntl.of(context).localizedResource.max, counterText: "", contentPadding: EdgeInsets.all(0), isDense: true, diff --git a/lib/src/components/form/items/general/brn_ratio_input_item.dart b/lib/src/components/form/items/general/brn_ratio_input_item.dart index 7f9e402c..e166748a 100644 --- a/lib/src/components/form/items/general/brn_ratio_input_item.dart +++ b/lib/src/components/form/items/general/brn_ratio_input_item.dart @@ -2,6 +2,7 @@ import 'package:bruno/src/components/form/base/brn_form_item_type.dart'; import 'package:bruno/src/components/form/utils/brn_form_util.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_form_config.dart'; import 'package:flutter/material.dart'; @@ -61,7 +62,7 @@ class BrnRatioInputFormItem extends StatefulWidget { final VoidCallback? onTip; ///内容 - final String hint; + final String? hint; /// 输入内容类型 final String? inputType; @@ -91,7 +92,7 @@ class BrnRatioInputFormItem extends StatefulWidget { this.onAddTap, this.onRemoveTap, this.onTip, - this.hint: "请输入", + this.hint, this.inputType, this.controller, this.inputFormatters, @@ -180,7 +181,7 @@ class BrnRatioInputFormItemState extends State { border: InputBorder.none, hintStyle: BrnFormUtil.getHintTextStyle(widget.themeData!), - hintText: widget.hint, + hintText: widget.hint ?? BrnIntl.of(context).localizedResource.pleaseEnter, counterText: "", contentPadding: EdgeInsets.all(0), isDense: true, diff --git a/lib/src/components/form/items/general/brn_text_block_input_item.dart b/lib/src/components/form/items/general/brn_text_block_input_item.dart index aa292ef3..c77093e7 100644 --- a/lib/src/components/form/items/general/brn_text_block_input_item.dart +++ b/lib/src/components/form/items/general/brn_text_block_input_item.dart @@ -1,5 +1,6 @@ import 'package:bruno/src/components/form/base/brn_form_item_type.dart'; import 'package:bruno/src/components/form/utils/brn_form_util.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -61,7 +62,7 @@ class BrnTextBlockInputFormItem extends StatefulWidget { final int? maxCharCount; /// 录入项 hint 提示 - final String hint; + final String? hint; /// 输入内容类型 final String? inputType; @@ -104,7 +105,7 @@ class BrnTextBlockInputFormItem extends StatefulWidget { this.onRemoveTap, this.onTip, this.onChanged, - this.hint = "请输入", + this.hint, this.maxCharCount, this.autofocus: false, this.inputType, @@ -199,7 +200,7 @@ class BrnTextBlockInputFormItemState extends State { widget.themeData!, widget.isEdit), inputFormatters: widget.inputFormatters, decoration: InputDecoration( - hintText: widget.hint, + hintText: widget.hint ?? BrnIntl.of(context).localizedResource.pleaseEnter, hintStyle: BrnFormUtil.getHintTextStyle(widget.themeData!), contentPadding: EdgeInsets.all(0), border: InputBorder.none, diff --git a/lib/src/components/form/items/general/brn_text_input_item.dart b/lib/src/components/form/items/general/brn_text_input_item.dart index 6f7ab230..3055f279 100644 --- a/lib/src/components/form/items/general/brn_text_input_item.dart +++ b/lib/src/components/form/items/general/brn_text_input_item.dart @@ -1,5 +1,6 @@ import 'package:bruno/src/components/form/base/brn_form_item_type.dart'; import 'package:bruno/src/components/form/utils/brn_form_util.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_form_config.dart'; import 'package:bruno/src/constants/brn_fonts_constants.dart'; @@ -72,7 +73,7 @@ class BrnTextInputFormItem extends StatefulWidget { final String? prefixText; /// 提示文案 - final String hint; + final String? hint; /// 单位 final String? unit; @@ -116,7 +117,7 @@ class BrnTextInputFormItem extends StatefulWidget { this.onRemoveTap, this.onTip, this.prefixText, - this.hint = "请输入", + this.hint, this.unit, this.maxCharCount, this.autofocus: false, @@ -210,7 +211,7 @@ class BrnTextInputFormItemState extends State { border: InputBorder.none, hintStyle: BrnFormUtil.getHintTextStyle(widget.themeData!), - hintText: widget.hint, + hintText: widget.hint?? BrnIntl.of(context).localizedResource.pleaseEnter, counterText: "", contentPadding: EdgeInsets.all(0), isDense: true, diff --git a/lib/src/components/form/items/general/brn_text_select_item.dart b/lib/src/components/form/items/general/brn_text_select_item.dart index 57ae557e..52aaeff9 100644 --- a/lib/src/components/form/items/general/brn_text_select_item.dart +++ b/lib/src/components/form/items/general/brn_text_select_item.dart @@ -2,6 +2,7 @@ import 'dart:math'; +import 'package:bruno/bruno.dart'; import 'package:bruno/src/components/form/base/brn_form_item_type.dart'; import 'package:bruno/src/components/form/utils/brn_form_util.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; @@ -64,7 +65,7 @@ class BrnTextSelectFormItem extends StatefulWidget { final VoidCallback? onTap; /// 录入项 hint 提示 - final String hint; + final String? hint; /// 录入项 值 final String? value; @@ -101,7 +102,7 @@ class BrnTextSelectFormItem extends StatefulWidget { this.onAddTap, this.onRemoveTap, this.onTip, - this.hint: "请选择", + this.hint, this.value, this.valueMaxLines = 1, this.titleMaxLines, @@ -132,7 +133,7 @@ class BrnTextSelectFormItem extends StatefulWidget { this.onAddTap, this.onRemoveTap, this.onTip, - this.hint: "请选择", + this.hint, this.value, this.valueMaxLines = 1, this.titleMaxLines, @@ -369,7 +370,7 @@ class BrnTextSelectFormItemState extends State { textDirection: TextDirection.ltr, strutStyle: _contentStructStyle, text: TextSpan( - text: widget.hint, + text: widget.hint ?? BrnIntl.of(context).localizedResource.pleaseChoose, style: BrnFormUtil.getHintTextStyle(widget.themeData!, height: 1), )); } @@ -392,7 +393,7 @@ class BrnTextSelectFormItemState extends State { ); } else { return Text( - widget.hint, + widget.hint ?? BrnIntl.of(context).localizedResource.pleaseChoose, textAlign: TextAlign.end, strutStyle: _contentStructStyle, style: BrnFormUtil.getHintTextStyle(widget.themeData!, height: 1), @@ -401,11 +402,11 @@ class BrnTextSelectFormItemState extends State { } String getCalculateText() { - String value = '请选择'; + String value = BrnIntl.of(context).localizedResource.pleaseChoose; if (!BrunoTools.isEmpty(widget.value)) { value = widget.value!; } else if (!BrunoTools.isEmpty(widget.hint)) { - value = widget.hint; + value = widget.hint ?? BrnIntl.of(context).localizedResource.pleaseChoose; } return value; } diff --git a/lib/src/components/form/items/general/brn_title_select_input_item.dart b/lib/src/components/form/items/general/brn_title_select_input_item.dart index ccb27a80..a115c38d 100644 --- a/lib/src/components/form/items/general/brn_title_select_input_item.dart +++ b/lib/src/components/form/items/general/brn_title_select_input_item.dart @@ -5,6 +5,7 @@ import 'package:bruno/src/components/form/base/input_item_interface.dart'; import 'package:bruno/src/components/form/utils/brn_form_util.dart'; import 'package:bruno/src/components/popup/brn_popup_window.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_form_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; @@ -66,7 +67,7 @@ class BrnTitleSelectInputFormItem extends StatefulWidget { final VoidCallback? onTip; /// 提示文案 - final String hint; + final String? hint; /// 最大可输入字符数 final int? maxCount; @@ -112,7 +113,7 @@ class BrnTitleSelectInputFormItem extends StatefulWidget { this.onAddTap, this.onRemoveTap, this.onTip, - this.hint = "请输入", + this.hint, this.maxCount, this.inputType = BrnInputType.text, this.selectedIndex = -1, @@ -311,7 +312,7 @@ class BrnTitleSelectInputFormItemState color: Color(0xFFCCCCCC), fontSize: BrnFonts.f16, textBaseline: TextBaseline.alphabetic), - hintText: widget.hint, + hintText: widget.hint ?? BrnIntl.of(context).localizedResource.pleaseEnter, counterText: "", contentPadding: EdgeInsets.all(0), isDense: true, diff --git a/lib/src/components/gallery/config/brn_bottom_card.dart b/lib/src/components/gallery/config/brn_bottom_card.dart index e811c5bb..02c983a4 100644 --- a/lib/src/components/gallery/config/brn_bottom_card.dart +++ b/lib/src/components/gallery/config/brn_bottom_card.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/configs/brn_gallery_detail_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:flutter/material.dart'; @@ -74,7 +75,7 @@ class _BrnPhotoBottomCardState extends State children: [ Padding( padding: EdgeInsets.only(right: 4), - child: Text('展开', + child: Text(BrnIntl.of(context).localizedResource.expand, style: widget.themeData!.actionStyle.generateTextStyle()), ), @@ -112,7 +113,7 @@ class _BrnPhotoBottomCardState extends State children: [ Padding( padding: EdgeInsets.only(right: 4), - child: Text('收起', + child: Text(BrnIntl.of(context).localizedResource.collapse, style: widget.themeData!.actionStyle .generateTextStyle()), ), diff --git a/lib/src/components/gallery/page/brn_gallery_detail_page.dart b/lib/src/components/gallery/page/brn_gallery_detail_page.dart index fa1573a5..ba4b5ef1 100644 --- a/lib/src/components/gallery/page/brn_gallery_detail_page.dart +++ b/lib/src/components/gallery/page/brn_gallery_detail_page.dart @@ -5,6 +5,7 @@ import 'package:bruno/src/components/gallery/config/brn_controller.dart'; import 'package:bruno/src/components/gallery/page/brn_gallery_summary_page.dart'; import 'package:bruno/src/components/navbar/brn_appbar.dart'; import 'package:bruno/src/components/tabbar/normal/brn_tab_bar.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_appbar_config.dart'; import 'package:bruno/src/theme/configs/brn_gallery_detail_config.dart'; @@ -273,7 +274,7 @@ class _BrnGalleryDetailPageState extends State valueListenable: _titleNotifier!, ) : BrnTextAction( - '全部图片', + BrnIntl.of(context).localizedResource.allPics, themeData: _appBarConfig, iconPressed: () { if (widget.fromSummary) { diff --git a/lib/src/components/gallery/page/brn_gallery_summary_page.dart b/lib/src/components/gallery/page/brn_gallery_summary_page.dart index 30e07e9e..647e404a 100644 --- a/lib/src/components/gallery/page/brn_gallery_summary_page.dart +++ b/lib/src/components/gallery/page/brn_gallery_summary_page.dart @@ -4,6 +4,7 @@ import 'package:bruno/src/components/gallery/page/brn_gallery_detail_page.dart'; import 'package:bruno/src/components/navbar/brn_appbar.dart'; import 'package:bruno/src/components/scroll_anchor/brn_scroll_anchor_tab.dart'; import 'package:bruno/src/components/tabbar/normal/brn_tab_bar.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -69,7 +70,7 @@ class _BrnGallerySummaryPageState extends State { return Scaffold( backgroundColor: Colors.white, appBar: BrnAppBar( - title: "全部图片", + title: BrnIntl.of(context).localizedResource.allPics, ), body: Container(color: Colors.white, child: _body()), ); diff --git a/lib/src/components/guide/brn_flutter_guide.dart b/lib/src/components/guide/brn_flutter_guide.dart index 5eac9e50..bcf0ce4d 100644 --- a/lib/src/components/guide/brn_flutter_guide.dart +++ b/lib/src/components/guide/brn_flutter_guide.dart @@ -139,7 +139,7 @@ class BrnGuide { _widgetWidth = 0; _widgetHeight = 0; _widgetOffset = Offset.zero; - debugPrint('获取组件尺寸信息异常${e.toString()}'); + debugPrint('get screen size error: ${e.toString()}'); } } diff --git a/lib/src/components/guide/brn_tip_widget.dart b/lib/src/components/guide/brn_tip_widget.dart index d1cefe3b..58b84d71 100644 --- a/lib/src/components/guide/brn_tip_widget.dart +++ b/lib/src/components/guide/brn_tip_widget.dart @@ -1,6 +1,7 @@ import 'package:bruno/src/components/button/brn_icon_button.dart'; import 'package:bruno/src/components/guide/brn_flutter_guide.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:flutter/material.dart'; @@ -52,7 +53,7 @@ class BrnTipInfoWidget extends StatelessWidget { return Column( verticalDirection: VerticalDirection.up, children: [ - buildContent(), + _buildContent(context), Container( alignment: direction == GuideDirection.bottomLeft ? Alignment.bottomRight @@ -75,7 +76,7 @@ class BrnTipInfoWidget extends StatelessWidget { direction == GuideDirection.topRight) { return Column( children: [ - buildContent(), + _buildContent(context), Container( alignment: direction == GuideDirection.topLeft ? Alignment.topRight @@ -97,7 +98,7 @@ class BrnTipInfoWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - buildContent(), + _buildContent(context), Container( alignment: Alignment.topLeft, padding: EdgeInsets.only(top: 12), @@ -116,7 +117,7 @@ class BrnTipInfoWidget extends StatelessWidget { textDirection: TextDirection.rtl, verticalDirection: VerticalDirection.up, children: [ - buildContent(), + _buildContent(context), Container( alignment: Alignment.centerLeft, padding: EdgeInsets.only(top: 12), @@ -134,7 +135,7 @@ class BrnTipInfoWidget extends StatelessWidget { return Row(); } - Widget buildContent() { + Widget _buildContent(BuildContext context) { return Container( decoration: BoxDecoration( boxShadow: [ @@ -157,7 +158,7 @@ class BrnTipInfoWidget extends StatelessWidget { buildImage(), buildTitle(), buildMessage(), - mode == GuideMode.force ? buildForceBottom() : buildSoftBottom() + mode == GuideMode.force ? _buildForceBottom(context) : _buildSoftBottom(context) ], ), ); @@ -220,7 +221,7 @@ class BrnTipInfoWidget extends StatelessWidget { ); } - Widget buildSoftBottom() { + Widget _buildSoftBottom(BuildContext context) { if (onNext == null && onSkip == null) return Row(); return Container( height: 32, @@ -241,7 +242,7 @@ class BrnTipInfoWidget extends StatelessWidget { onSkip!(); }, child: Text( - '跳过 (${currentStepIndex + 1}/$stepCount)', + '${BrnIntl.of(context).localizedResource.skip} (${currentStepIndex + 1}/$stepCount)', style: TextStyle(color: Color(0xFF999999), fontSize: 14), ), @@ -273,8 +274,8 @@ class BrnTipInfoWidget extends StatelessWidget { child: Text( nextTip ?? (stepCount == currentStepIndex + 1 - ? '我知道了' - : '下一步'), + ? BrnIntl.of(context).localizedResource.known + : BrnIntl.of(context).localizedResource.next), style: TextStyle(color: Colors.white, fontSize: 14), ), ), @@ -287,7 +288,7 @@ class BrnTipInfoWidget extends StatelessWidget { ); } - Widget buildForceBottom() { + Widget _buildForceBottom(BuildContext context) { if (onNext == null && onSkip == null) return Row(); return Container( height: 20, @@ -308,7 +309,7 @@ class BrnTipInfoWidget extends StatelessWidget { onSkip!(); }, child: Text( - '跳过 (${currentStepIndex + 1}/$stepCount)', + '${BrnIntl.of(context).localizedResource.skip} (${currentStepIndex + 1}/$stepCount)', style: TextStyle(color: Color(0xFF999999), fontSize: 14), ), @@ -332,8 +333,8 @@ class BrnTipInfoWidget extends StatelessWidget { child: Text( nextTip ?? (stepCount == currentStepIndex + 1 - ? '我知道了' - : '下一步'), + ? BrnIntl.of(context).localizedResource.known + : BrnIntl.of(context).localizedResource.next), style: TextStyle( color: BrnThemeConfigurator.instance .getConfig() diff --git a/lib/src/components/input/brn_input_text.dart b/lib/src/components/input/brn_input_text.dart index 42f754f9..58c2f46c 100644 --- a/lib/src/components/input/brn_input_text.dart +++ b/lib/src/components/input/brn_input_text.dart @@ -1,3 +1,4 @@ +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -34,7 +35,7 @@ class BrnInputText extends StatelessWidget { final Color bgColor; /// 输入框的hint文字,默认为"请输入..." - final String hint; + final String? hint; /// 输入框的初始值,默认为"" /// 不能定义为String,兼容example调用的传值 @@ -79,7 +80,7 @@ class BrnInputText extends StatelessWidget { this.bgColor = Colors.white, this.maxLength = 200, this.minLines = 1, - this.hint = "请输入", + this.hint, this.maxHintLines, this.padding = EdgeInsets.zero, this.textString = "", @@ -175,7 +176,7 @@ class BrnInputText extends StatelessWidget { ); }, decoration: InputDecoration( - hintText: hint, + hintText: hint ?? BrnIntl.of(context).localizedResource.pleaseEnter, hintMaxLines: maxHintLines, hintStyle: TextStyle(fontSize: 16.0, color: Color(0xFFCCCCCC)), contentPadding: EdgeInsets.all(0), diff --git a/lib/src/components/loading/brn_loading.dart b/lib/src/components/loading/brn_loading.dart index e4548bcc..78a56ec6 100644 --- a/lib/src/components/loading/brn_loading.dart +++ b/lib/src/components/loading/brn_loading.dart @@ -1,5 +1,6 @@ import 'package:bruno/bruno.dart'; import 'package:bruno/src/constants/brn_strings_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:flutter/material.dart'; /// 页面或者弹窗中间的圆形加载框,左侧是可定制的加载文案[content],比如:加载中、提交中等等 @@ -29,9 +30,13 @@ import 'package:flutter/material.dart'; /// * [BrnLoadingDialog], 加载对话框。 class BrnPageLoading extends StatelessWidget { - final String content; + final String? content; + final BoxConstraints constraints; - const BrnPageLoading({this.content = BrnStrings.loadingContent}); + const BrnPageLoading({ + this.content, + this.constraints = const BoxConstraints(minWidth: 130, maxWidth: 130, minHeight: 50, maxHeight: 50,), + }); @override Widget build(BuildContext context) { @@ -39,13 +44,13 @@ class BrnPageLoading extends StatelessWidget { double _iconSize = 19.0; double _textLeftPadding = 8.0; double _outPadding = 10.0; - + String loadingText = content ?? BrnIntl.of(context).localizedResource.loading; // 获取实际文字长度 TextPainter textPainter = TextPainter( textDirection: TextDirection.ltr, textScaleFactor: MediaQuery.of(context).textScaleFactor, text: TextSpan( - text: content, + text: loadingText, style: TextStyle( fontSize: 15, fontWeight: FontWeight.w600, @@ -59,12 +64,10 @@ class BrnPageLoading extends StatelessWidget { return Center( child: Container( padding: EdgeInsets.all(_outPadding), - constraints: BoxConstraints( - maxWidth: maxWidth, minWidth: _iconSize + _textLeftPadding), + constraints: BoxConstraints(maxWidth: maxWidth, minWidth: _iconSize + _textLeftPadding), height: 50, width: _loadingMaxWidth, - decoration: BoxDecoration( - color: Color(0xff222222), borderRadius: BorderRadius.circular(5)), + decoration: BoxDecoration(color: Color(0xff222222), borderRadius: BorderRadius.circular(5)), child: Center( child: Row( mainAxisSize: MainAxisSize.min, @@ -81,7 +84,8 @@ class BrnPageLoading extends StatelessWidget { child: Container( margin: EdgeInsets.only(left: _textLeftPadding), child: Text( - content, + loadingText, + maxLines: 1, style: TextStyle( fontSize: 15, fontWeight: FontWeight.w600, @@ -90,30 +94,13 @@ class BrnPageLoading extends StatelessWidget { overflow: TextOverflow.ellipsis, ), ), - ) + ), ], ), ), ), ); } - - _buildText(BuildContext context, double maxWidth) { - TextPainter textPainter = TextPainter( - textScaleFactor: MediaQuery.of(context).textScaleFactor, - text: TextSpan( - text: content, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.w600, - color: Colors.white, - decoration: TextDecoration.none)), - )..layout(maxWidth: maxWidth, minWidth: 0); - return BoxConstraints( - maxWidth: maxWidth, - minWidth: 0, - ); - } } /// 通过 [BrnPageLoading] 构建出的加载状态的弹窗,加载动画和加载文字并排展示,且在屏幕中间。可通 @@ -123,13 +110,13 @@ class BrnLoadingDialog extends Dialog { static const String _loadingDialogTag = '_loadingDialogTag'; /// 加载时的提示文案,默认为 `加载中...` - final String content; + final String? content; - const BrnLoadingDialog({Key? key, this.content = BrnStrings.loadingContent}) : super(key: key); + const BrnLoadingDialog({Key? key, this.content}) : super(key: key); @override Widget build(BuildContext context) { - return BrnPageLoading(content: content); + return BrnPageLoading(content: content ?? BrnIntl.of(context).localizedResource.loading); } /// 展示加载弹窗的静态方法。 @@ -141,7 +128,7 @@ class BrnLoadingDialog extends Dialog { /// rootNavigator,详见 [showDialog] 中的 [useRootNavigator]。 static Future show( BuildContext context, { - String content = BrnStrings.loadingContent, + String? content, bool barrierDismissible = true, bool useRootNavigator = true, }) { @@ -151,7 +138,7 @@ class BrnLoadingDialog extends Dialog { barrierDismissible: barrierDismissible, useRootNavigator: useRootNavigator, builder: (_) { - return BrnLoadingDialog(content: content); + return BrnLoadingDialog(content: content ?? BrnIntl.of(context).localizedResource.loading); }); } diff --git a/lib/src/components/navbar/brn_search_bar.dart b/lib/src/components/navbar/brn_search_bar.dart index c8b34f30..0bc088a3 100644 --- a/lib/src/components/navbar/brn_search_bar.dart +++ b/lib/src/components/navbar/brn_search_bar.dart @@ -3,6 +3,7 @@ import 'package:bindings_compatible/bindings_compatible.dart'; import 'package:bruno/src/components/navbar/brn_appbar_theme.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; import 'package:bruno/src/constants/brn_strings_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:flutter/material.dart'; @@ -151,7 +152,7 @@ class _SearchInputWidget extends StatefulWidget { final dynamic leading; final BrnSearchBarInputChangeCallback? searchBarInputChangeCallback; final BrnSearchBarInputSubmitCallback? searchBarInputSubmitCallback; - final String? hint; + String? hint; final TextStyle? hintStyle; final TextStyle? inputTextStyle; final TextStyle? dismissStyle; @@ -168,7 +169,7 @@ class _SearchInputWidget extends StatefulWidget { this.textEditingController, this.searchBarInputChangeCallback, this.searchBarInputSubmitCallback, - this.hint = '请输入搜索内容', + this.hint, this.hintStyle, this.inputTextStyle, this.showDivider = true, @@ -309,7 +310,7 @@ class __SearchInputWidgetState extends State<_SearchInputWidget> { color: _defaultHintTextColor, ), // 提示文本属性,提示字段接受哪种输入的文本。 - hintText: widget.hint, + hintText: widget.hint ?? BrnIntl.of(context).localizedResource.inputSearchTip, ), // 在改变属性,当正在编辑的文本发生更改时调用。 onChanged: (content) { @@ -370,7 +371,7 @@ class __SearchInputWidgetState extends State<_SearchInputWidget> { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '取消', + BrnIntl.of(context).localizedResource.cancel, style: widget.dismissStyle ?? TextStyle( color: _defaultCancelTextColor, diff --git a/lib/src/components/picker/base/brn_picker_title.dart b/lib/src/components/picker/base/brn_picker_title.dart index 7079cbbf..7ed83017 100755 --- a/lib/src/components/picker/base/brn_picker_title.dart +++ b/lib/src/components/picker/base/brn_picker_title.dart @@ -2,6 +2,7 @@ import 'package:bruno/src/components/picker/time_picker/brn_date_picker_constants.dart'; import 'package:bruno/src/components/picker/base/brn_picker_title_config.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:bruno/src/utils/i18n/brn_date_picker_i18n.dart'; import 'package:flutter/material.dart'; @@ -11,13 +12,11 @@ import 'package:flutter/material.dart'; // ignore: must_be_immutable class BrnPickerTitle extends StatelessWidget { final BrnPickerTitleConfig pickerTitleConfig; - final DateTimePickerLocale? locale; final DateVoidCallback onCancel, onConfirm; BrnPickerConfig? themeData; BrnPickerTitle({ Key? key, - this.locale, required this.onCancel, required this.onConfirm, this.pickerTitleConfig = BrnPickerTitleConfig.Default, @@ -63,7 +62,8 @@ class BrnPickerTitle extends StatelessWidget { }, ), Text( - pickerTitleConfig.titleContent, + pickerTitleConfig.titleContent ?? + BrnIntl.of(context).localizedResource.pleaseChoose, style: themeData!.titleTextStyle.generateTextStyle(), ), GestureDetector( @@ -91,7 +91,7 @@ class BrnPickerTitle extends StatelessWidget { if (cancelWidget == null) { TextStyle textStyle = themeData!.cancelTextStyle.generateTextStyle(); cancelWidget = Text( - '取消', + BrnIntl.of(context).localizedResource.cancel, style: textStyle, textAlign: TextAlign.left, ); @@ -105,7 +105,7 @@ class BrnPickerTitle extends StatelessWidget { if (confirmWidget == null) { TextStyle textStyle = themeData!.confirmTextStyle.generateTextStyle(); confirmWidget = Text( - '完成', + BrnIntl.of(context).localizedResource.done, style: textStyle, textAlign: TextAlign.right, ); diff --git a/lib/src/components/picker/base/brn_picker_title_config.dart b/lib/src/components/picker/base/brn_picker_title_config.dart index 4b2a3c7c..72133b0c 100755 --- a/lib/src/components/picker/base/brn_picker_title_config.dart +++ b/lib/src/components/picker/base/brn_picker_title_config.dart @@ -1,9 +1,9 @@ +import 'package:bruno/bruno.dart'; import 'package:flutter/material.dart'; import 'package:bruno/src/components/picker/base/brn_picker_constants.dart'; class BrnPickerTitleConfig { - final Text cancelDefault = const Text('OK'); /// DateTimePicker theme. /// @@ -17,7 +17,7 @@ class BrnPickerTitleConfig { this.confirm, this.title, this.showTitle: pickerShowTitleDefault, - this.titleContent: "请选择", + this.titleContent, }); static const BrnPickerTitleConfig Default = const BrnPickerTitleConfig(); @@ -34,7 +34,7 @@ class BrnPickerTitleConfig { /// Whether display title widget or not. If set false, the default cancel and confirm widgets will not display, but the custom title widget will display if had specified one custom title widget. final bool showTitle; - final String titleContent; + final String? titleContent; BrnPickerTitleConfig copyWith({ Widget? cancel, diff --git a/lib/src/components/picker/brn_bottom_picker.dart b/lib/src/components/picker/brn_bottom_picker.dart index de2acb08..a57b4bce 100644 --- a/lib/src/components/picker/brn_bottom_picker.dart +++ b/lib/src/components/picker/brn_bottom_picker.dart @@ -1,6 +1,7 @@ import 'package:bruno/src/components/picker/base/brn_picker_title.dart'; import 'package:bruno/src/components/picker/base/brn_picker_title_config.dart'; import 'package:bruno/src/components/picker/brn_picker_cliprrect.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:flutter/material.dart'; @@ -200,7 +201,7 @@ class BrnBottomPickerWidgetState extends State } else if (widget.confirm is String) { confirmWidget = _buildDefaultConfirm(widget.confirm); } else { - confirmWidget = _buildDefaultConfirm('确认'); + confirmWidget = _buildDefaultConfirm(BrnIntl.of(context).localizedResource.confirm); } return confirmWidget; } @@ -212,7 +213,7 @@ class BrnBottomPickerWidgetState extends State } else if (widget.cancel is String) { cancelWidget = _buildDefaultCancel(widget.cancel); } else { - cancelWidget = _buildDefaultCancel('取消'); + cancelWidget = _buildDefaultCancel(BrnIntl.of(context).localizedResource.cancel); } return cancelWidget; } @@ -232,7 +233,7 @@ class BrnBottomPickerWidgetState extends State Widget _buildDefaultCancel(String? string) { return Text( - string ?? '取消', + string ?? BrnIntl.of(context).localizedResource.cancel, style: TextStyle( color: BrnThemeConfigurator.instance .getConfig() diff --git a/lib/src/components/picker/brn_bottom_write_picker.dart b/lib/src/components/picker/brn_bottom_write_picker.dart index eada4a9c..38b1d1c0 100644 --- a/lib/src/components/picker/brn_bottom_write_picker.dart +++ b/lib/src/components/picker/brn_bottom_write_picker.dart @@ -1,5 +1,6 @@ import 'package:bruno/src/components/picker/base/brn_picker_title_config.dart'; import 'package:bruno/src/components/picker/brn_bottom_picker.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:flutter/material.dart'; @@ -13,16 +14,16 @@ typedef BrnBottomWritePickerConfirmClickCallback = Future? Function( class BrnBottomWritePicker extends StatefulWidget { /// 弹窗左边自定义文案,默认 '取消' - final String leftTag; + final String? leftTag; /// 弹窗自定义标题 final String title; /// 弹窗右边自定义文案,默认 '确认' - final String rightTag; + final String? rightTag; /// 输入框默认提示文案,默认'请输入' - final String hintText; + final String? hintText; /// 输入框最大能输入的字符长度,默认 200 final int maxLength; @@ -47,10 +48,10 @@ class BrnBottomWritePicker extends StatefulWidget { const BrnBottomWritePicker( {this.maxLength = 200, - this.hintText = "请输入", - this.leftTag = "取消", + this.hintText, + this.leftTag, this.title = "", - this.rightTag = "确认", + this.rightTag, this.onCancel, this.onConfirm, this.rightTextColor, @@ -65,10 +66,10 @@ class BrnBottomWritePicker extends StatefulWidget { static void show(BuildContext context, {int maxLength = 200, - String hintText = "请输入", - String leftTag = "取消", + String? hintText, + String? leftTag, String title = "", - String rightTag = "确认", + String? rightTag, BrnBottomWritePickerClickCallback? onCancel, BrnBottomWritePickerConfirmClickCallback? onConfirm, bool confirmDismiss = false, @@ -84,10 +85,10 @@ class BrnBottomWritePicker extends StatefulWidget { Animation secondaryAnimation) { final Widget pageChild = BrnBottomWritePicker( maxLength: maxLength, - hintText: hintText, - leftTag: leftTag, + hintText: hintText ?? BrnIntl.of(context).localizedResource.pleaseEnter, + leftTag: leftTag ?? BrnIntl.of(context).localizedResource.cancel, title: title, - rightTag: rightTag, + rightTag: rightTag ?? BrnIntl.of(context).localizedResource.ok, onConfirm: onConfirm, onCancel: onCancel, rightTextColor: rightTextColor ?? @@ -159,14 +160,14 @@ class _BottomWritePickerState extends State { .getConfig() .commonConfig .colorTextHint), - hintText: widget.hintText, + hintText: widget.hintText ?? BrnIntl.of(context).localizedResource.pleaseEnter, )), ), pickerTitleConfig: BrnPickerTitleConfig( titleContent: widget.title, ), - confirm: _buildRightTag(), - cancel: widget.leftTag, + confirm: _buildRightTag(context), + cancel: widget.leftTag ?? BrnIntl.of(context).localizedResource.cancel, onConfirmPressed: () { if (widget.onConfirm != null) { widget.onConfirm!(context, _controller?.text); @@ -182,10 +183,10 @@ class _BottomWritePickerState extends State { } //此处返回类型为dynamic,在build的时候,会判读具体类型 - dynamic _buildRightTag() { + dynamic _buildRightTag(BuildContext context) { if (widget.rightTextColor != null) { return Text( - widget.rightTag, + widget.rightTag ?? BrnIntl.of(context).localizedResource.ok, style: TextStyle( fontSize: 16.0, color: widget.rightTextColor, diff --git a/lib/src/components/picker/brn_mulit_select_tags_picker.dart b/lib/src/components/picker/brn_mulit_select_tags_picker.dart index 187869b4..8df631be 100644 --- a/lib/src/components/picker/brn_mulit_select_tags_picker.dart +++ b/lib/src/components/picker/brn_mulit_select_tags_picker.dart @@ -1,6 +1,7 @@ import 'package:bruno/src/components/picker/base/brn_picker_title_config.dart'; import 'package:bruno/src/components/picker/brn_tags_common_picker.dart'; import 'package:bruno/src/components/picker/brn_tags_picker_config.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:flutter/material.dart'; @@ -104,7 +105,7 @@ class BrnMultiSelectTagsPicker extends CommonTagsPicker { return Container( height: 200, child: Center( - child: Text('未配置tags数据'), + child: Text(BrnIntl.of(context).localizedResource.noTagDataTip), ), ); } diff --git a/lib/src/components/picker/brn_select_tags_with_input_picker.dart b/lib/src/components/picker/brn_select_tags_with_input_picker.dart index c6d8e131..8fe8892b 100644 --- a/lib/src/components/picker/brn_select_tags_with_input_picker.dart +++ b/lib/src/components/picker/brn_select_tags_with_input_picker.dart @@ -1,5 +1,6 @@ import 'package:bruno/src/components/picker/brn_picker_cliprrect.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:flutter/material.dart'; @@ -22,7 +23,7 @@ class BrnSelectTagsWithInputPicker extends Dialog { final String title; ///输入框默认提示文案 - final String hintText; + final String? hintText; ///输入框最大能输入的字符长度。默认值 200 final int maxLength; @@ -56,7 +57,7 @@ class BrnSelectTagsWithInputPicker extends Dialog { const BrnSelectTagsWithInputPicker( {this.maxLength = 200, - this.hintText = "请输入", + this.hintText, this.title = "", this.confirm, this.cancelCallBack, @@ -74,7 +75,7 @@ class BrnSelectTagsWithInputPicker extends Dialog { title: title, confirm: confirm, maxLength: maxLength, - hintText: hintText, + hintText: hintText ?? BrnIntl.of(context).localizedResource.pleaseEnter, cursorColor: cursorColor ?? BrnThemeConfigurator.instance.getConfig().commonConfig.brandPrimary, forceShowTextInput: forceShowTextInput, @@ -184,7 +185,7 @@ class _BrnSelectTagsWithInputPickerWidgetState color: Colors.white, height: 200, child: Center( - child: Text('暂未配置可选标签数据'), + child: Text(BrnIntl.of(context).localizedResource.noTagDataTip), ), ), ]; @@ -439,7 +440,7 @@ class _BrnSelectTagsWithInputPickerWidgetState borderRadius: BorderRadius.all(Radius.circular(4))), child: Center( child: Text( - '提交', + BrnIntl.of(context).localizedResource.submit, style: TextStyle( fontSize: 16, color: Colors.white, diff --git a/lib/src/components/picker/brn_tags_common_picker.dart b/lib/src/components/picker/brn_tags_common_picker.dart index 9a45f503..966d1d62 100644 --- a/lib/src/components/picker/brn_tags_common_picker.dart +++ b/lib/src/components/picker/brn_tags_common_picker.dart @@ -17,7 +17,7 @@ typedef TagsPickerContentBuilder = Widget Function( /// 创建时传入Builder 或者 子类实现 createBuilder 函数 // ignore: must_be_immutable -class CommonTagsPicker extends StatefulWidget { +abstract class CommonTagsPicker extends StatefulWidget { final BuildContext context; final ValueChanged? onConfirm; final VoidCallback? onCancel; @@ -69,13 +69,7 @@ class CommonTagsPicker extends StatefulWidget { /// 子类需重写getConfirmData()函数,直接使用LJTagsPickerWidget类时忽略 @protected - Object getConfirmData() { - return '子类需重写getConfirmData()函数'; - } - - Object getCommitData() { - return '子类需重写getConfirmData()函数'; - } + Object getConfirmData(); @override _CommonPickerState createState() => _CommonPickerState(); diff --git a/lib/src/components/picker/brn_tags_picker_config.dart b/lib/src/components/picker/brn_tags_picker_config.dart index ab8ffa20..2e07a872 100644 --- a/lib/src/components/picker/brn_tags_picker_config.dart +++ b/lib/src/components/picker/brn_tags_picker_config.dart @@ -1,46 +1,7 @@ -import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:flutter/material.dart'; -class BrnTagsPickerHeaderConfig { - BrnTagsPickerHeaderConfig({ - this.headerHeight = 48, - this.title = "", - this.titleColor, - this.titleFontSize = 18, - this.confirmTitle = '确定', - this.confirmColor, - this.confirmFontSize = 18, - this.cancelTitle = "取消", - this.cancelColor, - this.cancelFontSize = 18, - this.dividingLineColor, - }) { - this.titleColor = - BrnThemeConfigurator.instance.getConfig().commonConfig.colorTextBase; - this.cancelColor = - BrnThemeConfigurator.instance.getConfig().commonConfig.colorTextBase; - } - - final double headerHeight; - - final String title; - Color? titleColor; - final double titleFontSize; - - final String confirmTitle; - final Color? confirmColor; - final double confirmFontSize; - - final String cancelTitle; - Color? cancelColor; - final double cancelFontSize; - - //分割线颜色 - final Color? dividingLineColor; -} - class BrnTagsPickerConfig { BrnTagsPickerConfig( {this.tagTitleFontSize = 16.0, diff --git a/lib/src/components/picker/multi_range_picker/brn_multi_column_list.dart b/lib/src/components/picker/multi_range_picker/brn_multi_column_list.dart index fd0212f9..d8c77ff2 100644 --- a/lib/src/components/picker/multi_range_picker/brn_multi_column_list.dart +++ b/lib/src/components/picker/multi_range_picker/brn_multi_column_list.dart @@ -5,6 +5,7 @@ import 'package:bruno/src/components/picker/multi_range_picker/brn_multi_column_ import 'package:bruno/src/components/picker/multi_range_picker/brn_multi_column_picker_util.dart'; import 'package:bruno/src/components/picker/multi_range_picker/btn_multi_column_picker_item.dart'; import 'package:bruno/src/components/toast/brn_toast.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:flutter/material.dart'; /// 单个 item 点击的回调 @@ -134,7 +135,7 @@ class _BrnMultiColumnListWidgetState extends State { if (selectedEntity.filterType == PickerFilterType.checkbox && !selectedEntity.isSelected) { if (!BrnMultiColumnPickerUtil.isSelectedCountExceed(selectedEntity)) { - BrnToast.show("您选择的数量已达上限", context); + BrnToast.show(BrnIntl.of(context).localizedResource.selectCountLimitTip, context); return; } } diff --git a/lib/src/components/picker/time_picker/brn_date_time_formatter.dart b/lib/src/components/picker/time_picker/brn_date_time_formatter.dart index e89c1f16..8ad665c4 100755 --- a/lib/src/components/picker/time_picker/brn_date_time_formatter.dart +++ b/lib/src/components/picker/time_picker/brn_date_time_formatter.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'package:bruno/src/components/picker/time_picker/brn_date_picker_constants.dart'; import 'package:bruno/src/components/picker/time_picker/date_picker/brn_date_picker.dart'; import 'package:bruno/src/components/picker/time_picker/date_range_picker/brn_date_range_picker.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:bruno/src/utils/i18n/brn_date_picker_i18n.dart'; import 'package:intl/intl.dart'; @@ -105,8 +106,7 @@ class DateTimeFormatter { } /// Format datetime string - static String formatDateTime( - int value, String format, DateTimePickerLocale locale) { + static String formatDateTime(int value, String format) { if (format.isEmpty) { return value.toString(); } @@ -114,30 +114,30 @@ class DateTimeFormatter { String result = format; // format year text if (format.contains('y')) { - result = _formatYear(value, result, locale); + result = _formatYear(value, result); } // format month text if (format.contains('M')) { - result = _formatMonth(value, result, locale); + result = _formatMonth(value, result); } // format day text if (format.contains('d')) { - result = _formatDay(value, result, locale); + result = _formatDay(value, result); } if (format.contains('E')) { - result = _formatWeek(value, result, locale); + result = _formatWeek(value, result); } // format hour text if (format.contains('H')) { - result = _formatHour(value, result, locale); + result = _formatHour(value, result); } // format minute text if (format.contains('m')) { - result = _formatMinute(value, result, locale); + result = _formatMinute(value, result); } // format second text if (format.contains('s')) { - result = _formatSecond(value, result, locale); + result = _formatSecond(value, result); } if (result == format) { return value.toString(); @@ -147,7 +147,7 @@ class DateTimeFormatter { /// Format day display static String formatDate( - DateTime dateTime, String format, DateTimePickerLocale locale) { + DateTime dateTime, String format) { if (format.isEmpty) { return dateTime.toString(); } @@ -155,18 +155,18 @@ class DateTimeFormatter { String result = format; // format year text if (format.contains('y')) { - result = _formatYear(dateTime.year, result, locale); + result = _formatYear(dateTime.year, result); } // format month text if (format.contains('M')) { - result = _formatMonth(dateTime.month, result, locale); + result = _formatMonth(dateTime.month, result); } // format day text if (format.contains('d')) { - result = _formatDay(dateTime.day, result, locale); + result = _formatDay(dateTime.day, result); } if (format.contains('E')) { - result = _formatWeek(dateTime.weekday, result, locale); + result = _formatWeek(dateTime.weekday, result); } if (result == format) { return dateTime.toString(); @@ -175,8 +175,7 @@ class DateTimeFormatter { } /// format year text - static String _formatYear( - int value, String format, DateTimePickerLocale locale) { + static String _formatYear(int value, String format) { if (format.contains('yyyy')) { // yyyy: the digit count of year is 4, e.g. 2019 return format.replaceAll('yyyy', value.toString()); @@ -190,8 +189,8 @@ class DateTimeFormatter { /// format month text static String _formatMonth( - int value, String format, DateTimePickerLocale locale) { - List months = DatePickerI18n.getLocaleMonths(locale); + int value, String format) { + List months = BrnIntl.currentResource.months; if (format.contains('MMMM')) { // MMMM: the full name of month, e.g. January return format.replaceAll('MMMM', months[value - 1]); @@ -205,38 +204,38 @@ class DateTimeFormatter { /// format day text static String _formatDay( - int value, String format, DateTimePickerLocale locale) { + int value, String format) { return _formatNumber(value, format, 'd'); } /// format week text static String _formatWeek( - int value, String format, DateTimePickerLocale locale) { + int value, String format) { if (format.contains('EEEE')) { // EEEE: the full name of week, e.g. Monday - List weeks = DatePickerI18n.getLocaleWeeks(locale); + List weeks = BrnIntl.currentResource.weekFullName; return format.replaceAll('EEEE', weeks[value - 1]); } // EEE: the short name of week, e.g. Mon - List weeks = DatePickerI18n.getLocaleWeeks(locale, false); + List weeks = BrnIntl.currentResource.weekShortName; return format.replaceAll(RegExp(r'E+'), weeks[value - 1]); } /// format hour text static String _formatHour( - int value, String format, DateTimePickerLocale locale) { + int value, String format) { return _formatNumber(value, format, 'H'); } /// format minute text static String _formatMinute( - int value, String format, DateTimePickerLocale locale) { + int value, String format) { return _formatNumber(value, format, 'm'); } /// format second text static String _formatSecond( - int value, String format, DateTimePickerLocale locale) { + int value, String format) { return _formatNumber(value, format, 's'); } diff --git a/lib/src/components/picker/time_picker/date_picker/brn_date_picker.dart b/lib/src/components/picker/time_picker/date_picker/brn_date_picker.dart index c2804c38..e0d1a47b 100755 --- a/lib/src/components/picker/time_picker/date_picker/brn_date_picker.dart +++ b/lib/src/components/picker/time_picker/date_picker/brn_date_picker.dart @@ -60,7 +60,6 @@ class BrnDatePicker { /// 分钟间切换的差值 int minuteDivider: 1, - DateTimePickerLocale locale = datetimePickerLocaleDefault, /// 时间选择组件显示的时间类型 BrnDateTimePickerMode pickerMode = BrnDateTimePickerMode.date, @@ -106,7 +105,6 @@ class BrnDatePicker { initialDateTime: initialDateTime, dateFormat: dateFormat, minuteDivider: minuteDivider, - locale: locale, pickerMode: pickerMode, pickerTitleConfig: pickerTitleConfig, onCancel: onCancel, @@ -129,7 +127,6 @@ class _DatePickerRoute extends PopupRoute { this.initialDateTime, this.minuteDivider, this.dateFormat, - this.locale = datetimePickerLocaleDefault, this.pickerMode = BrnDateTimePickerMode.date, this.pickerTitleConfig = BrnPickerTitleConfig.Default, this.onCancel, @@ -150,7 +147,6 @@ class _DatePickerRoute extends PopupRoute { final DateTime? minDateTime, maxDateTime, initialDateTime; final String? dateFormat; - final DateTimePickerLocale locale; final BrnDateTimePickerMode pickerMode; final BrnPickerTitleConfig pickerTitleConfig; final VoidCallback? onCancel; @@ -222,7 +218,6 @@ class _DatePickerComponent extends StatelessWidget { maxDateTime: route.maxDateTime, initialDateTime: route.initialDateTime, dateFormat: route.dateFormat, - locale: route.locale, pickerTitleConfig: route.pickerTitleConfig, onCancel: route.onCancel, onChange: route.onChange, @@ -236,7 +231,6 @@ class _DatePickerComponent extends StatelessWidget { maxDateTime: route.maxDateTime, initDateTime: route.initialDateTime, dateFormat: route.dateFormat, - locale: route.locale, minuteDivider: route.minuteDivider, pickerTitleConfig: route.pickerTitleConfig, onCancel: route.onCancel, @@ -252,7 +246,6 @@ class _DatePickerComponent extends StatelessWidget { initDateTime: route.initialDateTime, dateFormat: route.dateFormat, minuteDivider: route.minuteDivider, - locale: route.locale, pickerTitleConfig: route.pickerTitleConfig, onCancel: route.onCancel, onChange: route.onChange, diff --git a/lib/src/components/picker/time_picker/date_picker/brn_date_widget.dart b/lib/src/components/picker/time_picker/date_picker/brn_date_widget.dart index 39c1e0d6..25248afa 100755 --- a/lib/src/components/picker/time_picker/date_picker/brn_date_widget.dart +++ b/lib/src/components/picker/time_picker/date_picker/brn_date_widget.dart @@ -26,7 +26,6 @@ class BrnDateWidget extends StatefulWidget { this.maxDateTime, this.initialDateTime, this.dateFormat = datetimePickerDateFormat, - this.locale = datetimePickerLocaleDefault, this.pickerTitleConfig = BrnPickerTitleConfig.Default, this.onCancel, this.onChange, @@ -46,7 +45,6 @@ class BrnDateWidget extends StatefulWidget { final DateTime? minDateTime, maxDateTime, initialDateTime; final String? dateFormat; - final DateTimePickerLocale locale; final BrnPickerTitleConfig pickerTitleConfig; final DateVoidCallback? onCancel; @@ -129,7 +127,6 @@ class _BrnDateWidgetState extends State { widget.pickerTitleConfig.showTitle) { Widget titleWidget = BrnPickerTitle( pickerTitleConfig: widget.pickerTitleConfig, - locale: widget.locale, onCancel: () => _onPressedCancel(), onConfirm: () => _onPressedConfirm(), ); @@ -258,7 +255,7 @@ class _BrnDateWidgetState extends State { height: widget.themeData!.itemHeight, alignment: Alignment.center, child: Text( - DateTimeFormatter.formatDateTime(value, format, widget.locale), + DateTimeFormatter.formatDateTime(value, format), style: textStyle), ); } diff --git a/lib/src/components/picker/time_picker/date_picker/brn_datetime_widget.dart b/lib/src/components/picker/time_picker/date_picker/brn_datetime_widget.dart index 6f842698..4663d4cf 100755 --- a/lib/src/components/picker/time_picker/date_picker/brn_datetime_widget.dart +++ b/lib/src/components/picker/time_picker/date_picker/brn_datetime_widget.dart @@ -22,7 +22,6 @@ class BrnDateTimeWidget extends StatefulWidget { this.maxDateTime, this.initDateTime, this.dateFormat: datetimePickerTimeFormat, - this.locale: datetimePickerLocaleDefault, this.pickerTitleConfig: BrnPickerTitleConfig.Default, this.onCancel, this.onChange, @@ -43,7 +42,6 @@ class BrnDateTimeWidget extends StatefulWidget { final DateTime? minDateTime, maxDateTime, initDateTime; final int? minuteDivider; final String? dateFormat; - final DateTimePickerLocale locale; final BrnPickerTitleConfig pickerTitleConfig; final DateVoidCallback? onCancel; @@ -190,7 +188,6 @@ class _BrnDateTimeWidgetState extends State { widget.pickerTitleConfig.showTitle) { Widget titleWidget = BrnPickerTitle( pickerTitleConfig: widget.pickerTitleConfig, - locale: widget.locale, onCancel: () => _onPressedCancel(), onConfirm: () => _onPressedConfirm(), ); @@ -473,7 +470,7 @@ class _BrnDateTimeWidgetState extends State { height: widget.themeData!.itemHeight, alignment: Alignment.center, child: Text( - DateTimeFormatter.formatDateTime(value, format, widget.locale), + DateTimeFormatter.formatDateTime(value, format), style: textStyle), ); } diff --git a/lib/src/components/picker/time_picker/date_picker/brn_time_widget.dart b/lib/src/components/picker/time_picker/date_picker/brn_time_widget.dart index 1e9e0491..f1f2cc6d 100755 --- a/lib/src/components/picker/time_picker/date_picker/brn_time_widget.dart +++ b/lib/src/components/picker/time_picker/date_picker/brn_time_widget.dart @@ -23,7 +23,6 @@ class BrnTimeWidget extends StatefulWidget { this.maxDateTime, this.initDateTime, this.dateFormat: datetimePickerTimeFormat, - this.locale: datetimePickerLocaleDefault, this.pickerTitleConfig: BrnPickerTitleConfig.Default, this.minuteDivider = 1, this.onCancel, @@ -43,7 +42,6 @@ class BrnTimeWidget extends StatefulWidget { final DateTime? minDateTime, maxDateTime, initDateTime; final String? dateFormat; - final DateTimePickerLocale locale; final BrnPickerTitleConfig pickerTitleConfig; final DateVoidCallback? onCancel; final DateValueCallback? onChange, onConfirm; @@ -143,7 +141,6 @@ class _BrnTimeWidgetState extends State { widget.pickerTitleConfig.showTitle) { Widget titleWidget = BrnPickerTitle( pickerTitleConfig: widget.pickerTitleConfig, - locale: widget.locale, onCancel: () => _onPressedCancel(), onConfirm: () => _onPressedConfirm(), ); @@ -301,7 +298,7 @@ class _BrnTimeWidgetState extends State { height: widget.themeData!.itemHeight, alignment: Alignment.center, child: Text( - DateTimeFormatter.formatDateTime(value, format, widget.locale), + DateTimeFormatter.formatDateTime(value, format), style: textStyle), ); } diff --git a/lib/src/components/picker/time_picker/date_range_picker/brn_date_range_picker.dart b/lib/src/components/picker/time_picker/date_range_picker/brn_date_range_picker.dart index c228832f..b7843a39 100755 --- a/lib/src/components/picker/time_picker/date_range_picker/brn_date_range_picker.dart +++ b/lib/src/components/picker/time_picker/date_range_picker/brn_date_range_picker.dart @@ -80,7 +80,6 @@ class BrnDateRangePicker { initialEndDateTime: initialEndDateTime, dateFormat: dateFormat, minuteDivider: minuteDivider, - locale: locale, pickerMode: pickerMode, pickerTitleConfig: pickerTitleConfig, onCancel: onCancel, @@ -102,7 +101,6 @@ class _DatePickerRoute extends PopupRoute { initialEndDateTime; final bool isLimitTimeRange; final String? dateFormat; - final DateTimePickerLocale locale; final BrnDateTimeRangePickerMode pickerMode; final BrnPickerTitleConfig pickerTitleConfig; final VoidCallback? onCancel; @@ -121,7 +119,6 @@ class _DatePickerRoute extends PopupRoute { this.initialEndDateTime, this.minuteDivider = 1, this.dateFormat, - this.locale = datetimePickerLocaleDefault, this.pickerMode = BrnDateTimeRangePickerMode.date, this.pickerTitleConfig = BrnPickerTitleConfig.Default, this.onCancel, @@ -204,7 +201,6 @@ class _DatePickerComponent extends StatelessWidget { initialStartDateTime: route.initialStartDateTime, initialEndDateTime: route.initialEndDateTime, dateFormat: route.dateFormat, - locale: route.locale, pickerTitleConfig: route.pickerTitleConfig, onCancel: route.onCancel, onChange: route.onChange, @@ -221,7 +217,6 @@ class _DatePickerComponent extends StatelessWidget { initialEndDateTime: route.initialEndDateTime, minuteDivider: route.minuteDivider, dateFormat: route.dateFormat, - locale: route.locale, pickerTitleConfig: route.pickerTitleConfig, onCancel: route.onCancel, onChange: route.onChange, diff --git a/lib/src/components/picker/time_picker/date_range_picker/brn_date_range_side_widget.dart b/lib/src/components/picker/time_picker/date_range_picker/brn_date_range_side_widget.dart index b975afac..8b19b21c 100755 --- a/lib/src/components/picker/time_picker/date_range_picker/brn_date_range_side_widget.dart +++ b/lib/src/components/picker/time_picker/date_range_picker/brn_date_range_side_widget.dart @@ -26,7 +26,6 @@ class BrnDateRangeSideWidget extends StatefulWidget { /// 时间展示格式 final String? dateFormat; - final DateTimePickerLocale locale; /// 时间选择变化时回调 final DateRangeSideValueCallback? onChange; @@ -43,7 +42,6 @@ class BrnDateRangeSideWidget extends StatefulWidget { this.maxDateTime, this.initialStartDateTime, this.dateFormat = datetimeRangePickerDateFormat, - this.locale = datetimePickerLocaleDefault, this.onInitSelectChange, this.onChange, }) : super(key: key) { @@ -260,7 +258,7 @@ class _DatePickerWidgetState extends State { height: widget.themeData!.itemHeight, alignment: Alignment.center, child: Text( - DateTimeFormatter.formatDateTime(value, format, widget.locale), + DateTimeFormatter.formatDateTime(value, format), style: textStyle, )); } diff --git a/lib/src/components/picker/time_picker/date_range_picker/brn_date_range_widget.dart b/lib/src/components/picker/time_picker/date_range_picker/brn_date_range_widget.dart index ff43ddb6..2aa16813 100755 --- a/lib/src/components/picker/time_picker/date_range_picker/brn_date_range_widget.dart +++ b/lib/src/components/picker/time_picker/date_range_picker/brn_date_range_widget.dart @@ -7,6 +7,7 @@ import 'package:bruno/src/components/picker/base/brn_picker_title.dart'; import 'package:bruno/src/components/picker/base/brn_picker_title_config.dart'; import 'package:bruno/src/components/picker/time_picker/brn_date_picker_constants.dart'; import 'package:bruno/src/components/picker/time_picker/date_range_picker/brn_date_range_side_widget.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:bruno/src/utils/i18n/brn_date_picker_i18n.dart'; import 'package:flutter/material.dart'; @@ -31,7 +32,6 @@ class BrnDateRangeWidget extends StatefulWidget { /// 时间展示格式 final String? dateFormat; - final DateTimePickerLocale locale; /// cancel 回调 final DateVoidCallback? onCancel; @@ -55,7 +55,6 @@ class BrnDateRangeWidget extends StatefulWidget { this.initialStartDateTime, this.initialEndDateTime, this.dateFormat: datetimeRangePickerDateFormat, - this.locale: datetimePickerLocaleDefault, this.pickerTitleConfig: BrnPickerTitleConfig.Default, this.onCancel, this.onChange, @@ -162,7 +161,6 @@ class _DatePickerWidgetState extends State { widget.pickerTitleConfig.showTitle) { Widget titleWidget = BrnPickerTitle( pickerTitleConfig: widget.pickerTitleConfig, - locale: widget.locale, onCancel: () => _onPressedCancel(), onConfirm: () => _onPressedConfirm(), ); @@ -278,7 +276,7 @@ class _DatePickerWidgetState extends State { height: widget.themeData!.itemHeight, alignment: Alignment.center, child: Text( - "至", + BrnIntl.of(context).localizedResource.to, style: widget.themeData!.itemTextStyle.generateTextStyle(), ), ); diff --git a/lib/src/components/picker/time_picker/date_range_picker/brn_time_range_side_widget.dart b/lib/src/components/picker/time_picker/date_range_picker/brn_time_range_side_widget.dart index 1a0573e0..1ff9dea3 100755 --- a/lib/src/components/picker/time_picker/date_range_picker/brn_time_range_side_widget.dart +++ b/lib/src/components/picker/time_picker/date_range_picker/brn_time_range_side_widget.dart @@ -24,7 +24,6 @@ class BrnTimeRangeSideWidget extends StatefulWidget { /// 时间展示格式 final String? dateFormat; - final DateTimePickerLocale locale; /// 时间选择变化时回调 final DateRangeSideValueCallback? onChange; @@ -44,7 +43,6 @@ class BrnTimeRangeSideWidget extends StatefulWidget { this.maxDateTime, this.initialStartDateTime, this.dateFormat: datetimeRangePickerTimeFormat, - this.locale: datetimePickerLocaleDefault, this.minuteDivider = 1, this.onChange, this.onInitSelectChange, @@ -292,7 +290,7 @@ class _TimePickerWidgetState extends State { height: widget.themeData!.itemHeight, alignment: Alignment.center, child: Text( - DateTimeFormatter.formatDateTime(value, format, widget.locale), + DateTimeFormatter.formatDateTime(value, format), style: textStyle, )); } diff --git a/lib/src/components/picker/time_picker/date_range_picker/brn_time_range_widget.dart b/lib/src/components/picker/time_picker/date_range_picker/brn_time_range_widget.dart index 07fe2d61..e401024e 100755 --- a/lib/src/components/picker/time_picker/date_range_picker/brn_time_range_widget.dart +++ b/lib/src/components/picker/time_picker/date_range_picker/brn_time_range_widget.dart @@ -7,6 +7,7 @@ import 'package:bruno/src/components/picker/base/brn_picker_title.dart'; import 'package:bruno/src/components/picker/base/brn_picker_title_config.dart'; import 'package:bruno/src/components/picker/time_picker/brn_date_picker_constants.dart'; import 'package:bruno/src/components/picker/time_picker/date_range_picker/brn_time_range_side_widget.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme.dart'; import 'package:bruno/src/utils/i18n/brn_date_picker_i18n.dart'; import 'package:flutter/material.dart'; @@ -31,7 +32,6 @@ class BrnTimeRangeWidget extends StatefulWidget { /// 时间格式 final String? dateFormat; - final DateTimePickerLocale locale; /// cancel 回调 final DateVoidCallback? onCancel; @@ -62,7 +62,6 @@ class BrnTimeRangeWidget extends StatefulWidget { this.initialStartDateTime, this.initialEndDateTime, this.dateFormat: datetimeRangePickerTimeFormat, - this.locale: datetimePickerLocaleDefault, this.pickerTitleConfig: BrnPickerTitleConfig.Default, this.minuteDivider = 1, this.onCancel, @@ -183,7 +182,6 @@ class _TimePickerWidgetState extends State { widget.pickerTitleConfig.showTitle) { Widget titleWidget = BrnPickerTitle( pickerTitleConfig: widget.pickerTitleConfig, - locale: widget.locale, onCancel: () => _onPressedCancel(), onConfirm: () => _onPressedConfirm(), ); @@ -345,7 +343,7 @@ class _TimePickerWidgetState extends State { height: widget.themeData!.itemHeight, alignment: Alignment.center, child: Text( - "至", + BrnIntl.of(context).localizedResource.to, style: widget.themeData!.itemTextStyle.generateTextStyle(), ), ); diff --git a/lib/src/components/selectcity/brn_single_select_city_page.dart b/lib/src/components/selectcity/brn_single_select_city_page.dart index f71cff48..e9c034d8 100644 --- a/lib/src/components/selectcity/brn_single_select_city_page.dart +++ b/lib/src/components/selectcity/brn_single_select_city_page.dart @@ -8,6 +8,7 @@ import 'package:bruno/src/components/selectcity/brn_select_city_model.dart'; import 'package:bruno/src/components/sugsearch/brn_search_text.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; import 'package:bruno/src/constants/brn_strings_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:bruno/src/constants/brn_fonts_constants.dart'; import 'package:flutter/material.dart'; @@ -141,7 +142,7 @@ class _BrnSingleSelectCityPageState extends State { Container( padding: EdgeInsets.only(left: 20, right: 10, top: 20, bottom: 0), child: Text( - widget.hotCityTitle ?? '这里是推荐城市', + widget.hotCityTitle ?? BrnIntl.of(context).localizedResource.recommandCity, textAlign: TextAlign.left, style: TextStyle( fontWeight: FontWeight.w500, @@ -237,7 +238,7 @@ class _BrnSingleSelectCityPageState extends State { Widget _buildSearchBar() { return BrnSearchText( searchController: _brnSearchTextController, - hintText: '请输入搜索信息', + hintText: BrnIntl.of(context).localizedResource.inputSearchTip, onTextChange: (text) { _searchText = text; _showCityStack = text.isEmpty; @@ -277,7 +278,7 @@ class _BrnSingleSelectCityPageState extends State { Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, - appBar: BrnAppBar(title: widget.appBarTitle ?? '城市选择'), + appBar: BrnAppBar(title: widget.appBarTitle ?? BrnIntl.of(context).localizedResource.selectCity), body: Container( decoration: BoxDecoration(color: Colors.white), child: Column( @@ -363,8 +364,8 @@ class _BrnSingleSelectCityPageState extends State { Widget _noDataWidget() { return Container( child: BrnAbnormalStateWidget( - img: widget.emptyImage ?? BrunoTools.getAssetImage(BrnAsset.noData), - title: BrnStrings.noSearchData, + img: BrunoTools.getAssetImage(BrnAsset.noData), + title: BrnIntl.of(context).localizedResource.noSearchData, ), ); } diff --git a/lib/src/components/selection/brn_flat_selection.dart b/lib/src/components/selection/brn_flat_selection.dart index 7d8b03d0..aebdefcf 100644 --- a/lib/src/components/selection/brn_flat_selection.dart +++ b/lib/src/components/selection/brn_flat_selection.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:bruno/bruno.dart'; import 'package:bruno/src/components/popup/brn_measure_size.dart'; import 'package:bruno/src/components/selection/bean/brn_selection_common_entity.dart'; import 'package:bruno/src/components/selection/brn_selection_util.dart'; @@ -246,7 +247,7 @@ class _BrnFlatSelectionState extends State node = tmp.removeLast(); if (!node.isValidRange()) { isValid = false; - BrnToast.show('您输入的区间有误', context); + BrnToast.show(BrnIntl.of(context).localizedResource.enterRangeError, context); return; } node.children.forEach((data) { diff --git a/lib/src/components/selection/brn_more_selection.dart b/lib/src/components/selection/brn_more_selection.dart index 5ec4757f..1b5f643b 100644 --- a/lib/src/components/selection/brn_more_selection.dart +++ b/lib/src/components/selection/brn_more_selection.dart @@ -8,6 +8,7 @@ import 'package:bruno/src/components/selection/brn_selection_view.dart'; import 'package:bruno/src/components/selection/widget/brn_selection_more_item_widget.dart'; import 'package:bruno/src/components/toast/brn_toast.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/configs/brn_selection_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:flutter/material.dart'; @@ -250,10 +251,10 @@ class _BrnMoreSelectionPageState extends State if (!node.isValidRange()) { isValid = false; if (node.filterType == BrnSelectionFilterType.range) { - BrnToast.show('您输入的区间有误', context); + BrnToast.show(BrnIntl.of(context).localizedResource.enterRangeError, context); } else if (node.filterType == BrnSelectionFilterType.dateRange || node.filterType == BrnSelectionFilterType.dateRangeCalendar) { - BrnToast.show('您选择的区间有误', context); + BrnToast.show(BrnIntl.of(context).localizedResource.enterRangeError, context); } return; } @@ -310,7 +311,7 @@ class MoreBottomSelectionWidget extends StatelessWidget { child: BrunoTools.getAssetImage(BrnAsset.iconSelectionReset), ), Text( - '重置', + BrnIntl.of(context).localizedResource.reset, style: themeData.resetTextStyle.generateTextStyle(), ) ], @@ -319,7 +320,7 @@ class MoreBottomSelectionWidget extends StatelessWidget { ), Expanded( child: BrnBigMainButton( - title: '确定', + title: BrnIntl.of(context).localizedResource.ok, onTap: () { if (conformCallback != null) { conformCallback!(entity); diff --git a/lib/src/components/selection/widget/brn_flat_selection_item.dart b/lib/src/components/selection/widget/brn_flat_selection_item.dart index f9921c17..e3fc0dc7 100644 --- a/lib/src/components/selection/widget/brn_flat_selection_item.dart +++ b/lib/src/components/selection/widget/brn_flat_selection_item.dart @@ -11,6 +11,7 @@ import 'package:bruno/src/components/selection/controller/brn_flat_selection_con import 'package:bruno/src/components/selection/widget/brn_layer_more_selection_page.dart'; import 'package:bruno/src/components/toast/brn_toast.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/configs/brn_selection_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:bruno/src/utils/i18n/brn_date_picker_i18n.dart'; @@ -249,7 +250,7 @@ class __FilterCommonTypeWidgetState extends State<_FilterCommonTypeWidget> { } else if (data.filterType == BrnSelectionFilterType.checkbox) { if (!data.isSelected) { if (!BrnSelectionUtil.checkMaxSelectionCount(data)) { - BrnToast.show('您选择的筛选条件数量已达上限', context); + BrnToast.show(BrnIntl.of(context).localizedResource.filterConditionCountLimited, context); return; } } @@ -303,8 +304,7 @@ class __FilterCommonTypeWidgetState extends State<_FilterCommonTypeWidget> { DateTime.now().millisecondsSinceEpoch; showName = DateTimeFormatter.formatDate( DateTime.fromMillisecondsSinceEpoch(time), - 'yyyy/MMMM/dd', - DateTimePickerLocale.zh_cn); + 'yyyy/MMMM/dd'); } } else { showName = data.title; @@ -342,7 +342,7 @@ class __FilterCommonTypeWidgetState extends State<_FilterCommonTypeWidget> { pickerMode: BrnDateTimePickerMode.date, pickerTitleConfig: BrnPickerTitleConfig.Default, initialDateTime: DateTime.fromMillisecondsSinceEpoch(time), - dateFormat: 'yyyy年,MMMM月,dd日', onConfirm: (dateTime, list) { + dateFormat: BrnIntl.of(context).localizedResource.dateFormate_yyyy_MMMM_dd, onConfirm: (dateTime, list) { if (mounted) { setState(() { data.parent?.clearSelectedEntity(); @@ -388,7 +388,7 @@ class __MoreArrowState extends State<_MoreArrow> { child: Row( mainAxisSize: MainAxisSize.min, children: [ - Text('更多', + Text(BrnIntl.of(context).localizedResource.more, style: widget.themeData.moreTextStyle.generateTextStyle()), Container( height: 16, @@ -560,7 +560,7 @@ class __MoreRangeWidgetState extends State<_MoreRangeWidget> { crossAxisAlignment: CrossAxisAlignment.center, children: [ _buildRangeField( - '最小值', minController, minFocusNode, widget.width, widget.themeData), + BrnIntl.of(context).localizedResource.minValue, minController, minFocusNode, widget.width, widget.themeData), Padding( padding: EdgeInsets.only(left: 2), ), @@ -573,7 +573,7 @@ class __MoreRangeWidgetState extends State<_MoreRangeWidget> { padding: EdgeInsets.only(right: 2), ), _buildRangeField( - '最大值', maxController, maxFocusNode, widget.width, widget.themeData), + BrnIntl.of(context).localizedResource.maxValue, maxController, maxFocusNode, widget.width, widget.themeData), ], ); } @@ -681,7 +681,7 @@ class _FilterLayerTypeWidgetState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( - child: Text(isEmptyCondition() ? '请选择' : getCondition(), + child: Text(isEmptyCondition() ? BrnIntl.of(context).localizedResource.pleaseChoose : getCondition(), style: isEmptyCondition() ? widget.themeData.hintTextStyle.generateTextStyle() : widget.themeData.optionTextStyle diff --git a/lib/src/components/selection/widget/brn_layer_more_selection_page.dart b/lib/src/components/selection/widget/brn_layer_more_selection_page.dart index 95fc6532..11d7d667 100644 --- a/lib/src/components/selection/widget/brn_layer_more_selection_page.dart +++ b/lib/src/components/selection/widget/brn_layer_more_selection_page.dart @@ -5,6 +5,7 @@ import 'package:bruno/src/components/selection/brn_more_selection.dart'; import 'package:bruno/src/components/selection/brn_selection_util.dart'; import 'package:bruno/src/components/toast/brn_toast.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_selection_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; @@ -145,7 +146,7 @@ class _BrnLayerMoreSelectionPageState extends State systemOverlayStyle: SystemUiOverlayStyle.dark, backgroundColor: Colors.white, title: Text( - '选择${widget.entityData.title}', + BrnIntl.of(context).localizedResource.selectTitle(widget.entityData.title), style: TextStyle( color: BrnThemeConfigurator.instance .getConfig() @@ -236,7 +237,7 @@ class _BrnLayerMoreSelectionPageState extends State if (!this._firstList[index].isSelected) { if (!BrnSelectionUtil.checkMaxSelectionCount( _firstList[index])) { - BrnToast.show('您选择的筛选条件数量已达上限', context); + BrnToast.show(BrnIntl.of(context).localizedResource.filterConditionCountLimited, context); setState(() {}); return; } else { @@ -373,7 +374,7 @@ class _BrnLayerMoreSelectionPageState extends State if (!_currentFirstEntity!.children[index].isSelected) { if (!BrnSelectionUtil.checkMaxSelectionCount( this._currentFirstEntity!.children[index])) { - BrnToast.show('您选择的筛选条件数量已达上限', context); + BrnToast.show(BrnIntl.of(context).localizedResource.filterConditionCountLimited, context); return; } } diff --git a/lib/src/components/selection/widget/brn_selection_date_range_item_widget.dart b/lib/src/components/selection/widget/brn_selection_date_range_item_widget.dart index b1079422..d76e181d 100644 --- a/lib/src/components/selection/widget/brn_selection_date_range_item_widget.dart +++ b/lib/src/components/selection/widget/brn_selection_date_range_item_widget.dart @@ -4,6 +4,7 @@ import 'package:bruno/src/components/picker/time_picker/date_picker/brn_date_wid import 'package:bruno/src/components/selection/bean/brn_selection_common_entity.dart'; import 'package:bruno/src/components/selection/controller/brn_selection_view_date_picker_controller.dart'; import 'package:bruno/src/components/selection/widget/brn_selection_datepicker_animate_widget.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/configs/brn_selection_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:bruno/src/utils/i18n/brn_date_picker_i18n.dart'; @@ -69,11 +70,11 @@ class _BrnSelectionDateRangeItemWidgetState } widget.minTextEditingController.text = minDateTime != null ? DateTimeFormatter.formatDate( - minDateTime, widget.dateFormat, DateTimePickerLocale.zh_cn) + minDateTime, widget.dateFormat) : ''; widget.maxTextEditingController.text = maxDateTime != null ? DateTimeFormatter.formatDate( - maxDateTime, widget.dateFormat, DateTimePickerLocale.zh_cn) + maxDateTime, widget.dateFormat) : ''; super.initState(); } @@ -90,7 +91,7 @@ class _BrnSelectionDateRangeItemWidgetState margin: EdgeInsets.only(bottom: 5), alignment: Alignment.centerLeft, child: Text( - widget.item.title.isEmpty ? '自定义区间' : widget.item.title, + widget.item.title.isEmpty ? BrnIntl.of(context).localizedResource.customRange : widget.item.title, textAlign: TextAlign.left, style: widget.themeData.rangeTitleTextStyle .generateTextStyle(), @@ -102,7 +103,7 @@ class _BrnSelectionDateRangeItemWidgetState getDateRangeTextField(false), Container( child: Text( - "至", + BrnIntl.of(context).localizedResource.to, style: widget.themeData.inputTextStyle.generateTextStyle(), ), ), @@ -139,7 +140,7 @@ class _BrnSelectionDateRangeItemWidgetState textAlign: TextAlign.center, decoration: InputDecoration( hintStyle: widget.themeData.hintTextStyle.generateTextStyle(), - hintText: (!isMax ? '开始日期' : '结束日期'), + hintText: (!isMax ? BrnIntl.of(context).localizedResource.startDate : BrnIntl.of(context).localizedResource.endDate), enabledBorder: UnderlineInputBorder( borderSide: BorderSide( width: 1, @@ -195,14 +196,14 @@ class _BrnSelectionDateRangeItemWidgetState pickerTitleConfig: BrnPickerTitleConfig( showTitle: true, // UI 规范规定高度按照比例设置,UI稿的比利为 240 / 812 - titleContent: isMax ? '请选择结束时间' : '请选择开始时间'), + titleContent: isMax ? BrnIntl.of(context).localizedResource.selectEndDate : BrnIntl.of(context).localizedResource.selectStartDate), onCancel: () { closeSelectionPopupWindow(); }, onConfirm: (DateTime selectedDate, List selectedIndex) { widget.item.isSelected = true; String selectedDateStr = DateTimeFormatter.formatDate( - selectedDate, widget.dateFormat, DateTimePickerLocale.zh_cn); + selectedDate, widget.dateFormat); if (isMax) { widget.maxTextEditingController.text = selectedDateStr; } else { diff --git a/lib/src/components/selection/widget/brn_selection_list_widget.dart b/lib/src/components/selection/widget/brn_selection_list_widget.dart index 1f7b5d75..a10d45fa 100644 --- a/lib/src/components/selection/widget/brn_selection_list_widget.dart +++ b/lib/src/components/selection/widget/brn_selection_list_widget.dart @@ -6,6 +6,7 @@ import 'package:bruno/src/components/selection/brn_selection_util.dart'; import 'package:bruno/src/components/selection/widget/brn_selection_menu_widget.dart'; import 'package:bruno/src/components/selection/widget/brn_selection_single_list_widget.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/configs/brn_selection_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:flutter/material.dart'; @@ -255,7 +256,7 @@ class _BrnSelectionGroupViewState extends State { BrnAsset.iconSelectionReset), ), Text( - "重置", + BrnIntl.of(context).localizedResource.reset, style: widget.themeData.resetTextStyle.generateTextStyle(), ) @@ -266,7 +267,7 @@ class _BrnSelectionGroupViewState extends State { ), Expanded( child: BrnBigMainButton( - title: '确定', + title: BrnIntl.of(context).localizedResource.ok, onTap: () { _confirmButtonClickEvent(); }, diff --git a/lib/src/components/selection/widget/brn_selection_menu_widget.dart b/lib/src/components/selection/widget/brn_selection_menu_widget.dart index 0deddc5b..d7b67027 100644 --- a/lib/src/components/selection/widget/brn_selection_menu_widget.dart +++ b/lib/src/components/selection/widget/brn_selection_menu_widget.dart @@ -9,6 +9,7 @@ import 'package:bruno/src/components/selection/widget/brn_selection_animate_widg import 'package:bruno/src/components/selection/widget/brn_selection_list_widget.dart'; import 'package:bruno/src/components/selection/widget/brn_selection_menu_item_widget.dart'; import 'package:bruno/src/components/selection/widget/brn_selection_range_widget.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/configs/brn_selection_config.dart'; import 'package:bruno/src/utils/brn_event_bus.dart'; import 'package:bruno/src/utils/brn_tools.dart'; @@ -475,7 +476,7 @@ class _BrnSelectionMenuWidgetState extends State { list[0].customMap!['min']); if (minDate != null) { minDateTime = DateTimeFormatter.formatDate( - minDate, 'yyyy年MM月dd日', DateTimePickerLocale.zh_cn); + minDate, BrnIntl.of(context).localizedResource.dateFormate_yyyy_MM_dd); } } if (list[0].customMap != null && @@ -485,7 +486,7 @@ class _BrnSelectionMenuWidgetState extends State { list[0].customMap!['max']); if (maxDate != null) { maxDateTime = DateTimeFormatter.formatDate( - maxDate, 'yyyy年MM月dd日', DateTimePickerLocale.zh_cn); + maxDate, BrnIntl.of(context).localizedResource.dateFormate_yyyy_MM_dd); } } return '$minDateTime-$maxDateTime'; @@ -497,8 +498,7 @@ class _BrnSelectionMenuWidgetState extends State { title = msDateTime != null ? DateTimeFormatter.formatDate( DateTime.fromMillisecondsSinceEpoch(msDateTime), - 'yyyy年MM月dd日', - DateTimePickerLocale.zh_cn) + BrnIntl.of(context).localizedResource.dateFormate_yyyy_MM_dd) : list[0].title; return title; } diff --git a/lib/src/components/selection/widget/brn_selection_more_item_widget.dart b/lib/src/components/selection/widget/brn_selection_more_item_widget.dart index 4c8e7baa..40b3834c 100644 --- a/lib/src/components/selection/widget/brn_selection_more_item_widget.dart +++ b/lib/src/components/selection/widget/brn_selection_more_item_widget.dart @@ -13,6 +13,7 @@ import 'package:bruno/src/components/selection/widget/brn_layer_more_selection_p import 'package:bruno/src/components/selection/widget/brn_selection_date_range_item_widget.dart'; import 'package:bruno/src/components/toast/brn_toast.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/theme/configs/brn_selection_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; @@ -226,7 +227,7 @@ class __FilterCommonTypeWidgetState extends State<_FilterCommonTypeWidget> { } else if (data.filterType == BrnSelectionFilterType.checkbox) { if (!data.isSelected) { if (!BrnSelectionUtil.checkMaxSelectionCount(data)) { - BrnToast.show('您选择的筛选条件数量已达上限', context); + BrnToast.show(BrnIntl.of(context).localizedResource.filterConditionCountLimited, context); return; } } @@ -261,8 +262,7 @@ class __FilterCommonTypeWidgetState extends State<_FilterCommonTypeWidget> { DateTime.now().millisecondsSinceEpoch; showName = DateTimeFormatter.formatDate( DateTime.fromMillisecondsSinceEpoch(time), - 'yyyy/MMMM/dd', - DateTimePickerLocale.zh_cn); + 'yyyy/MMMM/dd'); } } else { showName = entity.title; @@ -299,7 +299,7 @@ class __FilterCommonTypeWidgetState extends State<_FilterCommonTypeWidget> { pickerMode: BrnDateTimePickerMode.date, pickerTitleConfig: BrnPickerTitleConfig.Default, initialDateTime: DateTime.fromMillisecondsSinceEpoch(time), - dateFormat: 'yyyy年,MMMM月,dd日', onConfirm: (dateTime, list) { + dateFormat: BrnIntl.of(context).localizedResource.dateFormate_yyyy_MMMM_dd, onConfirm: (dateTime, list) { if (mounted) { setState(() { data.parent?.clearSelectedEntity(); @@ -351,7 +351,7 @@ class __MoreArrowState extends State<_MoreArrow> { mainAxisSize: MainAxisSize.min, children: [ Text( - '更多', + BrnIntl.of(context).localizedResource.more, style: widget.themeData?.moreTextStyle.generateTextStyle(), ), Container( @@ -518,20 +518,20 @@ class __MoreRangeWidgetState extends State<_MoreRangeWidget> { children: [ Expanded( child: _buildRangeField( - '最小值', minController, minFocusNode, widget.themeData), + BrnIntl.of(context).localizedResource.minValue, minController, minFocusNode, widget.themeData), ), Container( // height: 38, alignment: Alignment.center, child: Text( - '至', + BrnIntl.of(context).localizedResource.to, textAlign: TextAlign.center, style: widget.themeData.inputTextStyle.generateTextStyle(), ), ), Expanded( child: _buildRangeField( - '最大值', maxController, maxFocusNode, widget.themeData), + BrnIntl.of(context).localizedResource.maxValue, maxController, maxFocusNode, widget.themeData), ), ], ); @@ -651,7 +651,7 @@ class _FilterLayerTypeWidgetState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( - child: Text(_isEmptyCondition() ? '请选择' : _getCondition(), + child: Text(_isEmptyCondition() ? BrnIntl.of(context).localizedResource.pleaseChoose : _getCondition(), style: _isEmptyCondition() ? widget.themeData.hintTextStyle.generateTextStyle() : widget.themeData.optionTextStyle diff --git a/lib/src/components/selection/widget/brn_selection_range_input_item_widget.dart b/lib/src/components/selection/widget/brn_selection_range_input_item_widget.dart index ae412365..80c03e99 100644 --- a/lib/src/components/selection/widget/brn_selection_range_input_item_widget.dart +++ b/lib/src/components/selection/widget/brn_selection_range_input_item_widget.dart @@ -1,4 +1,5 @@ import 'package:bruno/src/components/selection/bean/brn_selection_common_entity.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/configs/brn_selection_config.dart'; import 'package:bruno/src/utils/brn_event_bus.dart'; import 'package:flutter/material.dart'; @@ -108,7 +109,7 @@ class _BrnSelectionRangeItemWidgetState margin: EdgeInsets.only(bottom: 5), alignment: Alignment.centerLeft, child: Text( - (widget.item.title.isNotEmpty ? widget.item.title : '自定义区间') + + (widget.item.title.isNotEmpty ? widget.item.title : BrnIntl.of(context).localizedResource.customRange) + "(" + (widget.item.extMap['unit']?.toString() ?? '') + ")", @@ -121,7 +122,7 @@ class _BrnSelectionRangeItemWidgetState getRangeTextField(false), Container( child: Text( - "至", + BrnIntl.of(context).localizedResource.to, style: widget.themeData.inputTextStyle.generateTextStyle(), ), ), @@ -151,7 +152,7 @@ class _BrnSelectionRangeItemWidgetState textAlign: TextAlign.center, decoration: InputDecoration( hintStyle: widget.themeData.hintTextStyle.generateTextStyle(), - hintText: (isMax ? '最大值' : '最小值'), + hintText: (isMax ? BrnIntl.of(context).localizedResource.maxValue : BrnIntl.of(context).localizedResource.minValue), enabledBorder: UnderlineInputBorder( borderSide: BorderSide( width: 1, diff --git a/lib/src/components/selection/widget/brn_selection_range_tag_widget.dart b/lib/src/components/selection/widget/brn_selection_range_tag_widget.dart index 4f67f14f..f843aaf1 100644 --- a/lib/src/components/selection/widget/brn_selection_range_tag_widget.dart +++ b/lib/src/components/selection/widget/brn_selection_range_tag_widget.dart @@ -2,6 +2,7 @@ import 'package:bruno/src/components/picker/time_picker/brn_date_time_formatter. import 'package:bruno/src/components/selection/bean/brn_selection_common_entity.dart'; import 'package:bruno/src/components/selection/brn_selection_util.dart'; import 'package:bruno/src/components/toast/brn_toast.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/configs/brn_selection_config.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:bruno/src/utils/i18n/brn_date_picker_i18n.dart'; @@ -70,7 +71,7 @@ class _BrnSelectionRangeTagWidgetState if (BrnSelectionFilterType.checkbox == selectedEntity.filterType && !selectedEntity.isSelected) { if (!BrnSelectionUtil.checkMaxSelectionCount(selectedEntity)) { - BrnToast.show("您选择的筛选条件数量已达上限", context); + BrnToast.show(BrnIntl.of(context).localizedResource.filterConditionCountLimited, context); return; } } @@ -97,7 +98,7 @@ class _BrnSelectionRangeTagWidgetState widget.tagFilterList[nameIndex].value); if (dateTime != null) { text = DateTimeFormatter.formatDate( - dateTime, 'yyyy年MM月dd日', DateTimePickerLocale.zh_cn); + dateTime, BrnIntl.of(context).localizedResource.dateFormate_yyyy_MM_dd); } } else { text = widget.tagFilterList[nameIndex].value ?? ''; diff --git a/lib/src/components/selection/widget/brn_selection_range_widget.dart b/lib/src/components/selection/widget/brn_selection_range_widget.dart index 94865188..a37c0158 100644 --- a/lib/src/components/selection/widget/brn_selection_range_widget.dart +++ b/lib/src/components/selection/widget/brn_selection_range_widget.dart @@ -13,6 +13,7 @@ import 'package:bruno/src/components/selection/widget/brn_selection_range_tag_wi import 'package:bruno/src/components/tabbar/normal/brn_tab_bar.dart'; import 'package:bruno/src/components/toast/brn_toast.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/configs/brn_selection_config.dart'; import 'package:bruno/src/utils/brn_event_bus.dart'; import 'package:bruno/src/utils/brn_text_util.dart'; @@ -372,7 +373,7 @@ class _BrnRangeSelectionGroupWidgetState BrunoTools.getAssetImage(BrnAsset.iconSelectionReset), ), Text( - '重置', + BrnIntl.of(context).localizedResource.reset, style: widget.themeData.resetTextStyle.generateTextStyle(), ) ], @@ -382,7 +383,7 @@ class _BrnRangeSelectionGroupWidgetState ), Expanded( child: BrnBigMainButton( - title: '确定', + title: BrnIntl.of(context).localizedResource.ok, onTap: () { _confirmButtonClickEvent(); }, @@ -423,12 +424,12 @@ class _BrnRangeSelectionGroupWidgetState if (!rangeEntity.isValidRange()) { FocusScope.of(context).requestFocus(FocusNode()); if (rangeEntity.filterType == BrnSelectionFilterType.range) { - BrnToast.show('您输入的区间有误', context); + BrnToast.show(BrnIntl.of(context).localizedResource.enterRangeError, context); } else if (rangeEntity.filterType == BrnSelectionFilterType.dateRange || rangeEntity.filterType == BrnSelectionFilterType.dateRangeCalendar) { - BrnToast.show('您选择的区间有误', context); + BrnToast.show(BrnIntl.of(context).localizedResource.selectRangeError, context); } return; } diff --git a/lib/src/components/selection/widget/brn_selection_single_list_widget.dart b/lib/src/components/selection/widget/brn_selection_single_list_widget.dart index 8db3012a..d943790a 100644 --- a/lib/src/components/selection/widget/brn_selection_single_list_widget.dart +++ b/lib/src/components/selection/widget/brn_selection_single_list_widget.dart @@ -3,6 +3,7 @@ import 'package:bruno/src/components/selection/brn_selection_util.dart'; import 'package:bruno/src/components/selection/widget/brn_selection_common_item_widget.dart'; import 'package:bruno/src/components/selection/widget/brn_selection_list_widget.dart'; import 'package:bruno/src/components/toast/brn_toast.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/configs/brn_selection_config.dart'; import 'package:flutter/material.dart'; @@ -103,12 +104,12 @@ class _BrnSelectionSingleListWidgetState /// 同级别中,存在不限类型已经选中情况,选择非不限类型 item,不检查数量限制 } else if (entity.isInLastLevel() && !BrnSelectionUtil.checkMaxSelectionCount(entity)) { - BrnToast.show("您选择的筛选条件数量已达上限", context); + BrnToast.show(BrnIntl.of(context).localizedResource.filterConditionCountLimited, context); return; } } else { if (!BrnSelectionUtil.checkMaxSelectionCount(entity)) { - BrnToast.show("您选择的筛选条件数量已达上限", context); + BrnToast.show(BrnIntl.of(context).localizedResource.filterConditionCountLimited, context); return; } } diff --git a/lib/src/components/sugsearch/brn_search_text.dart b/lib/src/components/sugsearch/brn_search_text.dart index def1cbed..112275c7 100644 --- a/lib/src/components/sugsearch/brn_search_text.dart +++ b/lib/src/components/sugsearch/brn_search_text.dart @@ -1,4 +1,5 @@ import 'package:bruno/src/constants/brn_asset_constants.dart'; +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/utils/brn_tools.dart'; import 'package:flutter/material.dart'; @@ -242,7 +243,7 @@ class _SearchTextState extends State { textBaseline: TextBaseline.alphabetic, color: Color(0xff999999), ), - hintText: widget.hintText ?? "请输入搜索内容", + hintText: widget.hintText ?? BrnIntl.of(context).localizedResource.inputSearchTip, counterText: '', ), // 在改变属性,当正在编辑的文本发生更改时调用。 @@ -301,7 +302,7 @@ class _SearchTextState extends State { child: Container( padding: EdgeInsets.fromLTRB(20, 0, 0, 0), child: Text( - '取消', + BrnIntl.of(context).localizedResource.cancel, style: TextStyle( color: BrnThemeConfigurator.instance .getConfig() diff --git a/lib/src/components/text/brn_expandable_text.dart b/lib/src/components/text/brn_expandable_text.dart index 1f59e249..b555c67e 100644 --- a/lib/src/components/text/brn_expandable_text.dart +++ b/lib/src/components/text/brn_expandable_text.dart @@ -1,3 +1,4 @@ +import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; @@ -108,7 +109,7 @@ class _BrnExpandableTextState extends State { Color btnColor = widget.color ?? Colors.white; Text tx = Text( - '更多', + BrnIntl.of(context).localizedResource.more, style: TextStyle( color: BrnThemeConfigurator.instance .getConfig() @@ -163,7 +164,7 @@ class _BrnExpandableTextState extends State { InlineSpan _foldButtonSpan(context) { return TextSpan( - text: ' 收起', + text: ' '+ BrnIntl.of(context).localizedResource.collapse, style: TextStyle( color: BrnThemeConfigurator.instance .getConfig() diff --git a/lib/src/constants/brn_constants.dart b/lib/src/constants/brn_constants.dart index f08bee66..98b48dc7 100644 --- a/lib/src/constants/brn_constants.dart +++ b/lib/src/constants/brn_constants.dart @@ -1,17 +1,4 @@ class BrnShareItemConstants { - /// 分享渠道名称列表 - static const List shareItemTitleList = [ - "微信", - "朋友圈", - "QQ", - "QQ空间", - "微博", - "链接", - "短信", - "剪贴板", - "浏览器", - "相册" - ]; /// 分享渠道图片地址列表 static const List shareItemImagePathList = [ diff --git a/lib/src/constants/brn_strings_constants.dart b/lib/src/constants/brn_strings_constants.dart index 5928c255..37da5502 100644 --- a/lib/src/constants/brn_strings_constants.dart +++ b/lib/src/constants/brn_strings_constants.dart @@ -1,13 +1,6 @@ class BrnStrings { const BrnStrings._(); - /// 加载获取 assets 资源需要 + /// to load assets resource static const String flutterPackageName = "bruno"; - - static const String getDateFailed = "获取数据失败,请重试"; - static const String networkConnectError = "网络连接失败,检查后重试"; - static const String noData = "暂无数据"; - static const String noSearchData = "暂无搜索结果"; - static const String clickPageRetry = "请点击页面重试"; - static const String loadingContent = '加载中...'; } diff --git a/lib/src/l10n/brn_intl.dart b/lib/src/l10n/brn_intl.dart new file mode 100644 index 00000000..4b1359ad --- /dev/null +++ b/lib/src/l10n/brn_intl.dart @@ -0,0 +1,166 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; + +import 'brn_resources.dart'; + +/// +/// Bruno 多语言支持 +/// +class BrnIntl { + + /// 内置支持的语言和资源 + final Map _defaultResourceMap = {'en': BrnResourceEn(), 'zh': BrnResourceZh()}; + + /// 缓存当前语言对应的资源,用于无 context 的情况 + static BrnIntl? _current; + static BrnBaseResource get currentResource { + assert(_current != null, + 'No instance of BrnIntl was loaded. \n' + 'Try to initialize the BrnLocalizationDelegate before accessing BrnIntl.currentResource.'); + /// 若应用未做本地化,则默认使用 zh-CN 资源 + if(_current == null) { + _current = BrnIntl(BrnResourceZh.locale); + } + return _current!.localizedResource; + } + + final Locale locale; + + BrnIntl(this.locale); + + /// 获取当前语言下对应的资源,若为 null 则返回 [BrnResourceZh] + BrnBaseResource get localizedResource { + // 支持动态资源文件 + BrnBaseResource? resource = _BrnIntlHelper.findIntlResourceOfType(locale); + if (resource != null) return resource; + // 常规的多语言资源加载 + return _defaultResourceMap[locale.languageCode] ?? _defaultResourceMap['zh']!; + } + + /// 获取[BrnIntl]实例 + static BrnIntl of(BuildContext context) { + return Localizations.of(context, BrnIntl); + } + + /// 获取当前语言下 [BrnBaseResource] 资源 + static BrnBaseResource i10n(BuildContext context) { + return BrnIntl.of(context).localizedResource; + } + + /// 应用加载本地化资源 + static Future _load(Locale locale) { + _current = BrnIntl(locale); + return SynchronousFuture(_current!); + } + + /// 支持非内置的本地化能力 + static void add(Locale locale, BrnBaseResource resource) { + _BrnIntlHelper.add(locale, resource); + } + + /// 支持非内置的本地化能力 + static void addAll(Locale locale, List resources) { + _BrnIntlHelper.addAll(locale, resources); + } +} + +/// +/// 组件多语言适配代理 +/// +class BrnLocalizationDelegate extends LocalizationsDelegate { + @override + bool isSupported(Locale locale) => true; + + @override + Future load(Locale locale) { + debugPrint(runtimeType.toString() + + ' load: locale = $locale, ${locale.countryCode}, ${locale.languageCode}'); + return BrnIntl._load(locale); + } + + @override + bool shouldReload(LocalizationsDelegate old) => false; + + /// 需在app入口注册 + static BrnLocalizationDelegate delegate = BrnLocalizationDelegate(); +} + +/// +/// 支持外部动态添加其他语言支的本地化 +/// +final Map> _additionalIntls = {}; +class _BrnIntlHelper { + + /// + /// 根据 locale 查找 value 类型为[T]的资源 + /// + static T? findIntlResourceOfType(Locale locale) { + Map? res = _additionalIntls[locale]; + if (res != null && res.isNotEmpty) { + for (var entry in res.entries) { + if (entry.value is T) { + return entry.value; + } + } + } + return null; + } + + /// + /// 根据 locale 查找Type为[T]的资源 + /// + static T? findIntlResourceOfExactType(Locale locale) { + Map? res = _additionalIntls[locale]; + if (res != null && res.isNotEmpty) { + for (var entry in res.entries) { + if (entry.key == T) { + return entry.value; + } + } + } + return null; + } + + /// + /// 根据 locale 查找 value 类型为 T 的一系列资源 + /// + static Iterable? findIntlResourcesOfType(Locale locale) { + final res = _additionalIntls[locale]; + if (res != null && res.isNotEmpty) { + List resources = []; + for (var entry in res.entries) { + if (entry.value is T) { + resources.add(entry.value); + } + } + return resources; + } + return null; + } + + /// + /// 设置自定义 locale 的资源 + /// + static void addAll(Locale locale, List resources) { + var res = _additionalIntls[locale]; + if (res == null) { + res = {}; + _additionalIntls[locale] = res; + } + for (BrnBaseResource resource in resources) { + res[resource.runtimeType] = resource; + } + } + + /// + /// 设置自定义 locale 的资源 + /// + static void add(Locale locale, BrnBaseResource resource) { + var res = _additionalIntls[locale]; + if (res == null) { + res = {}; + _additionalIntls[locale] = res; + } + res[resource.runtimeType] = resource; + } +} diff --git a/lib/src/l10n/brn_resources.dart b/lib/src/l10n/brn_resources.dart new file mode 100644 index 00000000..da8413a4 --- /dev/null +++ b/lib/src/l10n/brn_resources.dart @@ -0,0 +1,579 @@ + +import 'dart:core'; +import 'dart:ui'; + +/// 资源抽象类 +abstract class BrnBaseResource { + + String get ok; + + String get cancel; + + String get confirm; + + String get loading; + + String get pleaseEnter; + + String get enterRangeError; + + String get pleaseChoose; + + String get selectRangeError; + + String get reset; + + String get confirmClearSelectedList; + + String get selectedList; + + String get clear; + + String get shareTo; + + List get appriseLevel; + + String get dateFormate_yyyy_MM; + + String get dateFormate_yyyy_MM_dd; + + String get dateFormate_yyyy_MMMM_dd; + + String get expand; + + String get collapse; + + String get more; + + String get allPics; + + String get submit; + + String get noTagDataTip; + + List get months; + + List get weekFullName; + + List get weekShortName; + + List get weekMinName; + + String get skip; + + String get known; + + String get next; + + String get inputSearchTip; + + String get done; + + String get noDataTip; + + String get selectAll; + + String get selected; + + String get shareWayTip; + + String get max; + + String get min; + + String get selectCountLimitTip; + + String get to; + + String get recommandCity; + + String get selectCity; + + String get filterConditionCountLimited; + + String get minValue; + + String get maxValue; + + String selectTitle(String selected); + + String get customRange; + + String get startDate; + + String get endDate; + + String get selectStartDate; + + String get selectEndDate; + + List get shareChannels; + + String get fetchErrorAndRetry; + + String get netErrorAndRetryLater; + + String get noSearchData; + + String get clickPageAndRetry; +} + +/// +/// 中文资源 +/// +class BrnResourceZh extends BrnBaseResource { + + static Locale locale = Locale('zh', 'CN'); + + @override + String get ok => '确定'; + + @override + String get cancel => '取消'; + + @override + String get confirm => '确认'; + + @override + String get loading => '加载中...'; + + @override + String get pleaseEnter => '请输入'; + + @override + String get enterRangeError => '您输入的区间有误'; + +//// TODO + @override + String get pleaseChoose => '请选择'; + + @override + String get selectRangeError => '您选择的区间有误'; + + @override + String get reset => '重置'; + + @override + String get confirmClearSelectedList => '确定要清空已选列表吗?'; + + @override + String get selectedList => '已选列表'; + + @override + String get clear => '清空'; + + @override + String get shareTo => '分享至'; + + @override + List get appriseLevel => [ + '不好', + '还行', + '满意', + '很棒', + '超惊喜', + ]; + + @override + String get dateFormate_yyyy_MM => 'yyyy年MM月'; + + @override + String get dateFormate_yyyy_MM_dd => 'yyyy年MM月dd日'; + + @override + String get dateFormate_yyyy_MMMM_dd => 'yyyy年,MMMM月,dd日'; + + @override + String get expand => '展开'; + + @override + String get collapse => '收起'; + + @override + String get more => '更多'; + + @override + String get allPics => '全部图片'; + + @override + String get submit => '提交'; + + @override + String get noTagDataTip => '暂未配置可选标签数据'; + + List get months =>[ + '01', + '02', + '03', + '04', + '05', + '06', + '07', + '08', + '09', + '10', + '11', + '12', + ]; + + @override + List get weekFullName => [ + '星期一', + '星期二', + '星期三', + '星期四', + '星期五', + '星期六', + '星期日', + ]; + + @override + List get weekShortName => [ + '周一', + '周二', + '周三', + '周四', + '周五', + '周六', + '周日', + ]; + + @override + List get weekMinName => [ + '日', + '一', + '二', + '三', + '四', + '五', + '六', + ]; + + @override + String get skip => '跳过'; + + @override + String get known => '我知道了'; + + @override + String get next => '下一步'; + + @override + String get inputSearchTip => '请输入搜索内容'; + + @override + String get done => '完成'; + + @override + String get noDataTip => '暂无数据'; + + @override + String get selectAll => '全选'; + + @override + String get selected => '已选'; + + @override + String get shareWayTip => '你可以通过以下方式分享给客户'; + + @override + String get max => '最小'; + + @override + String get min => '最大'; + + @override + String get selectCountLimitTip => '您选择的数量已达上限'; + + @override + String get to => '至'; + + @override + String get recommandCity => '这里是推荐城市'; + + @override + String get selectCity => '城市选择'; + + @override + String get filterConditionCountLimited => '您选择的筛选条件数量已达上限'; + + @override + String get minValue => '最小值'; + + @override + String get maxValue => '最大值'; + + @override + String selectTitle(String selected) => '选择$selected'; + + @override + String get customRange => '自定义区间'; + + @override + String get startDate => '开始日期'; + + @override + String get endDate => '结束日期'; + + @override + String get selectStartDate => '请选择开始时间'; + + @override + String get selectEndDate => '请选择结束时间'; + + @override + List get shareChannels => [ + '微信', + '朋友圈', + 'QQ', + 'QQ空间', + '微博', + '链接', + '短信', + '剪贴板', + '浏览器', + '相册', + ]; + + @override + String get fetchErrorAndRetry => '获取数据失败,请重试'; + + @override + String get netErrorAndRetryLater => '网络连接失败,检查后重试'; + + @override + String get noSearchData => '暂无搜索结果'; + + @override + String get clickPageAndRetry => '请点击页面重试'; +} + +/// +/// en resources +/// +class BrnResourceEn extends BrnBaseResource { + + static Locale locale = Locale('en', 'US'); + + @override + String get ok => 'Ok'; + + @override + String get cancel => 'Cancel'; + + @override + String get confirm => 'Confirm'; + + @override + String get loading => 'Loading ...'; + + @override + String get pleaseEnter => 'Please Enter'; + + @override + String get enterRangeError => 'The range you entered is incorrect'; + + @override + String get pleaseChoose => 'Please choose'; + + @override + String get selectRangeError => 'You have selected the wrong range'; + + @override + String get reset => 'Reset'; + + @override + String get confirmClearSelectedList => 'Are you sure you want to clear the selected list?'; + + @override + String get selectedList => 'Selected list'; + + @override + String get clear => 'Clear'; + + @override + String get shareTo => 'Share to'; + + @override + List get appriseLevel => [ + 'not good', + 'good', + 'satisfy', + 'great', + 'surprise', + ]; + + @override + String get dateFormate_yyyy_MM => 'MM/yyyy'; + + @override + String get dateFormate_yyyy_MM_dd => 'dd/MM/yyyy'; + + @override + String get dateFormate_yyyy_MMMM_dd => 'dd/MMMM/yyyy'; + + @override + String get expand => 'Expand'; + + @override + String get collapse => 'Collapse'; + + @override + String get more => 'More'; + + @override + String get allPics => 'All pictures'; + + @override + String get submit => 'Submit'; + + @override + String get noTagDataTip => 'Tag data not configured yet'; + + @override + List get months =>[ + '01', + '02', + '03', + '04', + '05', + '06', + '07', + '08', + '09', + '10', + '11', + '12', + ]; + + @override + List get weekFullName => [ + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday', + ]; + + @override + List get weekShortName => [ + 'Mon', + 'Tue', + 'Wed', + 'Thu', + 'Fri', + 'Sat', + 'Sun', + ]; + + @override + List get weekMinName => [ + 'U', + 'M', + 'T', + 'W', + 'R', + 'F', + 'S', + ]; + + @override + String get skip => 'Skip'; + + @override + String get known => 'I see'; + + @override + String get next => 'Next'; + + @override + String get inputSearchTip => 'Please enter search content'; + + @override + String get done => 'Done'; + + @override + String get noDataTip => 'No data'; + + @override + String get selectAll => 'Select all'; + + @override + String get selected => 'Selected'; + + @override + String get shareWayTip => 'You can share with customers in the following ways'; + + @override + String get max => 'Min'; + + @override + String get min => 'Max'; + + @override + String get selectCountLimitTip => 'You have already selected the maximum number'; + + @override + String get to => 'to'; + + @override + String get recommandCity => 'Here are the recommended cities'; + + @override + String get selectCity => 'Select city'; + + @override + String get filterConditionCountLimited => 'You have selected the maximum number of filters'; + + @override + String get minValue => 'Min'; + + @override + String get maxValue => 'Max'; + + @override + String selectTitle(String selected) => 'Select $selected'; + + @override + String get customRange => 'Custom range'; + + @override + String get startDate => 'Start date'; + + @override + String get endDate => 'End date'; + + @override + String get selectStartDate => 'Please select a start time'; + + @override + String get selectEndDate => 'Please select a end time'; + + @override + List get shareChannels => [ + 'Wechat', + 'Friends', + 'QQ', + 'QQ Zone', + 'Weibo', + 'Link', + 'Message', + 'Clipboard', + 'Browser', + 'Photo Album', + ]; + + @override + String get fetchErrorAndRetry => 'Fetch data fail, please try again'; + + @override + String get netErrorAndRetryLater => 'Network connection failed, check and try again'; + + @override + String get noSearchData => 'No search results'; + + @override + String get clickPageAndRetry => 'Please click the page to try again'; +} diff --git a/lib/src/utils/i18n/brn_date_picker_i18n.dart b/lib/src/utils/i18n/brn_date_picker_i18n.dart index e75687ec..7b70f744 100755 --- a/lib/src/utils/i18n/brn_date_picker_i18n.dart +++ b/lib/src/utils/i18n/brn_date_picker_i18n.dart @@ -1,26 +1,3 @@ -import 'dart:math' as math; - -part 'brn_strings_zh_cn.dart'; - -abstract class _StringsI18n { - const _StringsI18n(); - - /// Get the done widget text - String getDoneText(); - - /// Get the cancel widget text - String getCancelText(); - - /// Get the name of month - List getMonths(); - - /// Get the full name of week - List getWeeksFull(); - - /// Get the short name of week - List getWeeksShort(); -} - enum DateTimePickerLocale { /// English (EN) United States en_us, @@ -66,66 +43,3 @@ enum DateTimePickerLocale { const DateTimePickerLocale datetimePickerLocaleDefault = DateTimePickerLocale.zh_cn; -const Map datePickerI18n = { - DateTimePickerLocale.zh_cn: _StringsZhCn(), -}; - -class DatePickerI18n { - const DatePickerI18n._(); - - /// Get done button text - static String getLocaleDone(DateTimePickerLocale locale) { - final _StringsI18n? i18n = - datePickerI18n[locale] ?? datePickerI18n[datetimePickerLocaleDefault]; - return i18n?.getDoneText() ?? - datePickerI18n[datetimePickerLocaleDefault]!.getDoneText(); - } - - /// Get cancel button text - static String getLocaleCancel(DateTimePickerLocale locale) { - final _StringsI18n? i18n = - datePickerI18n[locale] ?? datePickerI18n[datetimePickerLocaleDefault]; - return i18n?.getCancelText() ?? - datePickerI18n[datetimePickerLocaleDefault]!.getCancelText(); - } - - /// Get locale month array - static List getLocaleMonths(DateTimePickerLocale locale) { - final _StringsI18n? i18n = - datePickerI18n[locale] ?? datePickerI18n[datetimePickerLocaleDefault]; - final List? months = i18n?.getMonths(); - if (months != null && months.isNotEmpty) { - return months; - } - return datePickerI18n[datetimePickerLocaleDefault]!.getMonths(); - } - - /// Get locale week array - static List getLocaleWeeks( - DateTimePickerLocale locale, [ - bool isFull = true, - ]) { - final _StringsI18n? i18n = - datePickerI18n[locale] ?? datePickerI18n[datetimePickerLocaleDefault]; - if (isFull) { - final List? weeks = i18n?.getWeeksFull(); - if (weeks != null && weeks.isNotEmpty) { - return weeks; - } - return datePickerI18n[datetimePickerLocaleDefault]!.getWeeksFull(); - } - - final List? weeks = i18n?.getWeeksShort(); - if (weeks != null && weeks.isNotEmpty) { - return weeks; - } - - final List? fullWeeks = i18n?.getWeeksFull(); - if (fullWeeks != null && fullWeeks.isNotEmpty) { - return fullWeeks - .map((item) => item.substring(0, math.min(3, item.length))) - .toList(); - } - return datePickerI18n[datetimePickerLocaleDefault]!.getWeeksShort(); - } -} diff --git a/lib/src/utils/i18n/brn_strings_zh_cn.dart b/lib/src/utils/i18n/brn_strings_zh_cn.dart deleted file mode 100755 index 7f9294c0..00000000 --- a/lib/src/utils/i18n/brn_strings_zh_cn.dart +++ /dev/null @@ -1,56 +0,0 @@ -part of 'brn_date_picker_i18n.dart'; - -/// Chinese (ZH) Simplified -class _StringsZhCn extends _StringsI18n { - const _StringsZhCn(); - - @override - String getCancelText() => '取消'; - - @override - String getDoneText() => '确定'; - - @override - List getMonths() { - return [ - '01', - '02', - '03', - '04', - '05', - '06', - '07', - '08', - '09', - '10', - '11', - '12', - ]; - } - - @override - List getWeeksFull() { - return [ - '星期一', - '星期二', - '星期三', - '星期四', - '星期五', - '星期六', - '星期日', - ]; - } - - @override - List getWeeksShort() { - return [ - '周一', - '周二', - '周三', - '周四', - '周五', - '周六', - '周日', - ]; - } -} From 4717847f82f59c40f266646a6194b8d3afdfe52a Mon Sep 17 00:00:00 2001 From: Sandy <15143015732@163.com> Date: Wed, 14 Dec 2022 11:40:47 +0800 Subject: [PATCH 08/15] fix textInputAction error (#379) --- lib/src/components/form/items/general/brn_text_input_item.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/components/form/items/general/brn_text_input_item.dart b/lib/src/components/form/items/general/brn_text_input_item.dart index 3055f279..a02e9f0a 100644 --- a/lib/src/components/form/items/general/brn_text_input_item.dart +++ b/lib/src/components/form/items/general/brn_text_input_item.dart @@ -200,7 +200,7 @@ class BrnTextInputFormItemState extends State { autofocus: widget.autofocus, focusNode: widget.focusNode, keyboardType: BrnFormUtil.getInputType(widget.inputType), - textInputAction: textInputAction, + textInputAction: widget.textInputAction, enabled: widget.isEdit, obscureText: widget.obscureText, maxLines: 1, From e468f55ca8de6c996fec0c8fea4903f8b02233c0 Mon Sep 17 00:00:00 2001 From: leftcoding <137387869@qq.com> Date: Wed, 14 Dec 2022 14:32:17 +0800 Subject: [PATCH 09/15] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BB=A3=E7=A0=81=20(#378)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/lib/sample/home/group_card.dart | 1 + example/lib/sample/home/list_item.dart | 1 + lib/src/components/form/items/misc/brn_add_label_item.dart | 3 --- lib/src/components/loading/brn_loading.dart | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/example/lib/sample/home/group_card.dart b/example/lib/sample/home/group_card.dart index e63a2def..f1772a01 100644 --- a/example/lib/sample/home/group_card.dart +++ b/example/lib/sample/home/group_card.dart @@ -59,6 +59,7 @@ class GroupCardState extends State @override Widget build(BuildContext context) { + super.build(context); return BrnPickerClipRRect( borderRadius: BorderRadius.all(Radius.circular(6)), child: BrnExpandableContainerWidget( diff --git a/example/lib/sample/home/list_item.dart b/example/lib/sample/home/list_item.dart index 0d5cdedb..fdf232e6 100644 --- a/example/lib/sample/home/list_item.dart +++ b/example/lib/sample/home/list_item.dart @@ -48,6 +48,7 @@ class _ListItemState extends State with AutomaticKeepAliveClientMixin @override Widget build(BuildContext context) { + super.build(context); return TextButton( onPressed: widget.onPressed, style: ButtonStyle( diff --git a/lib/src/components/form/items/misc/brn_add_label_item.dart b/lib/src/components/form/items/misc/brn_add_label_item.dart index 63fd49c5..dec10cd3 100644 --- a/lib/src/components/form/items/misc/brn_add_label_item.dart +++ b/lib/src/components/form/items/misc/brn_add_label_item.dart @@ -1,9 +1,6 @@ - - import 'package:bruno/src/components/form/base/brn_form_item_type.dart'; import 'package:bruno/src/components/form/utils/brn_form_util.dart'; import 'package:bruno/src/theme/brn_theme.dart'; -import 'package:bruno/src/theme/brn_theme_configurator.dart'; import 'package:bruno/src/constants/brn_fonts_constants.dart'; import 'package:flutter/material.dart'; diff --git a/lib/src/components/loading/brn_loading.dart b/lib/src/components/loading/brn_loading.dart index 78a56ec6..a8e03087 100644 --- a/lib/src/components/loading/brn_loading.dart +++ b/lib/src/components/loading/brn_loading.dart @@ -1,5 +1,4 @@ import 'package:bruno/bruno.dart'; -import 'package:bruno/src/constants/brn_strings_constants.dart'; import 'package:bruno/src/l10n/brn_intl.dart'; import 'package:flutter/material.dart'; From 4c8caae389e4a6842628e17c355cb718d663ee4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=20v?= Date: Mon, 26 Dec 2022 16:02:57 +0800 Subject: [PATCH 10/15] =?UTF-8?q?perf:=20perf=20PickerTitle=E3=80=81AppBar?= =?UTF-8?q?=20hitTest=20area.=20(#383)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: perf PickerTitle hit test area. * perf: perf AppBar TextAction hitTest Area --- lib/src/components/navbar/brn_appbar.dart | 2 ++ .../components/picker/base/brn_picker_title.dart | 14 ++++++++++++-- lib/src/components/tabbar/normal/brn_tab_bar.dart | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/src/components/navbar/brn_appbar.dart b/lib/src/components/navbar/brn_appbar.dart index 0f042d05..c68cb0e3 100644 --- a/lib/src/components/navbar/brn_appbar.dart +++ b/lib/src/components/navbar/brn_appbar.dart @@ -566,7 +566,9 @@ class BrnTextAction extends StatelessWidget { .merge(_defaultThemeData); return GestureDetector( + behavior: HitTestBehavior.opaque, child: Container( + height: _defaultThemeData.appBarHeight, alignment: Alignment.center, child: Text(text, maxLines: 1, diff --git a/lib/src/components/picker/base/brn_picker_title.dart b/lib/src/components/picker/base/brn_picker_title.dart index 7ed83017..e891af4b 100755 --- a/lib/src/components/picker/base/brn_picker_title.dart +++ b/lib/src/components/picker/base/brn_picker_title.dart @@ -56,7 +56,12 @@ class BrnPickerTitle extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( - child: _renderCancelWidget(context), + behavior: HitTestBehavior.opaque, + child: Container( + height: themeData!.titleHeight, + alignment: Alignment.center, + child: _renderCancelWidget(context), + ), onTap: () { this.onCancel(); }, @@ -67,7 +72,12 @@ class BrnPickerTitle extends StatelessWidget { style: themeData!.titleTextStyle.generateTextStyle(), ), GestureDetector( - child: _renderConfirmWidget(context), + behavior: HitTestBehavior.opaque, + child: Container( + height: themeData!.titleHeight, + alignment: Alignment.center, + child: _renderConfirmWidget(context), + ), onTap: () { this.onConfirm(); }, diff --git a/lib/src/components/tabbar/normal/brn_tab_bar.dart b/lib/src/components/tabbar/normal/brn_tab_bar.dart index 2fa01466..8a4feb42 100644 --- a/lib/src/components/tabbar/normal/brn_tab_bar.dart +++ b/lib/src/components/tabbar/normal/brn_tab_bar.dart @@ -801,6 +801,7 @@ class BadgeTab { this.showRedBadge = false, this.isAutoDismiss = true}); + @Deprecated('无效参数,预计两个版本后删除') final Key? key; /// Tab文本 From 8a1b080bdd274d54313b6a59b097f954e580ba44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=20v?= Date: Wed, 28 Dec 2022 14:31:49 +0800 Subject: [PATCH 11/15] fix i18n exception, perf i18n demo (#387) --- ...view_customhandle_filter_example_page.dart | 27 +++++-------- example/lib/sample/home/home.dart | 40 ++++++++----------- .../calendar/brn_calendar_view.dart | 5 ++- .../content_card/brn_pair_info_table.dart | 4 +- 4 files changed, 31 insertions(+), 45 deletions(-) diff --git a/example/lib/sample/components/selection/selectionview_customhandle_filter_example_page.dart b/example/lib/sample/components/selection/selectionview_customhandle_filter_example_page.dart index e4c8b032..9eab077e 100644 --- a/example/lib/sample/components/selection/selectionview_customhandle_filter_example_page.dart +++ b/example/lib/sample/components/selection/selectionview_customhandle_filter_example_page.dart @@ -1,5 +1,3 @@ - - import 'package:bruno/bruno.dart'; import 'package:flutter/material.dart'; @@ -10,12 +8,10 @@ class SelectionViewCustomHandleFilterExamplePage extends StatefulWidget { SelectionViewCustomHandleFilterExamplePage(this._title, this._filters); @override - _SelectionViewExamplePageState createState() => - _SelectionViewExamplePageState(); + _SelectionViewExamplePageState createState() => _SelectionViewExamplePageState(); } -class _SelectionViewExamplePageState - extends State { +class _SelectionViewExamplePageState extends State { int count = 0; @override @@ -31,17 +27,17 @@ class _SelectionViewExamplePageState children: [ BrnSelectionView( originalSelectionData: widget._filters!, - onCustomSelectionMenuClick: (int index, - BrnSelectionEntity customMenuItem, + onCustomSelectionMenuClick: (int index, BrnSelectionEntity customMenuItem, BrnSetCustomSelectionParams customHandleCallBack) { /// 用户操作一段时间之后,将自定义参数回传,触发 onSelectionChanged回调。 BrnDialogManager.showConfirmDialog(context, - cancel: '取消', - confirm: '确定', - message: '点击确定,回传自定义参数到筛选', onConfirm: () { + cancel: '取消', confirm: '确定', message: '点击确定,回传自定义参数到筛选', onConfirm: () { count++; customHandleCallBack({"CKey": "CValue" + '$count'}); - }, onCancel: () {}); + Navigator.pop(context); + }, onCancel: () { + Navigator.pop(context); + }); }, onSelectionChanged: (int menuIndex, Map filterParams, @@ -49,11 +45,8 @@ class _SelectionViewExamplePageState BrnSetCustomSelectionMenuTitle setCustomTitleFunction) { if (menuIndex == 1) { setCustomTitleFunction( - menuTitle: BrunoTools.isEmpty(customParams) - ? "" - : customParams['CKey'] ?? "", - isMenuTitleHighLight: - !BrunoTools.isEmpty(customParams['CKey'])); + menuTitle: BrunoTools.isEmpty(customParams) ? "" : customParams['CKey'] ?? "", + isMenuTitleHighLight: !BrunoTools.isEmpty(customParams['CKey'])); } }, ), diff --git a/example/lib/sample/home/home.dart b/example/lib/sample/home/home.dart index 9216c2cc..f7db9336 100644 --- a/example/lib/sample/home/home.dart +++ b/example/lib/sample/home/home.dart @@ -18,30 +18,22 @@ class HomePage extends StatelessWidget { leading: null, automaticallyImplyLeading: false, actions: [ - GestureDetector( - child: Icon( - Icons.more_horiz, - key: _moreKey, - color: Colors.black54, - ), - onTap: () { - BrnPopupListWindow.showPopListWindow(context, _moreKey, data: ['切换语言', '测试动态增加语言'], - onItemClick: (int index, item) { - if(index == 0) { - ChangeLocalEvent.locale = ChangeLocalEvent.locale.languageCode == 'zh' - ? Locale('en', 'US') - : Locale('zh', 'CN'); - ChangeLocalEvent()..dispatch(context); - } else { - ChangeLocalEvent.locale = ChangeLocalEvent.locale.languageCode == 'zh' - ? Locale('de', 'DE') - : Locale('zh', 'CN'); - ChangeLocalEvent()..dispatch(context); - } - return false; - }); - }, - ) + BrnTextAction( "切换组件词条语言",key: _moreKey, iconPressed: (){ + BrnPopupListWindow.showPopListWindow(context, _moreKey, + data: ['BrnResourceEn', 'ResourceDe'], + onItemClick: (int index, item) { + if(index == 0) { + BrnToast.showInCenter(text: "已切换为英语词条(BrnResourceEn)。\n注意:组件传入的默认值会影响词条展示", context: context); + ChangeLocalEvent.locale = Locale('en', 'US'); + ChangeLocalEvent()..dispatch(context); + } else { + BrnToast.showInCenter(text: "已切换为德语词条(ResourceDe 部分)。\n注意:组件传入的默认值会影响词条展示", context: context); + ChangeLocalEvent.locale = Locale('de', 'DE'); + ChangeLocalEvent()..dispatch(context); + } + return false; + }); + },) ], ), body: _buildBodyWidget(), diff --git a/lib/src/components/calendar/brn_calendar_view.dart b/lib/src/components/calendar/brn_calendar_view.dart index 58c8b8b9..b3e9b4e9 100644 --- a/lib/src/components/calendar/brn_calendar_view.dart +++ b/lib/src/components/calendar/brn_calendar_view.dart @@ -94,7 +94,7 @@ class BrnCalendarView extends StatefulWidget { final bool showControllerBar; /// 自定义星期的名称 - List? weekNames; + final List? weekNames; /// 初始展示月份 /// @@ -120,7 +120,6 @@ class _CustomCalendarViewState extends State { @override void initState() { - assert(widget.weekNames != null && widget.weekNames!.length == 7); _displayMode = widget.displayMode; _currentDate = widget.initDisplayDate ?? DateTime.now(); _minDate = widget.minDate ?? DateTime(1970); @@ -374,6 +373,7 @@ class _CustomCalendarViewState extends State { .withOpacity(0.14) : Colors.transparent) : Colors.transparent, + // 范围选择两端圆角 borderRadius: BorderRadius.horizontal( left: _isStartDateRadius(date) ? const Radius.circular(24.0) @@ -402,6 +402,7 @@ class _CustomCalendarViewState extends State { .brandPrimary : Colors.transparent, borderRadius: + // 选中色圆角 const BorderRadius.all(Radius.circular(32.0)), ), ), diff --git a/lib/src/components/card/content_card/brn_pair_info_table.dart b/lib/src/components/card/content_card/brn_pair_info_table.dart index 41ad6a57..8a967135 100644 --- a/lib/src/components/card/content_card/brn_pair_info_table.dart +++ b/lib/src/components/card/content_card/brn_pair_info_table.dart @@ -288,7 +288,7 @@ class _BrnPairInfoTableState extends State { Padding( padding: EdgeInsets.only(right: 4), child: Text( - BrnIntl.of(context).localizedResource.expand, + BrnIntl.currentResource.expand, style: TextStyle( fontSize: 14, color: themeData.commonConfig.colorTextSecondary, @@ -347,7 +347,7 @@ class _BrnPairInfoTableState extends State { Padding( padding: EdgeInsets.only(right: 4), child: Text( - BrnIntl.of(context).localizedResource.collapse, + BrnIntl.currentResource.collapse, style: TextStyle( fontSize: 14, color: themeData.commonConfig.colorTextSecondary, From cc7701de1125068b0b56d192aef40fad316e41e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=20v?= Date: Wed, 28 Dec 2022 14:32:20 +0800 Subject: [PATCH 12/15] fix enhance_number_card item has different heights (#386) --- .../card/content_card/brn_enhance_number_card.dart | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/src/components/card/content_card/brn_enhance_number_card.dart b/lib/src/components/card/content_card/brn_enhance_number_card.dart index 22a27a34..5e79a5fe 100644 --- a/lib/src/components/card/content_card/brn_enhance_number_card.dart +++ b/lib/src/components/card/content_card/brn_enhance_number_card.dart @@ -145,13 +145,10 @@ class BrnEnhanceNumberCard extends StatelessWidget { )), //分割线的显示规则是:固定高度47 // item之间显示,最后一个不显示 - Visibility( - visible: !allCondition, - child: Container( - height: 47, - width: defaultConfig.dividerWidth, - color: defaultConfig.commonConfig.dividerColorBase, - ), + Container( + height: 47, + width: !allCondition ? defaultConfig.dividerWidth : 0, + color: defaultConfig.commonConfig.dividerColorBase, ), ], )); From 5ab118163ed3931b3940e551f7e097c38f7ccf96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=20v?= Date: Wed, 28 Dec 2022 14:33:39 +0800 Subject: [PATCH 13/15] sync docs (#385) * sync docs * sync docs --- .../BrnAbnormalStateWidget.md | 8 +-- .../appraise/BrnAppraise/BrnAppraise.md | 6 +-- .../BrnAppraiseBottomPicker.md | 4 +- .../BrnCalendarView/BrnCalendarView.md | 4 +- .../charts/BrnBrokenLine/BrnBrokenLine.md | 5 ++ .../BrnProgressChart/BrnProgressChart.md | 6 ++- .../BrnEnhanceOperationDialog.md | 4 +- .../BrnLoadingDialog/BrnLoadingDialog.md | 4 +- .../BrnMiddleInputDialog.md | 10 ++-- .../BrnMultiSelectDialog.md | 4 +- .../BrnSingleSelectDialog.md | 4 +- .../BrnRangeInputFormItem.md | 8 +-- .../BrnRatioInputFormItem.md | 4 +- .../BrnTextBlockInputFormItem.md | 4 +- .../BrnTextInputFormItem.md | 8 ++- .../BrnTextQuickSelectFormItem.md | 4 +- .../BrnTitleSelectInputFormItem.md | 4 +- .../iconButton/BrnIconButton/BrnIconButton.md | 29 +++++----- .../input/BrnInputText/BrnInputText.md | 6 ++- .../loading/BrnPageLoading/BrnPageLoading.md | 10 ++-- .../BrnBigGhostButton/BrnBigGhostButton.md | 4 +- .../BrnBigMainButton/BrnBigMainButton.md | 4 +- .../BrnBigOutlineButton.md | 4 +- .../BrnSmallMainButton/BrnSmallMainButton.md | 4 +- .../BrnSmallOutlineButton.md | 4 +- .../BrnBottomWritePicker.md | 8 +-- .../picker/BrnDatePicker/BrnDatePicker.md | 2 - .../BrnDateRangePicker/BrnDateRangePicker.md | 4 +- .../BrnMultiSelectListPicker.md | 54 ++++++++++++++++++- .../BrnSelectTagsWithInputPicker.md | 4 +- lib/src/components/loading/brn_loading.dart | 4 +- 31 files changed, 150 insertions(+), 82 deletions(-) diff --git a/doc/components/abnormalCard/BrnAbnormalStateWidget/BrnAbnormalStateWidget.md b/doc/components/abnormalCard/BrnAbnormalStateWidget/BrnAbnormalStateWidget.md index ad782e93..374643f2 100644 --- a/doc/components/abnormalCard/BrnAbnormalStateWidget/BrnAbnormalStateWidget.md +++ b/doc/components/abnormalCard/BrnAbnormalStateWidget/BrnAbnormalStateWidget.md @@ -78,11 +78,11 @@ BrnAbnormalStateWidget( scale: 3.0, ), isCenterVertical: true, - title: BrnStrings.getDateFailed, - operateTexts: [BrnStrings.clickPageRetry], - operateAreaType: OperateAreaType.TextButton, + title: "获取数据失败,请重试", + operateTexts: ["请点击页面重试"], + operateAreaType: OperateAreaType.textButton, action: (index) { - BrnToast.show(BrnStrings.getDateFailed, context); + BrnToast.show("获取数据失败,请重试", context); }, ) ``` diff --git a/doc/components/appraise/BrnAppraise/BrnAppraise.md b/doc/components/appraise/BrnAppraise/BrnAppraise.md index 68381da8..e211754e 100644 --- a/doc/components/appraise/BrnAppraise/BrnAppraise.md +++ b/doc/components/appraise/BrnAppraise/BrnAppraise.md @@ -82,7 +82,7 @@ BrnAppraise( this.title = '', this.headerType = BrnAppraiseHeaderType.spaceBetween, this.type = BrnAppraiseType.Star, - this.iconDescriptions = _defaultIconDescriptions, + this.iconDescriptions, this.tags, this.inputHintText = '', this.onConfirm, @@ -97,7 +97,7 @@ BrnAppraise( | title | String | 标题 | 否 | '' | | headerType | BrnAppraiseHeaderType | 标题类型,居中还是两侧 | 否 | BrnAppraiseHeaderType.spaceBetween | | type | BrnAppraiseType | 评价组件类型,表情包还是五角星 | 否 | BrnAppraiseType.Star | -| iconDescriptions | `List` | 点击表情时对应等级的提示文案。若 `type=BrnAppraiseType.Emoji`,则 list 长度为 5,不足 5 个时请在对应位置补空字符串。若 `type=BrnAppraiseType.Star`,list 长度不能比传入的 BrnAppraiseConfig 中的 count 小。 | 否 | ['不好','还行','满意','很棒','超惊喜'] | +| iconDescriptions | `List?` | 点击表情时对应等级的提示文案。若 `type=BrnAppraiseType.Emoji`,则 list 长度为 5,不足 5 个时请在对应位置补空字符串。若 `type=BrnAppraiseType.Star`,list 长度不能比传入的 BrnAppraiseConfig 中的 count 小。 | 否 | 默认值为国际化配置的数组,['不好','还行','满意','很棒','超惊喜'] | | tags | `List?` | 供选择的标签数据 | 否 | 无 | | inputHintText | String | 输入框的提示文字 | 否 | '' | | onConfirm | BrnAppraiseConfirmClick? | 点击提交时的回调,其中 index 是选中的表情或者五角星的 index,selectedTags 是选中的标签,input 是输入框的内容 | 否 | 无 | @@ -125,7 +125,7 @@ BrnAppraise( | inputDefaultText | String? | 输入框默认文案 | 否 | 无 | | inputMaxHeight | double | 输入框的最大高度 | 否 | 120 | | showConfirmButton | bool | 是否显示提交按钮 | 否 | true | -| confirmButtonText | String | 提交按钮自定义文案 | 否 | '提交' | +| confirmButtonText | String? | 提交按钮自定义文案 | 否 | 默认值为国际化配置文本,'提交' | | isConfirmButtonEnabled | bool | 提交按钮的可用状态 | 否 | 默认 null,在打分之后 enable | | iconClickCallback | BrnAppraiseIconClick? | 点击打分时的回调 | 否 | 无 | | inputTextChangeCallback | BrnInputTextChangeCallback? | 输入框内容改变的回调 | 否 | 无 | diff --git a/doc/components/appraise/BrnAppraiseBottomPicker/BrnAppraiseBottomPicker.md b/doc/components/appraise/BrnAppraiseBottomPicker/BrnAppraiseBottomPicker.md index ccec6891..8c6eba4c 100644 --- a/doc/components/appraise/BrnAppraiseBottomPicker/BrnAppraiseBottomPicker.md +++ b/doc/components/appraise/BrnAppraiseBottomPicker/BrnAppraiseBottomPicker.md @@ -28,7 +28,7 @@ BrnAppraiseBottomPicker({ this.title = '', this.headerType = BrnAppraiseHeaderType.spaceBetween, this.type = BrnAppraiseType.Star, - this.iconDescriptions = _defaultIconDescriptions, + this.iconDescriptions, this.tags, this.inputHintText = '', this.onConfirm, @@ -43,7 +43,7 @@ BrnAppraiseBottomPicker({ | title | String | 标题 | 否 | '' | | headerType | BrnAppraiseHeaderType | 标题类型,居中还是两侧 | 否 | BrnAppraiseHeaderType.spaceBetween | | type | BrnAppraiseType | 评价组件类型,表情包还是五角星 | 否 | BrnAppraiseType.Star | -| iconDescriptions | `List` | 点击表情时对应等级的提示文案。若 `type=BrnAppraiseType.Emoji`,则list长度为5,不足5个时请在对应位置补空字符串。若 `type=BrnAppraiseType.Star`,list长度不能比传入的 BrnAppraiseConfig中的 count 小。 | 否 | ['不好', '还行', '满意', '很棒', '超惊喜'] | +| iconDescriptions | `List?` | 点击表情时对应等级的提示文案。若 `type=BrnAppraiseType.Emoji`,则list长度为5,不足5个时请在对应位置补空字符串。若 `type=BrnAppraiseType.Star`,list长度不能比传入的 BrnAppraiseConfig中的 count 小。 | 否 | 默认值为国际化配置的数组,['不好', '还行', '满意', '很棒', '超惊喜'] | | tags | `List?` | 供选择的标签数据 | 否 | 无 | | inputHintText | String | 输入框的提示文字 | 否 | '' | | onConfirm | `void Function(int index, List selectedTags, String input)?` | 点击提交时的回调,其中index是选中的表情或者五角星的index,selectedTags是选中的标签,input是输入框的内容 | 否 | 无 | diff --git a/doc/components/calendar/BrnCalendarView/BrnCalendarView.md b/doc/components/calendar/BrnCalendarView/BrnCalendarView.md index f58e59ef..3a879ad1 100644 --- a/doc/components/calendar/BrnCalendarView/BrnCalendarView.md +++ b/doc/components/calendar/BrnCalendarView/BrnCalendarView.md @@ -33,7 +33,7 @@ BrnCalendarView( {Key key, this.selectMode = SelectMode.SINGLE, this.displayMode = DisplayMode.Month, - this.weekNames = _defaultWeekNames, + this.weekNames, this.showControllerBar = true, this.initStartSelectedDate, this.initEndSelectedDate, @@ -49,7 +49,7 @@ BrnCalendarView( | --------------------- | -------------------------------------------------------------- | ---------------------------------------------------------- | ------------ | ------------------ | | selectMode | SelectMode | 选择模式,是范围选择 RANGE 还是单点选择 SINGLE | 否 | SINGLE | | displayMode | DisplatMode | 展示模式,是周视图 WEEK 还是月视图 MONTH | 否 | MONTH | -| weekNames | List | 自定义星期名字,以【周日】开始排列 | 否 | \_defaultWeekNames | +| weekNames | List | 自定义星期名字,以【周日】开始排列 | 否 | 默认值为国际化配置文本 \_defaultWeekNames | | showControllerBar | bool | 是否展示顶部切换日期控制按钮 | 否 | true | | initStartSelectedDate | DateTime | 初始选中开始时间 | 否 | 无 | | initEndSelectedDate | DateTime | 初始选中结束时间 | 否 | 无 | diff --git a/doc/components/charts/BrnBrokenLine/BrnBrokenLine.md b/doc/components/charts/BrnBrokenLine/BrnBrokenLine.md index 1206b72e..f45f5a2e 100644 --- a/doc/components/charts/BrnBrokenLine/BrnBrokenLine.md +++ b/doc/components/charts/BrnBrokenLine/BrnBrokenLine.md @@ -54,6 +54,7 @@ BrnBrokenLine({ this.isTipWindowAutoDismiss = true, this.isShowXDialText = false, this.isShowYDialText = false, + this.isShowXDial = true }) : super(key: key) { // 设置自定义 X 轴时,检查 x轴的最大、最小刻度范围 if (xDialValues != null) { @@ -90,6 +91,7 @@ BrnBrokenLine({ | isTipWindowAutoDismiss | bool | 点击弹出的 tip 提示框,是否自动消失 | 否 | true | | | isShowXDialText | bool | 是否展示 X 坐标刻度文案 | 否 | false | | | isShowYDialText | bool | 是否展示 Y 坐标刻度文案 | 否 | false | | +| isShowXDial | bool | 是否绘制 x 刻度 | 是 | true | | ### 其他数据结构 @@ -190,6 +192,9 @@ class BrnDialItem { /// 刻度标志样式 TextStyle? dialTextStyle; + /// 刻度选中样式 + TextStyle? selectedDialTextStyle; + /// x,y 轴刻度值。用于刻度在坐标的真实定位 double value; } diff --git a/doc/components/charts/BrnProgressChart/BrnProgressChart.md b/doc/components/charts/BrnProgressChart/BrnProgressChart.md index 197001b8..65a05380 100644 --- a/doc/components/charts/BrnProgressChart/BrnProgressChart.md +++ b/doc/components/charts/BrnProgressChart/BrnProgressChart.md @@ -41,7 +41,9 @@ const BrnProgressChart( this.brnProgressIndicatorBuilder, this.colors = const [Colors.blueAccent, Colors.blue], this.backgroundColor = Colors.lightBlueAccent, - this.showAnimation = false}) + this.showAnimation = false, + this.isFromLastValue = false, + this.duration = const Duration(milliseconds: 250),}) : assert(0 <= value && value <= 1, 'value 必须在 0 到 1 之间'), super(key: key); ``` @@ -58,6 +60,8 @@ const BrnProgressChart( | colors | `List` | 进度条颜色 | 否 | [Colors.blueAccent, Colors.blue] | | backgroundColor | Color | 背景色 | 否 | Colors.lightBlueAccent | | showAnimation | bool | 是否展示动画 | 否 | false | +| duration | Duration | 动画时长 | 是 | Duration(milliseconds: 250) | +| isFromLastValue | bool | 进度条动画是否从上次的值开始 | 是 | false | ## 四、代码演示 diff --git a/doc/components/dialog/BrnEnhanceOperationDialog/BrnEnhanceOperationDialog.md b/doc/components/dialog/BrnEnhanceOperationDialog/BrnEnhanceOperationDialog.md index a51e29c7..4417875a 100644 --- a/doc/components/dialog/BrnEnhanceOperationDialog/BrnEnhanceOperationDialog.md +++ b/doc/components/dialog/BrnEnhanceOperationDialog/BrnEnhanceOperationDialog.md @@ -36,7 +36,7 @@ BrnEnhanceOperationDialog({ required this.context, this.titleText, this.descText, - this.mainButtonText = '确认', + this.mainButtonText, this.secondaryButtonText, this.onMainButtonClick, this.onSecondaryButtonClick, @@ -60,7 +60,7 @@ BrnEnhanceOperationDialog({ | customIconWidget | Widget? | 自定义图标 | 否 | | | titleText | String? | 弹框标题文案(为空则**不显示**标题) | 否 | 无 | | descText | String? | 弹框辅助信息文案(为空则**不显示**辅助信息) | 否 | 无 | -| mainButtonText | String | 主要按钮文案 | 否 | 无 | +| mainButtonText? | String | 主要按钮文案 | 否 | 默认值为国际化配置文本 '确认' | | secondaryButtonText | String? | 次要按钮文案(为空则**不显示**次要按钮) | 否 | 无 | | mainButtonCallBack | VoidCallback? | 点击**主要按钮**后回调方法,使用者**根据参数自行配置响应动作**。 | 否 | 空 | | secondaryButtonCallBack | VoidCallback? | 点击**次要按钮**后回调方法,使用者**根据参数自行配置响应动作**。 | 否 | 空 | diff --git a/doc/components/dialog/BrnLoadingDialog/BrnLoadingDialog.md b/doc/components/dialog/BrnLoadingDialog/BrnLoadingDialog.md index 69263fe8..cadcfe75 100644 --- a/doc/components/dialog/BrnLoadingDialog/BrnLoadingDialog.md +++ b/doc/components/dialog/BrnLoadingDialog/BrnLoadingDialog.md @@ -24,7 +24,7 @@ group: ### 构造函数 ```dart -const BrnLoadingDialog({Key? key, this.content = BrnStrings.loadingContent}) +const BrnLoadingDialog({Key? key, this.content}) : super(key: key); ``` @@ -32,7 +32,7 @@ const BrnLoadingDialog({Key? key, this.content = BrnStrings.loadingContent}) | **参数名** | **参数类型** | **描述** | **是否必填** | **默认值** | | ---------- | ------------ | ---------- | ------------ | ---------- | -| content | String | 显示的文案 | 否 | 加载中... | +| content | String? | 显示的文案 | 否 | 默认值为国际化配置文本 '加载中...' | ## 四、效果及代码展示 diff --git a/doc/components/dialog/BrnMiddleInputDialog/BrnMiddleInputDialog.md b/doc/components/dialog/BrnMiddleInputDialog/BrnMiddleInputDialog.md index 3d8cabca..d7e4544e 100644 --- a/doc/components/dialog/BrnMiddleInputDialog/BrnMiddleInputDialog.md +++ b/doc/components/dialog/BrnMiddleInputDialog/BrnMiddleInputDialog.md @@ -28,6 +28,7 @@ const BrnMiddleInputDialog( {this.title, this.message, this.hintText, + this.keyboardType, this.maxLength = 20, this.maxLines, this.minLines: 1, @@ -35,8 +36,8 @@ const BrnMiddleInputDialog( this.inputEditingController, this.inputFormatters, this.textInputAction = TextInputAction.newline, - this.cancelText = '取消', - this.confirmText = '确定', + this.cancelText, + this.confirmText, this.onConfirm, this.onCancel, this.dismissOnActionsTap = true, @@ -51,13 +52,14 @@ const BrnMiddleInputDialog( | title | String? | 标题 | 否 | | | message | String? | 辅助内容 | 否 | | | hintText | String? | 提示语 | 否 | | +| keyboardType | TextInputType? | 输入类型 | 否 | | | maxLength | int | 最大输入长度 | 否 | 20 | | maxLines | int? | 可输入的最maxLines多行数。超过 [maxLines] 指定的行数后,输入内容会变成可滑动 | 否 | | | minLines | int | 可输入的最少行数 | 否 | 1 | | inputFocusNode | FocusNode? | 焦点控制 | 否 | | | inputEditingController | TextEditingController? | 输入控制器。如果有初始状态的填充文字,可以通过 [inputEditingController] 设置 | 否 | | -| cancelText | String | 取消文案 | 否 | 取消 | -| confirmText | String | 确定文案 | 否 | 确定 | +| cancelText? | String | 取消文案 | 否 | 默认值为国际化配置文本 '取消' | +| confirmText? | String | 确定文案 | 否 | 默认值为国际化配置文本 '确定' | | inputFormatters | `List?` | 键盘操作按钮类型,可参见系统的 TextField.textInputAction | 否 | TextInputAction.newline | | textInputAction | `TextInputAction` | 用于控制输入的内容范围比如只能输入数字可以填写:`FilteringTextInputFormatter.digitsOnly` | 否 | 无 | | onConfirm | void Function(String value)? | 确定回调,返回输入的值 | 否 | | diff --git a/doc/components/dialog/BrnMultiSelectDialog/BrnMultiSelectDialog.md b/doc/components/dialog/BrnMultiSelectDialog/BrnMultiSelectDialog.md index 8cb174f1..1f2afd8c 100644 --- a/doc/components/dialog/BrnMultiSelectDialog/BrnMultiSelectDialog.md +++ b/doc/components/dialog/BrnMultiSelectDialog/BrnMultiSelectDialog.md @@ -32,7 +32,7 @@ BrnMultiSelectDialog({ this.messageWidget, this.customWidget, this.isCustomFollowScroll = true, - this.submitText = "提交", + this.submitText, this.submitBgColor, this.onSubmitClick, this.onItemClick, @@ -53,7 +53,7 @@ BrnMultiSelectDialog({ | isCustomFollowScroll | bool | 是否支持滚动 | 否 | true | | onSubmitClick | BrnMultiSelectDialogClickSubmitCallback? | 点击【完成】时回调给外部选中的数据 | 否 | | | onItemClick | BrnMultiSelectDialogOnItemClickCallback? | Item 被点击的回调 | 否 | | -| submitText | String | 底部提交按钮的文案 | 否 | 提交 | +| submitText | String? | 底部提交按钮的文案 | 否 | 默认值为国际化配置文本 '提交' | | submitBgColor | Color? | 底部按钮的主题色 | 否 | 主题色 | | isShowOperateWidget | bool | 是否展示底部操作区域 | 否 | true | diff --git a/doc/components/dialog/BrnSingleSelectDialog/BrnSingleSelectDialog.md b/doc/components/dialog/BrnSingleSelectDialog/BrnSingleSelectDialog.md index 5b6bfcca..32c2637e 100644 --- a/doc/components/dialog/BrnSingleSelectDialog/BrnSingleSelectDialog.md +++ b/doc/components/dialog/BrnSingleSelectDialog/BrnSingleSelectDialog.md @@ -30,7 +30,7 @@ const BrnSingleSelectDialog( this.messageText, this.messageWidget, required this.conditions, - this.submitText: "提交", + this.submitText, this.submitBgColor, this.onSubmitClick, this.onItemClick, @@ -51,7 +51,7 @@ const BrnSingleSelectDialog( | messageWidget | Widget? | 描述 Widget | 否 | | | conditions | List | 备选项数组 | 否 | | | checkedItem | String | 选中的选项名称 | 否 | | -| submitText | String | 确定/提交 按钮文案 | 否 | | +| submitText | String? | 确定/提交 按钮文案 | 否 | 默认值为国际化配置文本 '提交' | | submitBgColor | Color | 提交按钮背景颜色 | 否 | | | customWidget | Widget | 在单选列表底部自定义 Widget | 否 | null | | onCloseClick | VoidCallback | 点击关闭 icon 的回调 | 否 | null | diff --git a/doc/components/form/BrnRangeInputFormItem/BrnRangeInputFormItem.md b/doc/components/form/BrnRangeInputFormItem/BrnRangeInputFormItem.md index 39c6c69e..49b859a6 100644 --- a/doc/components/form/BrnRangeInputFormItem/BrnRangeInputFormItem.md +++ b/doc/components/form/BrnRangeInputFormItem/BrnRangeInputFormItem.md @@ -54,8 +54,8 @@ BrnRangeInputFormItem( this.onAddTap, this.onRemoveTap, this.onTip, - this.hintMin: '最小', - this.hintMax: '最大', + this.hintMin, + this.hintMax, this.minUnit, this.maxUnit, this.leftMaxCount, @@ -100,8 +100,8 @@ BrnRangeInputFormItem( | onTip | VoidCallback? | 点击"?"图标回调 | 否 | 无 | 见**tipLabel**字段 | | minUnit | String? | 最小范围单位 | 否 | 无 | | | maxUnit | String? | 最大范围单位 | 否 | 无 | | -| hintMin | String | 最小范围录入项 hint 提示 | 否 | "最小" | | -| hintMax | String | 最大范围录入项 hint 提示 | 否 | "最大" | | +| hintMin | String? | 最小范围录入项 hint 提示 | 否 | 默认值为国际化配置文本 "最小" | | +| hintMax | String? | 最大范围录入项 hint 提示 | 否 | 默认值为国际化配置文本 "最大" | | | leftMaxCount | int? | 最小值输入框最大字符数 | 否 | 无 | | | rightMaxCount | int? | 最大值输入框最大字符数 | 否 | 无 | | | inputType | String? | 输入内容类型,指定键盘类型,参见 `BrnInputType` | 否 | 无 | 详见**BrnInputType**类,注意:无法通过指定键盘类型确保输入。比如不能通过指定数字键盘确保用户只输入数字。如果有要求用户只输入特定字符的需求请使用**inputFormatters**参数 | diff --git a/doc/components/form/BrnRatioInputFormItem/BrnRatioInputFormItem.md b/doc/components/form/BrnRatioInputFormItem/BrnRatioInputFormItem.md index 3f0c60d6..49af9367 100644 --- a/doc/components/form/BrnRatioInputFormItem/BrnRatioInputFormItem.md +++ b/doc/components/form/BrnRatioInputFormItem/BrnRatioInputFormItem.md @@ -52,7 +52,7 @@ BrnRatioInputFormItem( this.onAddTap, this.onRemoveTap, this.onTip, - this.hint: "请输入", + this.hint, this.inputType, this.controller, this.inputFormatters, @@ -88,7 +88,7 @@ BrnRatioInputFormItem( | onAddTap | VoidCallback? | 点击"+"图标回调 | 否 | 无 | 见**prefixIconType**字段 | | onRemoveTap | VoidCallback? | 点击"-"图标回调 | 否 | 无 | 见**prefixIconType**字段 | | onTip | VoidCallback? | 点击"?"图标回调 | 否 | 无 | 见**tipLabel**字段 | -| hint | String | 录入项 hint 提示 | 否 | "请输入" | | +| hint | String? | 录入项 hint 提示 | 否 | 默认值为国际化配置文本 "请输入" | | | inputType | String? | 输入内容类型,指定键盘类型,参见 `BrnInputType` | 否 | 无 | 详见**BrnInputType**类,注意:无法通过指定键盘类型确保输入。比如不能通过指定数字键盘确保用户只输入数字。如果有要求用户只输入特定字符的需求请使用**inputFormatters**参数 | | inputFormatters | `List?` | 指定对输入数据的格式化要求 | 否 | 无 | | | onChanged | `ValueChanged?` | 输入文案回调 | 否 | 无 | | diff --git a/doc/components/form/BrnTextBlockInputFormItem/BrnTextBlockInputFormItem.md b/doc/components/form/BrnTextBlockInputFormItem/BrnTextBlockInputFormItem.md index 331a0719..6fa13812 100644 --- a/doc/components/form/BrnTextBlockInputFormItem/BrnTextBlockInputFormItem.md +++ b/doc/components/form/BrnTextBlockInputFormItem/BrnTextBlockInputFormItem.md @@ -55,7 +55,7 @@ BrnTextBlockInputFormItem( this.onRemoveTap, this.onTip, this.onChanged, - this.hint = "请输入", + this.hint, this.maxCharCount, this.autofocus: false, this.inputType, @@ -93,7 +93,7 @@ BrnTextBlockInputFormItem( | onAddTap | VoidCallback? | 点击"+"图标回调 | 否 | 无 | 见**prefixIconType**字段 | | onRemoveTap | VoidCallback? | 点击"-"图标回调 | 否 | 无 | 见**prefixIconType**字段 | | onTip | VoidCallback? | 点击"?"图标回调 | 否 | 无 | 见**tipLabel**字段 | -| hint | String | 录入项 hint 提示 | 否 | "请输入" | | +| hint | String? | 录入项 hint 提示 | 否 | 默认值为国际化配置文本 "请输入" | | | maxCharCount | int? | 最大输入字符数 | 否 | 无 | | | autofocus | bool | 是否自动获取焦点 | 否 | false | | | inputType | String? | 输入内容类型,指定键盘类型,参见 `BrnInputType` | 否 | 无 | 详见**BrnInputType**类,注意:无法通过指定键盘类型确保输入。比如不能通过指定数字键盘确保用户只输入数字。如果有要求用户只输入特定字符的需求请使用**inputFormatters**参数 | diff --git a/doc/components/form/BrnTextInputFormItem/BrnTextInputFormItem.md b/doc/components/form/BrnTextInputFormItem/BrnTextInputFormItem.md index ece6ddc2..6d6fe1dc 100644 --- a/doc/components/form/BrnTextInputFormItem/BrnTextInputFormItem.md +++ b/doc/components/form/BrnTextInputFormItem/BrnTextInputFormItem.md @@ -46,16 +46,18 @@ BrnTextInputFormItem({ this.title = "", this.subTitle, this.tipLabel, + this.focusNode, this.prefixIconType = BrnPrefixIconType.normal, this.error = "", this.isEdit = true, + this.obscureText = false, this.isRequire = false, this.isPrefixIconEnabled = false, this.onAddTap, this.onRemoveTap, this.onTip, this.prefixText, - this.hint = "请输入", + this.hint, this.unit, this.maxCharCount, this.autofocus: false, @@ -85,16 +87,18 @@ BrnTextInputFormItem({ | title | String | 录入项标题 | 否 | '' | | | subTitle | String? | 录入项子标题 | 否 | 无 | | | tipLabel | String? | 录入项提示(问号图标&文案) 用户点击时触发onTip回调。 | 否 | 备注中类型3 | 1. 设置"空字符串"时展示问号图标 2. 设置"非空字符串"时展示问号图标&文案 3. 若不赋值或赋值为null时,不显示提示项 | +| focusNode | FocusNode? | 录入项的焦点控制对象,主要用于控制焦点 | 否 | | | | prefixIconType | String | 录入项前缀图标样式 "添加项" "删除项" 详见 **BrnPrefixIconType** 类 | 否 | BrnPrefixIconType.normal | 1. 不展示图标:BrnPrefixIconType.normal 2. 展示加号图标:BrnPrefixIconType.add 3. 展示减号图标:BrnPrefixIconType.remove | | error | String | 录入项错误提示 | 否 | '' | | | isRequire | bool | 录入项是否为必填项(展示`*`图标) 默认为 false 不必填 | 否 | false | | | isEdit | bool | 录入项 是否可编辑 | 否 | true | true:可编辑false:禁用 | +| obscureText | bool | 录入项 是否模糊文本(输入后*代替文本,常用于密码框) 默认值 | | false | | | isPrefixIconEnabled | bool | 录入项不可编辑时(isEdit: false) "+"、"-"号是否可点击,true: 可点击回调 false: 不可点击回调 | 否 | false | | | onAddTap | VoidCallback? | 点击"+"图标回调 | 否 | 无 | 见**prefixIconType**字段 | | onRemoveTap | VoidCallback? | 点击"-"图标回调 | 否 | 无 | 见**prefixIconType**字段 | | onTip | VoidCallback? | 点击"?"图标回调 | 否 | 无 | | | prefixText | String? | 固定前缀文案 | 否 | 无 | | -| hint | String | 录入项 hint 提示 | 否 | "请输入" | | +| hint | String? | 录入项 hint 提示 | 否 | 默认值为国际化配置文本 "请输入" | | | unit | String? | 单位 | 否 | 无 | | | maxCharCount | int? | 最大输入字符数 | 否 | 无 | | | autofocus | bool | 是否自动获取焦点 | 否 | false | | diff --git a/doc/components/form/BrnTextQuickSelectFormItem/BrnTextQuickSelectFormItem.md b/doc/components/form/BrnTextQuickSelectFormItem/BrnTextQuickSelectFormItem.md index 1f8f73b6..8dde62eb 100644 --- a/doc/components/form/BrnTextQuickSelectFormItem/BrnTextQuickSelectFormItem.md +++ b/doc/components/form/BrnTextQuickSelectFormItem/BrnTextQuickSelectFormItem.md @@ -46,7 +46,7 @@ BrnTextQuickSelectFormItem( this.onAddTap, this.onRemoveTap, this.onTip, - this.hint: "请选择", + this.hint, this.value, this.btnsTxt, this.selectBtnList, @@ -87,7 +87,7 @@ BrnTextQuickSelectFormItem( | onAddTap | VoidCallback? | 点击"+"图标回调 | 否 | 无 | 见prefixIconType字段 | | onRemoveTap | VoidCallback? | 点击"-"图标回调 | 否 | 无 | 见prefixIconType字段 | | onBtnSelectChanged | `ValueChanged?` | 按钮选中文案,会把选中的序号回调出去。 | 否 | 无 | | -| hint | String | 录入项 hint 提示 | 否 | '请选择' | | +| hint | String? | 录入项 hint 提示 | 否 | 默认值为国际化配置文本 '请选择' | | | btnsTxt | `List?` | 快捷操作按钮选项文案列表 | 否 | 无 | | | selectBtnList | `List?` | 快捷按钮区的初始选中状态 | 否 | 无 | | | enableBtnList | `List?` | 快捷按钮区的是否可用状态 | 否 | 无 | | diff --git a/doc/components/form/BrnTitleSelectInputFormItem/BrnTitleSelectInputFormItem.md b/doc/components/form/BrnTitleSelectInputFormItem/BrnTitleSelectInputFormItem.md index 0585e391..a271956a 100644 --- a/doc/components/form/BrnTitleSelectInputFormItem/BrnTitleSelectInputFormItem.md +++ b/doc/components/form/BrnTitleSelectInputFormItem/BrnTitleSelectInputFormItem.md @@ -53,7 +53,7 @@ BrnTitleSelectInputFormItem( this.onAddTap, this.onRemoveTap, this.onTip, - this.hint = "请输入", + this.hint, this.maxCount, this.inputType = BrnInputType.text, this.selectedIndex = -1, @@ -93,7 +93,7 @@ BrnTitleSelectInputFormItem( | onAddTap | VoidCallback? | 点击"+"图标回调 | 否 | 无 | 见**prefixIconType**字段 | | onRemoveTap | VoidCallback? | 点击"-"图标回调 | 否 | 无 | 见**prefixIconType**字段 | | onTip | VoidCallback? | 点击"?"图标回调 | 否 | 无 | 见**tipLabel**字段 | -| hint | String | 录入项 hint 提示 | 否 | "请输入" | | +| hint | String? | 录入项 hint 提示 | 否 | 默认值为国际化配置文本 "请输入" | | | maxCount | int? | 最大输入字符数 | 否 | 无 | | | inputType | String | 指定键盘类型 | 否 | BrnInputType.TEXT | 详见**BrnInputType**类,注意:无法通过指定键盘类型确保输入。比如不能通过指定数字键盘确保用户只输入数字。如果有要求用户只输入特定字符的需求请使用**inputFormatters**参数 | | inputFormatters | `List?` | 指定对输入数据的格式化要求 | 否 | 无 | | diff --git a/doc/components/iconButton/BrnIconButton/BrnIconButton.md b/doc/components/iconButton/BrnIconButton/BrnIconButton.md index b19b6fbd..2eccc635 100644 --- a/doc/components/iconButton/BrnIconButton/BrnIconButton.md +++ b/doc/components/iconButton/BrnIconButton/BrnIconButton.md @@ -34,6 +34,7 @@ const BrnIconButton({ this.onTap, this.iconWidth = 24, this.iconHeight = 24, + @Deprecated('该字段废弃,请使用 style ,未来版本会删除该字段') this.fontSize = 11, this.widgetWidth = 80, this.widgetHeight = 80, @@ -46,20 +47,20 @@ const BrnIconButton({ ### 参数说明 -| 参数名 | 参数类型 | 描述 | 是否必填 | 默认值 | -| ----------------- | -------------------------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ | -| name | String | 图文组合文字的名称 | 否 | 空 | -| iconWidget | Widget? | 图文组合需要展示的图片/可以是置灰的图片 | 否 | 空 | -| onTap | VoidCallback? | 点击的回调 | 否 | 空 | -| direction | enum Direction { left, right, top, bottom, } | 文字相对于图片的位置。 bottom:文字在下 icon 在上, top:文字在上 icon 在下 ,left:文字在左 icon 在右,right:文字在右 icon 在左 | 否 | top | -| iconWidth | double | 图片的宽度 | 否 | 24 | -| iconHeight | Color | 图片的高度 | 否 | 24 | -| widgetWidth | double | 图文组合的宽度 | 否 | 80 | -| widgetHeight | double | 图文组合的高度 | 否 | 80 | -| padding | double | 文字和图片的间距 | 否 | 4 | -| style | TextStyle? | 文字样式 | 否 | TextStyle( fontSize: 11, color: BrunoColor.instance.F2Color, ), | -| fontSize | double | 文字字体大小 | 否 | 11 | -| mainAxisAlignment | MainAxisAlignment | 图文对齐方式 | 否 | MainAxisAlignment.center | +| 参数名 | 参数类型 | 描述 | 是否必填 | 默认值 | +| ---------------------------- | -------------------------------------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------------------ | +| name | String | 图文组合文字的名称 | 否 | 空 | +| iconWidget | Widget? | 图文组合需要展示的图片/可以是置灰的图片 | 否 | 空 | +| onTap | VoidCallback? | 点击的回调 | 否 | 空 | +| direction | enum Direction { left, right, top, bottom, } | 文字相对于图片的位置。 bottom:文字在下 icon 在上, top:文字在上 icon 在下 ,left:文字在左 icon 在右,right:文字在右 icon 在左 | 否 | top | +| iconWidth | double | 图片的宽度 | 否 | 24 | +| iconHeight | Color | 图片的高度 | 否 | 24 | +| widgetWidth | double | 图文组合的宽度 | 否 | 80 | +| widgetHeight | double | 图文组合的高度 | 否 | 80 | +| padding | double | 文字和图片的间距 | 否 | 4 | +| style | TextStyle? | 文字样式 | 否 | TextStyle( fontSize: 11, color: BrunoColor.instance.F2Color, ), | +| **@Deprecated**
fontSize | double | 文字字体大小
**Deprecated 该字段废弃,请使用 style ,未来版本会删除该字段** | 否 | 11 | +| mainAxisAlignment | MainAxisAlignment | 图文对齐方式 | 否 | MainAxisAlignment.center | ## 四、代码演示 diff --git a/doc/components/input/BrnInputText/BrnInputText.md b/doc/components/input/BrnInputText/BrnInputText.md index 10dbfdc8..24de63d7 100644 --- a/doc/components/input/BrnInputText/BrnInputText.md +++ b/doc/components/input/BrnInputText/BrnInputText.md @@ -36,13 +36,14 @@ group: this.bgColor = Colors.white, this.maxLength = 200, this.minLines = 1, - this.hint = "请输入", + this.hint, this.maxHintLines, this.padding = EdgeInsets.zero, this.textString = "", this.autoFocus, this.textEditingController, this.focusNode, + this.textInputAction, this.textInputAction = TextInputAction.done, this.borderRadius, this.borderColor, @@ -53,7 +54,7 @@ group: | **参数名** | **参数类型** | **描述** | **是否必填** | **默认值** | | --------------------- | ---------------------------------------------------- | ------------------------------------------------------------ | ------------ | -------------------- | -| hint | String | 输入提示语,默认为"请输入..." | 否 | "请输入..." | +| hint | String? | 输入提示语,默认为"请输入" | 否 | 默认值为国际化配置文本 "请输入" | | textString | String | 输入框初始值 | 否 | "" | | maxHintLines | int? | 最大 hint 行数 | | | | textEditingController | TextEditingController? | 用于对 TextField 更精细的控制,若传入该字段,[textString] 参数将失效,可使用 TextEditingController.text 进行赋值 | 否 | | @@ -69,6 +70,7 @@ group: | borderRadius | double? | 背景圆角 | 否 | | | autoFocus | bool? | 光标展示 | 否 | | | focusNode | FocusNode | 搜索框的焦点控制器 | 否 | | +| textInputAction | TextInputAction? | 选择键盘的完成按钮 | 否 | | | padding | EdgeInsetsGeometry | 文字距离边框的边距 | 否 | EdgeInsets.zero | | textEditingController | TextInputAction | 键盘输入行为 | 否 | TextInputAction.done | diff --git a/doc/components/loading/BrnPageLoading/BrnPageLoading.md b/doc/components/loading/BrnPageLoading/BrnPageLoading.md index dde58c04..cac1e382 100644 --- a/doc/components/loading/BrnPageLoading/BrnPageLoading.md +++ b/doc/components/loading/BrnPageLoading/BrnPageLoading.md @@ -22,15 +22,17 @@ group: ### 构造函数 ```dart - const BrnLoadingDialog({Key? key, this.content = BrnStrings.loadingContent}) - : super(key: key); +const BrnPageLoading({Key? key, + this.content, + this.constraints = const BoxConstraints(minWidth: 130, maxWidth: 130, minHeight: 50, maxHeight: 50,), +}): super(key: key); ``` ### 参数配置 | **参数名** | **参数类型** | **描述** | **是否必填** | **默认值** | | --- | --- | --- | --- | --- | -| content | String | 显示的文案 | 否 | 加载中... | - +| content | String? | 显示的文案 | 否 | 默认值为国际化配置文本 '加载中...' | +| constraints | BoxConstraints | 约束 | 否 | BoxConstraints(minWidth: 130, maxWidth: 130, minHeight: 50, maxHeight: 50,) | ## 四、代码演示 ###  效果1:只有主按钮 diff --git a/doc/components/normalButton/BrnBigGhostButton/BrnBigGhostButton.md b/doc/components/normalButton/BrnBigGhostButton/BrnBigGhostButton.md index a5f9a937..61acfbdf 100644 --- a/doc/components/normalButton/BrnBigGhostButton/BrnBigGhostButton.md +++ b/doc/components/normalButton/BrnBigGhostButton/BrnBigGhostButton.md @@ -25,7 +25,7 @@ group: ```dart const BrnBigGhostButton({ Key? key, - this.title = '确认', + this.title, this.titleColor, this.bgColor, this.onTap, @@ -37,7 +37,7 @@ const BrnBigGhostButton({ | **参数名** | **参数类型** | 描述 | **是否必填** | **默认值** | | --- | --- | --- | --- | --- | -| title | String | 按钮显示文案 | 否 | 确认 | +| title | String? | 按钮显示文案 | 否 | 默认值为国际化配置文本,确认 | | onTap | VoidCallback? | 点击的回调 | 否 | 无 | | bgColor | Color? | 按钮的背景色 | 否 | 主题色为5透明度的颜色 | | width | double? | 按钮的宽度 | 否 | double.infinity | diff --git a/doc/components/normalButton/BrnBigMainButton/BrnBigMainButton.md b/doc/components/normalButton/BrnBigMainButton/BrnBigMainButton.md index 2c4462c5..f88314af 100644 --- a/doc/components/normalButton/BrnBigMainButton/BrnBigMainButton.md +++ b/doc/components/normalButton/BrnBigMainButton/BrnBigMainButton.md @@ -27,7 +27,7 @@ group: ```dart const BrnBigMainButton({ Key? key, - this.title = '确认', + this.title, this.width, this.isEnable = true, this.onTap, @@ -39,7 +39,7 @@ const BrnBigMainButton({ | **参数名** | **参数类型** | 描述 | **是否必填** | **默认值** | | --- | --- | --- | --- | --- | -| title | String | 按钮显示文案 | 否 | `'确认'` | +| title | String? | 按钮显示文案 | 否 | 默认值为国际化配置文本 `'确认'` | | onTap | VoidCallback? | 点击的回调 | 否 | 无 | | isEnable | bool | 按钮是否可用 | 否 | false | | bgColor | Color? | 按钮的背景色 | 否 | 主题色 | diff --git a/doc/components/normalButton/BrnBigOutlineButton/BrnBigOutlineButton.md b/doc/components/normalButton/BrnBigOutlineButton/BrnBigOutlineButton.md index 95488697..e36bfd3a 100644 --- a/doc/components/normalButton/BrnBigOutlineButton/BrnBigOutlineButton.md +++ b/doc/components/normalButton/BrnBigOutlineButton/BrnBigOutlineButton.md @@ -26,7 +26,7 @@ group: ```dart const BrnBigOutlineButton({ Key? key, - this.title = '确认', + this.title, this.lineColor, this.textColor, this.isEnable = true, @@ -39,7 +39,7 @@ const BrnBigOutlineButton({ | **参数名** | **参数类型** | 描述 | **是否必填** | **默认值** | | --- | --- | --- | --- | --- | -| title | String | 按钮显示文案 | 否 | '确认' | +| title | String? | 按钮显示文案 | 否 | 默认值为国际化配置文本 '确认' | | onTap | VoidCallback? | 点击的回调 | 否 | 无 | | isEnable | bool | 按钮是否可用 | 否 | True | | lineColor | Color? | 边框颜色 | 否 | 主题色 | diff --git a/doc/components/normalButton/BrnSmallMainButton/BrnSmallMainButton.md b/doc/components/normalButton/BrnSmallMainButton/BrnSmallMainButton.md index 5978b472..9a074497 100644 --- a/doc/components/normalButton/BrnSmallMainButton/BrnSmallMainButton.md +++ b/doc/components/normalButton/BrnSmallMainButton/BrnSmallMainButton.md @@ -25,7 +25,7 @@ group: ```dart const BrnSmallMainButton({ Key? key, - this.title = '确认', + this.title, this.onTap, this.isEnable = true, this.bgColor, @@ -43,7 +43,7 @@ const BrnSmallMainButton({ | 参数名 | 参数类型 | 描述 | 是否必填 | 默认值 | | ---------- | --------------- | -------------- | -------- | --------------- | -| title | String | 按钮显示文案 | 否 | '确认' | +| title | String? | 按钮显示文案 | 否 | 默认值为国际化配置文本 '确认' | | onTap | VoidCallback? | 点击的回调 | 否 | 无 | | isEnable | bool | 按钮是否可用 | 否 | True | | bgColor | Color? | 按钮的背景色 | 否 | 主题色 | diff --git a/doc/components/normalButton/BrnSmallOutlineButton/BrnSmallOutlineButton.md b/doc/components/normalButton/BrnSmallOutlineButton/BrnSmallOutlineButton.md index 1984ee8e..c93ebebe 100644 --- a/doc/components/normalButton/BrnSmallOutlineButton/BrnSmallOutlineButton.md +++ b/doc/components/normalButton/BrnSmallOutlineButton/BrnSmallOutlineButton.md @@ -25,7 +25,7 @@ group: ```dart const BrnSmallOutlineButton({ Key? key, - this.title = '确认', + this.title, this.onTap, this.isEnable = true, this.lineColor, @@ -42,7 +42,7 @@ const BrnSmallOutlineButton({ | 参数名 | 参数类型 | 描述 | 是否必填 | 默认值 | | ---------- | ---------------- | ------------ | -------- | --------------- | -| title | String | 按钮显示文案 | 否 | '确认' | +| title | String? | 按钮显示文案 | 否 | 默认值为国际化配置文本 '确认' | | onTap | VoidCallback? | 点击的回调 | 否 | 无 | | isEnable | bool | 按钮是否可用 | 否 | true | | lineColor | Color? | 边框的背景色 | 否 | 主题色 | diff --git a/doc/components/picker/BrnBottomWritePicker/BrnBottomWritePicker.md b/doc/components/picker/BrnBottomWritePicker/BrnBottomWritePicker.md index 792ba7d3..60ef0e63 100644 --- a/doc/components/picker/BrnBottomWritePicker/BrnBottomWritePicker.md +++ b/doc/components/picker/BrnBottomWritePicker/BrnBottomWritePicker.md @@ -30,7 +30,7 @@ group: ```dart const BrnBottomWritePicker( {this.maxLength = 200, - this.hintText = "请输入", + this.hintText, this.leftTag = "取消", this.title = "", this.rightTag = "确认", @@ -47,10 +47,10 @@ const BrnBottomWritePicker( | 参数名 | 参数类型 | 作用 | 是否必填 | 默认值 | | --------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -------- | ------ | | maxLength | int | 最大输入长度 | 否 | 200 | -| hintText | String | 提示语 | 否 | 请输入 | -| leftTag | String | 左侧按钮文案 | 否 | 取消 | +| hintText | String? | 提示语 | 否 | 默认值为国际化配置文本 '请输入' | +| leftTag | String? | 左侧按钮文案 | 否 | 默认值为国际化配置文本 '取消' | | title | String | 标题文案 | 否 | | -| rightTag | String | 右侧按钮文案 | 否 | 确认 | +| rightTag | String? | 右侧按钮文案 | 否 | 默认值为国际化配置文本 '确认' | | cancel | BrnBottomWritePickerClickCallback = Future Function(String content)? | 取消输入事件回调 | 否 | | | confirm | BrnBottomWritePickerConfirmClickCallback = Future Function( BuildContext dialogContext, String content)? | 确认输入事件回调 | 否 | | | rightTextColor | Color? | 右侧文案 Color | 否 | 主题色 | diff --git a/doc/components/picker/BrnDatePicker/BrnDatePicker.md b/doc/components/picker/BrnDatePicker/BrnDatePicker.md index 5b159532..577e4180 100644 --- a/doc/components/picker/BrnDatePicker/BrnDatePicker.md +++ b/doc/components/picker/BrnDatePicker/BrnDatePicker.md @@ -51,7 +51,6 @@ static void showDatePicker( DateTime? initialDateTime, String? dateFormat, int minuteDivider: 1, - DateTimePickerLocale locale: DATETIME_PICKER_LOCALE_DEFAULT, BrnDateTimePickerMode pickerMode: BrnDateTimePickerMode.date, BrnPickerTitleConfig pickerTitleConfig, DateVoidCallback? onCancel, @@ -72,7 +71,6 @@ static void showDatePicker( | initialDateTime | DateTime? | 初始选择的时间 | 否 | 当前时间 | | minDateTime | DateTime? | 能滚动到的最小日期 | 否 | minDateTime ≤ maxDateTime | | maxDateTime | DateTime? | 能滚动到的最大日期 | 否 | minDateTime ≤ maxDateTime | -| locale | DateTimePickerLocale | 设置本地语言 | 否 | DateTimePickerLocale.zh\_cn | | pickerMode | BrnDateTimePickerMode | 时间选择组件显示的时间类型 | 否 | BrnDateTimePickerMode.date | | pickerTitleConfig | BrnPickerTitleConfig | 时间选择组件的主题样式 | 否 | BrnPickerTitleConfig.Default | | dateFormat | String? | 时间格式化的格式 | 是 | | diff --git a/doc/components/picker/BrnDateRangePicker/BrnDateRangePicker.md b/doc/components/picker/BrnDateRangePicker/BrnDateRangePicker.md index c2c3a4bb..4674e3e8 100644 --- a/doc/components/picker/BrnDateRangePicker/BrnDateRangePicker.md +++ b/doc/components/picker/BrnDateRangePicker/BrnDateRangePicker.md @@ -50,7 +50,6 @@ static void showDatePicker( DateTime? initialEndDateTime, String? dateFormat, int minuteDivider = 1, - DateTimePickerLocale locale = datetimePickerLocaleDefault, BrnDateTimeRangePickerMode pickerMode = BrnDateTimeRangePickerMode.date, BrnPickerTitleConfig pickerTitleConfig = BrnPickerTitleConfig.Default, DateVoidCallback? onCancel, @@ -72,7 +71,6 @@ static void showDatePicker( | initialEndDateTime | DateTime? | 初始设置选中的结束时间 | 否 | DateTime.now() | | dateFormat | String? | 展示格式,仅在pickerMode 为 DateTimeRangePickerMode.date时生效。可设置为”MM月-dd日“、”yyyy-年MM月-dd日“等年月日格式,将数据带上单位显示 | 否 | 'MM-dd' | | minuteDivider | int | 刻度值,仅在pickerMode 为DateTimeRangePickerMode.time时生效 | 否 | 1 | -| locale | DateTimePickerLocale | 时区 | 否 | DateTimePickerLocale.zh\_cn | | pickerMode | DateTimeRangePickerMode | 要展示的时间范围选择类型,date 还是 time | 否 | DateTimeRangePickerMode.date | | pickerTitleConfig | `BrnPickerTitleConfig` | picker title 内容配置 | 否 | BrnPickerTitleConfig.Default | | onCancel | DateVoidCallback? | 取消回调 | 否 | | @@ -92,7 +90,7 @@ const BrnPickerTitleConfig({ this.confirm,/// 确认 widget,默认文案【完成】 this.title, /// Title widget。 this.showTitle: DATETIME_PICKER_SHOW_TITLE_DEFAULT, /// 是否展示 title,默认true 展示 - this.titleContent:"请选择" /// Title 文案 + this.titleContent /// Title 文案 }); ``` diff --git a/doc/components/picker/BrnMultiSelectListPicker/BrnMultiSelectListPicker.md b/doc/components/picker/BrnMultiSelectListPicker/BrnMultiSelectListPicker.md index 428c861f..27690d07 100644 --- a/doc/components/picker/BrnMultiSelectListPicker/BrnMultiSelectListPicker.md +++ b/doc/components/picker/BrnMultiSelectListPicker/BrnMultiSelectListPicker.md @@ -74,7 +74,7 @@ BrnPickerTitleConfig({ this.confirm, this.title, this.showTitle: PICKER_SHOW_TITLE_DEFAULT, - this.titleContent: "请选择", + this.titleContent, }); ``` @@ -152,3 +152,55 @@ showModalBottomSheet( }, ); ``` + +### 效果 3:页面底部 Picker 多选,自定义数据协议 + + + +```dart +List items = []; +items.add(new ExpendMultiSelectBottomPickerItem("100", "这里是标题1",attribute1: "第一条自定义参数1")); +items.add(new ExpendMultiSelectBottomPickerItem("101", "这里是标题2",attribute1: "第二条自定义参数2")); +items.add(new ExpendMultiSelectBottomPickerItem("102", "这里是标题3", isChecked: true,attribute1: "第三条自定义参数3")); +items.add(new ExpendMultiSelectBottomPickerItem("103", "这里是标题4", isChecked: true)); +items.add(new ExpendMultiSelectBottomPickerItem("104", "这里是标题5")); +items.add(new ExpendMultiSelectBottomPickerItem("104", "这里是标题6")); +BrnMultiSelectListPicker.show( + context, + items: items, + pickerTitleConfig: BrnPickerTitleConfig(titleContent: "多选 Picker"), + onSubmit: (List data) { + var str = ""; + data.forEach((item) { + String attribute = item.attribute1 ?? ""; //处理自定义字段 + str = str + attribute; + }); + BrnToast.show(str, context); + Navigator.of(context).pop(); + }, +); +``` + + + +自定义数据协议(继承基类:BrnMultiSelectBottomPickerItem) + +```dart +class ExpendMultiSelectBottomPickerItem extends BrnMultiSelectBottomPickerItem { + final String? attribute1; + final String? attribute2; + final String? attribute3; + String code; //选项编号 + String content; //选项内容 + bool isChecked; //是否选中 + + ExpendMultiSelectBottomPickerItem( + this.code, + this.content, { + this.attribute1, + this.attribute2, + this.attribute3, + this.isChecked = false, + }) : super(code, content, isChecked: isChecked); +} +``` diff --git a/doc/components/picker/BrnSelectTagsWithInputPicker/BrnSelectTagsWithInputPicker.md b/doc/components/picker/BrnSelectTagsWithInputPicker/BrnSelectTagsWithInputPicker.md index f8fac20e..fdfa715e 100644 --- a/doc/components/picker/BrnSelectTagsWithInputPicker/BrnSelectTagsWithInputPicker.md +++ b/doc/components/picker/BrnSelectTagsWithInputPicker/BrnSelectTagsWithInputPicker.md @@ -41,7 +41,7 @@ group: ```dart const BrnSelectTagsWithInputPicker( {this.maxLength = 200, - this.hintText = "请输入", + this.hintText, this.title = "", this.confirm, this.cancelCallBack, @@ -58,7 +58,7 @@ const BrnSelectTagsWithInputPicker( | 参数名 | 参数类型 | 描述 | 是否必填 | 默认值 | | --- | --- | --- | --- | --- | | title | String | Picker显示标题 | 否 | 空字符串 | -| hintText | String | 默认输入框提示文本 | 否 | 请输入 | +| hintText | String? | 默认输入框提示文本 | 否 | 默认值为国际化配置文本 '请输入' | | maxLength | int | 输入框最长文本字符数 | 否 | 200 | | confirm | BrnTagInputConfirmClickCallback? | 点击“确定”按钮事件回调 | 否 | - | | cancelCallBack | BrnTagInputCancelClickCallBack? | 关闭Picker事件回调 | 否 | - | diff --git a/lib/src/components/loading/brn_loading.dart b/lib/src/components/loading/brn_loading.dart index a8e03087..a9ae87ee 100644 --- a/lib/src/components/loading/brn_loading.dart +++ b/lib/src/components/loading/brn_loading.dart @@ -32,10 +32,10 @@ class BrnPageLoading extends StatelessWidget { final String? content; final BoxConstraints constraints; - const BrnPageLoading({ + const BrnPageLoading({Key? key, this.content, this.constraints = const BoxConstraints(minWidth: 130, maxWidth: 130, minHeight: 50, maxHeight: 50,), - }); + }): super(key: key); @override Widget build(BuildContext context) { From 1146d00e7e31539af34c884c84a1280762a06937 Mon Sep 17 00:00:00 2001 From: Sandy <15143015732@163.com> Date: Thu, 29 Dec 2022 12:06:48 +0800 Subject: [PATCH 14/15] add setting page (#388) * add setting page * update version to 3.2.0 * fix error desc --- CHANGELOG.md | 24 +++ README.en-US.md | 48 ++--- README.md | 48 ++--- example/assets/image/setting.png | Bin 0 -> 44450 bytes .../gallery/gallery_detail_example.dart | 38 ++-- example/lib/sample/home/home.dart | 32 ++-- example/lib/sample/home/setting.dart | 90 ++++++++++ .../components/popup/brn_popup_window.dart | 2 +- .../theme/adapter/brn_pad_theme_config.dart | 165 ++++++++++++++++++ lib/src/theme/brn_theme.dart | 1 + pubspec.yaml | 2 +- 11 files changed, 373 insertions(+), 77 deletions(-) create mode 100644 example/assets/image/setting.png create mode 100644 example/lib/sample/home/setting.dart create mode 100644 lib/src/theme/adapter/brn_pad_theme_config.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index e87bd413..0269189a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ + + +## [3.2.0] - 2022-12-29 + +### Changed + +#### base + +- support for localization capabilities. +- add pad theme configuration. +- expend title click area in pickers [#369](https://github.com/LianjiaTech/bruno/issues/369). + +#### components + +- BrnMultiSelectListPicker : add generics for more flexible data transfer [#336](https://github.com/LianjiaTech/bruno/issues/336) . +- BrnLinePainter : add the limit of yDialMax > yDialMin to fix the NaN error when calculating the path [359](https://github.com/LianjiaTech/bruno/issues/359). +- BrnTabBar : fix the overflow error when setting BrnTabBarBadgeMode.origin mode [#340](https://github.com/LianjiaTech/bruno/issues/340). +- BrnAppraise: fix gif file error [#372](https://github.com/LianjiaTech/bruno/issues/372). +- BrnTextInputFormItem: fix attribute textInputAction does not take effect and add attribute obscureText, thank to **echo-LuGuang**. +- BrnAppBar: expand BrnTextAction click area. +- BrnEnhanceNumberCard: fix the number card is not centered [#380](https://github.com/LianjiaTech/bruno/issues/380). + + + ## [3.1.0] - 2022-9-30 ### Changed diff --git a/README.en-US.md b/README.en-US.md index 850c31f6..0e086fd4 100644 --- a/README.en-US.md +++ b/README.en-US.md @@ -54,6 +54,7 @@ Please download from [Releases](https://github.com/LianjiaTech/bruno/releases) o | 2.2.0 | 2.10.5 | | 3.0.0 | 3.0.3 | | 3.1.0 | 3.3.0 | +| 3.2.0 | 3.3.0 | ## Preparing for use @@ -89,64 +90,71 @@ Please read our [Contributing](https://bruno.ke.com/page/guide/contribution) fir Thanks to all the developers who contributed to Bruno ! + diff --git a/README.md b/README.md index e78605da..43dbc0a3 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ | 2.2.0 | 2.10.5 | | 3.0.0 | 3.0.3 | | 3.1.0 | 3.3.0 | +| 3.2.0 | 3.3.0 | @@ -90,64 +91,71 @@ BrnBubbleText( 感谢所有为 Bruno 做出贡献的开发者! + ## 🔗 链接 diff --git a/example/assets/image/setting.png b/example/assets/image/setting.png new file mode 100644 index 0000000000000000000000000000000000000000..7c2b24a76b265063ecd0b6be6400ae715fe8ea92 GIT binary patch literal 44450 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%0AvN!T6jMZi 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
BXXhWE*|#nwc;D5= z9}9~IBojI)-G;*x{=uPRz|#2$byG~YufveMRw1@D_yZ9LRWsg|?9-VC4Na7Lg9ekT zJU>zD`7Ra|3cM<8;mbRDqcm^lgaF*bN?ia>dmG#e>}E0<24X3hLq~e2)-K*syz$OP z+dwBOcxU^t{n>Q7uYfE8QPEPq-^VLp_HS8Qb?c$IO8ssz6lRPF;)8sViFJ#!sYbHo z(%!ql-GPW`Y{$Ja;p@-EVE+O4QmG^h3vT%2UVH_no@=nS2OtyZnM`CdK>0w=@G;n~ zV1;3NjT7I-4cg`v`(*-%%%K60RNHd*i~h4T`a2ZC^dUSV=v**m-bj4XVjf9A>vjQU znCJD5T7SdUTaaP^T$WbQZjI=bNyxPxr<(VANVT|r)Q*=?y6-s%g7QI&41Abi7)iqs zkUSfZqj~z~1M`E~6p!&qnAgCw!g&Sxw9mm#(nQgFefXFCl4ja;mPXi>y*-*4&+yhp Rauo>$UwYccglfDK@ju0t4=(@! literal 0 HcmV?d00001 diff --git a/example/lib/sample/components/gallery/gallery_detail_example.dart b/example/lib/sample/components/gallery/gallery_detail_example.dart index 1406e68a..bec731fc 100644 --- a/example/lib/sample/components/gallery/gallery_detail_example.dart +++ b/example/lib/sample/components/gallery/gallery_detail_example.dart @@ -33,12 +33,12 @@ class GalleryDetailExamplePageState extends State { : BrnGalleryDetailConfig.light(), title: '第一项', urls: [ - "https://img1.baidu.com/it/u=2496571732,442429806&fm=26&fmt=auto&gp=0.jpg", - "http://img.pconline.com.cn/images/upload/upc/tx/wallpaper/1508/20/c0/11483087_1440080502911_800x600.jpg", - "https://img1.baidu.com/it/u=2496571732,442429806&fm=26&fmt=auto&gp=0.jpg", - "http://img.pconline.com.cn/images/upload/upc/tx/wallpaper/1508/20/c0/11483087_1440080502911_800x600.jpg", - "https://img1.baidu.com/it/u=2496571732,442429806&fm=26&fmt=auto&gp=0.jpg", - "http://img.pconline.com.cn/images/upload/upc/tx/wallpaper/1508/20/c0/11483087_1440080502911_800x600.jpg", + "https://img1.baidu.com/it/u=1035835481,2764635772&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750", + "https://img2.baidu.com/it/u=987135572,1298604833&fm=253&fmt=auto&app=138&f=JPEG?w=587&h=445", + "https://img1.baidu.com/it/u=2029510411,2926361415&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889", + "https://img2.baidu.com/it/u=3489452515,1789465937&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=333", + "https://img2.baidu.com/it/u=2011041083,1329194196&fm=253&fmt=auto&app=138&f=JPEG?w=333&h=500", + "https://img2.baidu.com/it/u=3412982025,1011812299&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", ]), BrnPhotoGroupConfig(title: "信息", configList: [ BrnPhotoItemConfig( @@ -46,7 +46,7 @@ class GalleryDetailExamplePageState extends State { ? BrnGalleryDetailConfig.dark() : BrnGalleryDetailConfig.light(), url: - "https://img1.baidu.com/it/u=2496571732,442429806&fm=26&fmt=auto&gp=0.jpg", + "https://img2.baidu.com/it/u=3489452515,1789465937&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=333", showBottom: true, bottomCardModel: PhotoBottomCardState.cantFold, name: "一只猫", @@ -57,7 +57,7 @@ class GalleryDetailExamplePageState extends State { ? BrnGalleryDetailConfig.dark() : BrnGalleryDetailConfig.light(), url: - "http://m.360buyimg.com/mobilecms/s1600x1120_jfs/t19540/272/1542853502/335716/5ef8759b/5acc6c5bN988cd3d9.jpg", + "https://img2.baidu.com/it/u=2011041083,1329194196&fm=253&fmt=auto&app=138&f=JPEG?w=333&h=500", showBottom: true, bottomCardModel: PhotoBottomCardState.fold, name: "两只猫", @@ -68,7 +68,7 @@ class GalleryDetailExamplePageState extends State { ? BrnGalleryDetailConfig.dark() : BrnGalleryDetailConfig.light(), url: - "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1604923055966&di=7d5ea9848f0b40b5317ad08d2fd6a2b3&imgtype=0&src=http%3A%2F%2Fa1.att.hudong.com%2F05%2F00%2F01300000194285122188000535877.jpg", + "https://img0.baidu.com/it/u=3926156041,1190073021&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889", showBottom: true, bottomCardModel: PhotoBottomCardState.unFold, name: "三只猫", @@ -79,7 +79,7 @@ class GalleryDetailExamplePageState extends State { ? BrnGalleryDetailConfig.dark() : BrnGalleryDetailConfig.light(), url: - "http://m.360buyimg.com/mobilecms/s1600x1120_jfs/t19540/272/1542853502/335716/5ef8759b/5acc6c5bN988cd3d9.jpg", + "https://img1.baidu.com/it/u=456300708,413059805&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", showBottom: false, name: "一张图片", des: @@ -91,8 +91,8 @@ class GalleryDetailExamplePageState extends State { ? BrnGalleryDetailConfig.dark() : BrnGalleryDetailConfig.light(), urls: [ - "https://img1.baidu.com/it/u=2496571732,442429806&fm=26&fmt=auto&gp=0.jpg", - "http://m.360buyimg.com/mobilecms/s1600x1120_jfs/t19540/272/1542853502/335716/5ef8759b/5acc6c5bN988cd3d9.jpg", + "https://img1.baidu.com/it/u=2029510411,2926361415&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889", + "https://img2.baidu.com/it/u=3412982025,1011812299&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", ]), BrnPhotoGroupConfig.url( themeData: PhotoGalleryTheme.dark == widget.photoGalleryTheme @@ -100,8 +100,8 @@ class GalleryDetailExamplePageState extends State { : BrnGalleryDetailConfig.light(), title: '第三项', urls: [ - "https://img1.baidu.com/it/u=2496571732,442429806&fm=26&fmt=auto&gp=0.jpg", - "http://m.360buyimg.com/mobilecms/s1600x1120_jfs/t19540/272/1542853502/335716/5ef8759b/5acc6c5bN988cd3d9.jpg", + "https://img2.baidu.com/it/u=987135572,1298604833&fm=253&fmt=auto&app=138&f=JPEG?w=587&h=445", + "https://img2.baidu.com/it/u=3412982025,1011812299&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", ]), BrnPhotoGroupConfig.url( themeData: PhotoGalleryTheme.dark == widget.photoGalleryTheme @@ -109,8 +109,8 @@ class GalleryDetailExamplePageState extends State { : BrnGalleryDetailConfig.light(), title: '第四项', urls: [ - "https://img1.baidu.com/it/u=2496571732,442429806&fm=26&fmt=auto&gp=0.jpg", - "http://m.360buyimg.com/mobilecms/s1600x1120_jfs/t19540/272/1542853502/335716/5ef8759b/5acc6c5bN988cd3d9.jpg", + "https://img2.baidu.com/it/u=3489452515,1789465937&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=333", + "https://img2.baidu.com/it/u=3412982025,1011812299&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", ]), BrnPhotoGroupConfig( themeData: PhotoGalleryTheme.dark == widget.photoGalleryTheme @@ -123,7 +123,7 @@ class GalleryDetailExamplePageState extends State { ? BrnGalleryDetailConfig.dark() : BrnGalleryDetailConfig.light(), url: - "http://tao.goulew.com/users/upfile/20180927/11eb065d-24d3-4a55-b9f8-e58085bdad2e.jpg", + "https://img2.baidu.com/it/u=3489452515,1789465937&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=333", showBottom: true, bottomCardModel: PhotoBottomCardState.fold, name: "一张图片", @@ -136,7 +136,7 @@ class GalleryDetailExamplePageState extends State { ? BrnGalleryDetailConfig.dark() : BrnGalleryDetailConfig.light(), url: - "https://c-ssl.duitang.com/uploads/item/201912/31/20191231121259_dckjf.thumb.1000_0.jpg", + "https://img2.baidu.com/it/u=987135572,1298604833&fm=253&fmt=auto&app=138&f=JPEG?w=587&h=445", showBottom: true, bottomCardModel: PhotoBottomCardState.fold, name: "一张图片", @@ -149,7 +149,7 @@ class GalleryDetailExamplePageState extends State { ? BrnGalleryDetailConfig.dark() : BrnGalleryDetailConfig.light(), url: - "https://c-ssl.duitang.com/uploads/item/201912/31/20191231121259_dckjf.thumb.1000_0.jpg", + "https://img2.baidu.com/it/u=3489452515,1789465937&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=333", showBottom: true, bottomCardModel: PhotoBottomCardState.fold, name: "一张图片", diff --git a/example/lib/sample/home/home.dart b/example/lib/sample/home/home.dart index f7db9336..d74281a0 100644 --- a/example/lib/sample/home/home.dart +++ b/example/lib/sample/home/home.dart @@ -6,6 +6,7 @@ import 'package:example/sample/home/group_card.dart'; import 'package:flutter/material.dart'; import '../l10n/l10n.dart'; +import 'setting.dart'; /// 主页面 class HomePage extends StatelessWidget { GlobalKey _moreKey = GlobalKey(); @@ -18,22 +19,21 @@ class HomePage extends StatelessWidget { leading: null, automaticallyImplyLeading: false, actions: [ - BrnTextAction( "切换组件词条语言",key: _moreKey, iconPressed: (){ - BrnPopupListWindow.showPopListWindow(context, _moreKey, - data: ['BrnResourceEn', 'ResourceDe'], - onItemClick: (int index, item) { - if(index == 0) { - BrnToast.showInCenter(text: "已切换为英语词条(BrnResourceEn)。\n注意:组件传入的默认值会影响词条展示", context: context); - ChangeLocalEvent.locale = Locale('en', 'US'); - ChangeLocalEvent()..dispatch(context); - } else { - BrnToast.showInCenter(text: "已切换为德语词条(ResourceDe 部分)。\n注意:组件传入的默认值会影响词条展示", context: context); - ChangeLocalEvent.locale = Locale('de', 'DE'); - ChangeLocalEvent()..dispatch(context); - } - return false; - }); - },) + BrnIconAction( + iconPressed: () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return Setting(); + }, + )); + }, + child: Image.asset( + 'assets/image/setting.png', + scale: 3.0, + height: 20, + width: 20, + ), + ), ], ), body: _buildBodyWidget(), diff --git a/example/lib/sample/home/setting.dart b/example/lib/sample/home/setting.dart new file mode 100644 index 00000000..df65ce1f --- /dev/null +++ b/example/lib/sample/home/setting.dart @@ -0,0 +1,90 @@ +import 'package:bruno/bruno.dart'; +import 'package:example/sample/home/list_item.dart'; +import 'package:flutter/material.dart'; + +import '../l10n/l10n.dart'; + +class Setting extends StatelessWidget { + GlobalKey _localKey = GlobalKey(); + GlobalKey _themeKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: BrnAppBar( + title: '设置', + leading: BrnBackLeading(), + automaticallyImplyLeading: false, + ), + body: Container( + padding: EdgeInsets.all(20), + child: ListView( + children: [ + ListItem( + key: _localKey, + title: "切换组件词条语言", + describe: "仅改变组件内部词条语言,Demo示例部分不支持", + isShowLine: false, + onPressed: () { + BrnPopupListWindow.showPopListWindow(context, _localKey, + data: ['中文', '英文', '德语'], onItemClick: (int index, item) { + switch (index) { + case 0: + BrnToast.showInCenter( + text: "已切换为英语词条(BrnResourceZh)。\n注意:组件传入的默认值会影响词条展示", + context: context); + ChangeLocalEvent.locale = Locale('zh', 'CN'); + ChangeLocalEvent()..dispatch(context); + break; + case 1: + BrnToast.showInCenter( + text: "已切换为英语词条(BrnResourceEn)。\n注意:组件传入的默认值会影响词条展示", + context: context); + ChangeLocalEvent.locale = Locale('en', 'US'); + ChangeLocalEvent()..dispatch(context); + break; + case 2: + BrnToast.showInCenter( + text: "已切换为德语词条(ResourceDe 部分)。\n注意:组件传入的默认值会影响词条展示", + context: context); + ChangeLocalEvent.locale = Locale('de', 'DE'); + ChangeLocalEvent()..dispatch(context); + break; + } + return false; + }, arrowOffset: 100); + }, + ), + ListItem( + key: _themeKey, + title: "主题定制切换", + describe: "当切换为 Pad 主题样式请选用 Pad 设备查看", + onPressed: () { + BrnPopupListWindow.showPopListWindow( + context, + _themeKey, + data: ['App 主题样式', 'Pad 主题样式'], + onItemClick: (int index, item) { + if (index == 0) { + BrnInitializer.register( + allThemeConfig: + BrnDefaultConfigUtils.defaultAllConfig); + BrnToast.showInCenter( + text: "已切换为 App 主题样式", context: context); + } else { + BrnInitializer.register( + allThemeConfig: BrnPadThemeConfig.allConfig); + BrnToast.showInCenter( + text: "已切换为 Pad 主题样式", context: context); + } + return false; + }, + ); + }, + ), + ], + ), + ), + ); + } +} diff --git a/lib/src/components/popup/brn_popup_window.dart b/lib/src/components/popup/brn_popup_window.dart index 4d39d410..18f71cb8 100644 --- a/lib/src/components/popup/brn_popup_window.dart +++ b/lib/src/components/popup/brn_popup_window.dart @@ -556,6 +556,7 @@ class BrnPopupListWindow { {List? data, BrnPopupDirection popDirection = BrnPopupDirection.bottom, double offset = 0, + double? arrowOffset, BrnPopupListItemClick? onItemClick, VoidCallback? onDismiss}) { assert(popKey.currentContext != null && popKey.currentContext!.findRenderObject() != null); @@ -567,7 +568,6 @@ class BrnPopupListWindow { double minWidth = 100; double maxWidth = 150; double maxHeight = 200; - double? arrowOffset; Color borderColor = BrnThemeConfigurator.instance.getConfig().commonConfig.dividerColorBase; Color backgroundColor = Colors.white; TextStyle textStyle = TextStyle( diff --git a/lib/src/theme/adapter/brn_pad_theme_config.dart b/lib/src/theme/adapter/brn_pad_theme_config.dart new file mode 100644 index 00000000..6eb1227e --- /dev/null +++ b/lib/src/theme/adapter/brn_pad_theme_config.dart @@ -0,0 +1,165 @@ +import 'package:bruno/src/theme/base/brn_text_style.dart'; +import 'package:flutter/material.dart'; + +import '../configs/brn_all_config.dart'; +import '../configs/brn_appbar_config.dart'; +import '../configs/brn_button_config.dart'; +import '../configs/brn_common_config.dart'; +import '../configs/brn_dialog_config.dart'; +import '../configs/brn_enhance_number_card_config.dart'; +import '../configs/brn_form_config.dart'; +import '../configs/brn_pair_info_config.dart'; +import '../configs/brn_tag_config.dart'; + +/// Pad 主题配置 +class BrnPadThemeConfig { + /// 默认全局配置 + static BrnAllThemeConfig allConfig = BrnAllThemeConfig( + commonConfig: CommonConfig, + formItemConfig: formItemConfig, + dialogConfig: dialogConfig, + appBarConfig: appbarConfig, + pairInfoTableConfig: metaPairInfoTableConfig, + pairRichInfoGridConfig: metaPairRichInfoGridConfig, + buttonConfig: buttonConfig, + enhanceNumberCardConfig: numberInfoConfig, + tagConfig: tagConfig); + + /// 全局默认配置 + static BrnCommonConfig CommonConfig = BrnCommonConfig( + /// 主题色相关 + brandPrimary: const Color(0xFF3072F6), + brandPrimaryTap: const Color(0x193072F6), + brandSuccess: const Color(0xFF3072F6), + brandWarning: const Color(0xFFFA5741), + brandError: const Color(0xFFFA5741), + brandImportant: const Color(0xFFFA5741), + brandImportantValue: const Color(0xFFFA5741), + + colorTextBase: const Color(0xFF222222), + + colorTextImportant: const Color(0xFF222222), + + colorTextBaseInverse: const Color(0xFFFFFFFF), + + colorTextSecondary: const Color(0xFF999999), + + colorTextDisabled: const Color(0xFFCCCCCC), + + colorTextHint: const Color(0xFFCCCCCC), + + colorLink: const Color(0xFF0055FF), + + dividerColorBase: const Color(0xFFCCCCCC), + + fillBase: const Color(0xFFFFFFFF), + fillBody: const Color(0xFFF8F8F8), + fillMask: const Color(0x99000000), + fontSizeBebas: 18, + fontSizeHeadLg: 28, + fontSizeHead: 22, + fontSizeSubHead: 18, + fontSizeBase: 16, + fontSizeCaption: 14, + fontSizeCaptionSm: 14, + + radiusXs: 2.0, + radiusSm: 4.0, + radiusMd: 5.0, + radiusLg: 12.0, + borderWidthSm: 0.5, + borderWidthMd: 1, + borderWidthLg: 2, + + hSpacingXs: 8, + hSpacingSm: 12, + hSpacingMd: 16, + hSpacingLg: 20, + hSpacingXl: 24, + hSpacingXxl: 42, + + vSpacingXs: 4, + vSpacingSm: 8, + vSpacingMd: 12, + vSpacingLg: 14, + vSpacingXl: 16, + vSpacingXxl: 28, + + iconSizeXxs: 8, + iconSizeXs: 12, + iconSizeSm: 14, + iconSizeMd: 16, + iconSizeLg: 32, + ); + + ///******** 以下是子配置项 ********/// + + /// tagView 默认配置 + static BrnTagConfig tagConfig = BrnTagConfig( + tagRadius: 6, + tagMinWidth: 110, + tagTextStyle: BrnTextStyle(fontSize: 12, fontWeight: FontWeight.w600)); + + /// 数字信息展示默认配置 + static BrnEnhanceNumberCardConfig numberInfoConfig = + BrnEnhanceNumberCardConfig( + itemRunningSpace: 0, + titleTextStyle: BrnTextStyle(fontSize: 32), + descTextStyle: BrnTextStyle(fontSize: 16), + ); + + /// 表单项默认配置 + static BrnFormItemConfig formItemConfig = BrnFormItemConfig( + subTitleTextStyle: BrnTextStyle(fontSize: 14), + optionsMiddlePadding: EdgeInsets.only(left: 20), + errorTextStyle: BrnTextStyle(fontSize: 14)); + + /// Dialog默认配置 + static BrnDialogConfig dialogConfig = BrnDialogConfig( + dialogWidth: 420, + radius: 12.0, + titleTextStyle: BrnTextStyle(fontSize: 22), + titlePaddingSm: EdgeInsets.only(top: 14, left: 32, right: 32), + titlePaddingLg: EdgeInsets.only(top: 28, left: 32, right: 32), + contentTextStyle: BrnTextStyle(fontSize: 16), + contentPaddingSm: EdgeInsets.only(top: 14, left: 32, right: 32), + contentPaddingLg: EdgeInsets.only(top: 28, left: 32, right: 32), + ); + + static BrnAppBarConfig appbarConfig = BrnAppBarConfig( + appBarHeight: 57, + leftAndRightPadding: 24, + itemSpacing: 24, + titleMaxLength: 20, + titleStyle: BrnTextStyle( + color: Color(0xff222222), fontWeight: FontWeight.w600, fontSize: 24), + actionsStyle: BrnTextStyle( + color: Color(0xFF3072F6), fontWeight: FontWeight.w600, fontSize: 18), + ); + + static BrnButtonConfig buttonConfig = BrnButtonConfig( + bigButtonRadius: 12, + bigButtonHeight: 50, + bigButtonFontSize: 18, + smallButtonRadius: 12, + smallButtonFontSize: 14, + smallButtonHeight: 36); + + static BrnPairInfoTableConfig metaPairInfoTableConfig = + BrnPairInfoTableConfig( + rowSpacing: 6, + itemSpacing: 8, + valueTextStyle: + BrnTextStyle(fontSize: 16, fontWeight: FontWeight.w600), + keyTextStyle: BrnTextStyle(fontSize: 16), + linkTextStyle: BrnTextStyle(fontSize: 16)); + + static BrnPairRichInfoGridConfig metaPairRichInfoGridConfig = + BrnPairRichInfoGridConfig( + rowSpacing: 6, + itemSpacing: 4, + valueTextStyle: + BrnTextStyle(fontSize: 16, fontWeight: FontWeight.w500), + keyTextStyle: BrnTextStyle(fontSize: 16, fontWeight: FontWeight.w500), + linkTextStyle: BrnTextStyle(fontSize: 16)); +} diff --git a/lib/src/theme/brn_theme.dart b/lib/src/theme/brn_theme.dart index 6300080e..9e2fb670 100644 --- a/lib/src/theme/brn_theme.dart +++ b/lib/src/theme/brn_theme.dart @@ -25,3 +25,4 @@ export 'configs/brn_tabbar_config.dart'; export 'configs/brn_tag_config.dart'; export 'brn_initializer.dart'; export 'brn_theme_configurator.dart'; +export 'adapter/brn_pad_theme_config.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index d4f7d474..5d2268ab 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: bruno description: An enterprise-class package of Flutter components for mobile applications. -version: 3.1.0 +version: 3.2.0 homepage: https://github.com/LianjiaTech/bruno environment: From b8f90d9264e27a325e4ed895d43934e4835ec7a4 Mon Sep 17 00:00:00 2001 From: violinday Date: Thu, 29 Dec 2022 15:35:25 +0800 Subject: [PATCH 15/15] cherry-pick: e868c577fa98898f3e732b397266d5b79e9cc28e [e868c57] --- .../ratingBar/BrnRatingStar/BrnRatingStar.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/components/ratingBar/BrnRatingStar/BrnRatingStar.md b/doc/components/ratingBar/BrnRatingStar/BrnRatingStar.md index 6251c6e4..bda15d02 100644 --- a/doc/components/ratingBar/BrnRatingStar/BrnRatingStar.md +++ b/doc/components/ratingBar/BrnRatingStar/BrnRatingStar.md @@ -17,7 +17,7 @@ group: ### 适用场景 -星级评分条RatingBar支持自定义图片,颜色,大小,间距,支持点击选中,支持第一个反选,支持半颗星(只用于展示,不支持选择半颗星)。 +星级评分条BrnRatingStar支持自定义图片,颜色,大小,间距,支持点击选中,支持第一个反选,支持半颗星(只用于展示,不支持选择半颗星)。 ## 三、构造函数及参数说明 @@ -54,7 +54,7 @@ const BrnRatingStar({ ```dart -BrnRatingBar(), +BrnRatingStar(), ``` ### 效果2 @@ -63,13 +63,13 @@ BrnRatingBar(), ```dart -BrnRatingBar( +BrnRatingStar( selectedCount: 0.5, ) -BrnRatingBar( +BrnRatingStar( selectedCount: 3.1, ), -BrnRatingBar( +BrnRatingStar( selectedCount: 3.6, count: 10, ),