diff --git a/lib/src/components/noticebar/brn_marquee_text.dart b/lib/src/components/noticebar/brn_marquee_text.dart index b5e9ee02..4b6b3435 100644 --- a/lib/src/components/noticebar/brn_marquee_text.dart +++ b/lib/src/components/noticebar/brn_marquee_text.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'dart:async'; import 'package:flutter/material.dart'; @@ -10,7 +8,7 @@ class BrnMarqueeText extends StatefulWidget { final String text; /// 文字样式 - final TextStyle textStyle; + final TextStyle? textStyle; ///滚动方向,水平或者垂直 final Axis scrollAxis; @@ -27,16 +25,14 @@ class BrnMarqueeText extends StatefulWidget { double height; BrnMarqueeText({ - @required this.text, + required this.text, this.width: 0, this.height: 0, this.timerRest: 100, this.textStyle, this.scrollAxis: Axis.horizontal, this.ratioOfBlankToScreen: 0.25, - }) : assert( - text != null, - ); + }); @override State createState() { @@ -46,26 +42,26 @@ class BrnMarqueeText extends StatefulWidget { class BrnMarqueeTextState extends State with SingleTickerProviderStateMixin { - ScrollController scroController; + late ScrollController scroController; double blankWidth = 1; double blankHeight = 1; double position = 0.0; - Timer timer; + Timer? timer; final double _moveDistance = 3.0; - GlobalKey _key = null; + GlobalKey? _key; @override void initState() { super.initState(); scroController = new ScrollController(); - WidgetsBinding.instance.addPostFrameCallback((callback) { - var size = context?.findRenderObject()?.paintBounds?.size; + WidgetsBinding.instance?.addPostFrameCallback((callback) { + var size = context.findRenderObject()!.paintBounds.size; widget.width = (widget.width) > 0 ? widget.width : size.width; widget.height = (widget.height) > 0 ? widget.height : size.height; _key = GlobalKey(); - if (calculateTextWith(widget.text, widget.textStyle.fontSize, - widget.textStyle.fontWeight, double.infinity, 1, context) > + if (calculateTextWith(widget.text, widget.textStyle?.fontSize, + widget.textStyle?.fontWeight, double.infinity, 1, context) > widget.width) { blankWidth = widget.width * widget.ratioOfBlankToScreen; blankHeight = widget.height * widget.ratioOfBlankToScreen; @@ -138,10 +134,8 @@ class BrnMarqueeTextState extends State @override void dispose() { - if (timer != null) { - timer.cancel(); - } - scroController = null; + timer?.cancel(); + scroController.dispose(); super.dispose(); } @@ -164,8 +158,13 @@ class BrnMarqueeTextState extends State ); } - double calculateTextWith(String value, double fontSize, FontWeight fontWeight, - double maxWidth, int maxLines, BuildContext context) { + double calculateTextWith( + String value, + double? fontSize, + FontWeight? fontWeight, + double maxWidth, + int maxLines, + BuildContext context) { TextPainter painter = TextPainter( ///AUTO:华为手机如果不指定locale的时候,该方法算出来的文字高度是比系统计算偏小的。 diff --git a/lib/src/components/noticebar/brn_notice_bar.dart b/lib/src/components/noticebar/brn_notice_bar.dart index 1ba2dc20..637a20d6 100644 --- a/lib/src/components/noticebar/brn_notice_bar.dart +++ b/lib/src/components/noticebar/brn_notice_bar.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'package:bruno/src/components/noticebar/brn_marquee_text.dart'; import 'package:bruno/src/constants/brn_asset_constants.dart'; import 'package:bruno/src/utils/brn_tools.dart'; @@ -12,7 +10,7 @@ import 'package:flutter/material.dart'; class BrnNoticeBar extends StatelessWidget { /// 自定义左边的图标 - final Widget leftWidget; + final Widget? leftWidget; /// 是否显示左边的图标 final bool showLeftIcon; @@ -21,30 +19,30 @@ class BrnNoticeBar extends StatelessWidget { final String content; /// 通知的文字颜色 - final Color textColor; + final Color? textColor; /// 背景颜色 - final Color backgroundColor; + final Color? backgroundColor; /// 右边的图标 - final Widget rightWidget; + final Widget? rightWidget; /// 是否显示右边的图标 /// 默认值true final bool showRightIcon; /// 默认样式,取[NoticeStyles]里面的值 - final NoticeStyle noticeStyle; + final NoticeStyle? noticeStyle; /// 是否跑马灯 /// 默认值false final bool marquee; /// 通知钮点击的回调 - final VoidCallback onNoticeTap; + final VoidCallback? onNoticeTap; /// 右侧图标点击的回调 - final VoidCallback onRightIconTap; + final VoidCallback? onRightIconTap; /// 最小高度。leftWidget、rightWidget 都为空时,限制的最小高度。 /// 可以通过该属性控制组件高度,内容会自动垂直居中。 @@ -52,13 +50,13 @@ class BrnNoticeBar extends StatelessWidget { final double minHeight; /// 内容的内边距 - final EdgeInsets padding; + final EdgeInsets? padding; const BrnNoticeBar( - {Key key, + {Key? key, this.leftWidget, this.showLeftIcon = true, - @required this.content, + required this.content, this.textColor, this.backgroundColor, this.rightWidget, @@ -69,8 +67,7 @@ class BrnNoticeBar extends StatelessWidget { this.marquee = false, this.padding, this.minHeight = 36}) - : assert(content != null), - super(key: key); + : super(key: key); @override Widget build(BuildContext context) { @@ -82,7 +79,7 @@ class BrnNoticeBar extends StatelessWidget { tempRightWidget = GestureDetector( child: tempRightWidget, onTap: () { - onRightIconTap(); + onRightIconTap!(); }, ); } @@ -91,7 +88,7 @@ class BrnNoticeBar extends StatelessWidget { if (marquee) { contentWidget = BrnMarqueeText( height: 36, - text: content ?? '', + text: content, textStyle: TextStyle( color: textColor ?? (noticeStyle?.textColor ?? defaultStyle.textColor), @@ -100,7 +97,7 @@ class BrnNoticeBar extends StatelessWidget { ); } else { contentWidget = Text( - content ?? '', + content, overflow: TextOverflow.ellipsis, style: TextStyle( color: @@ -113,14 +110,14 @@ class BrnNoticeBar extends StatelessWidget { return Container( color: backgroundColor ?? (noticeStyle != null - ? noticeStyle.backgroundColor + ? noticeStyle!.backgroundColor : defaultStyle.backgroundColor), padding: this.padding ?? EdgeInsets.symmetric(horizontal: 20), constraints: BoxConstraints(minHeight: this.minHeight), child: GestureDetector( onTap: () { if (onNoticeTap != null) { - onNoticeTap(); + onNoticeTap!(); } }, child: Row( diff --git a/lib/src/components/noticebar/brn_notice_bar_with_button.dart b/lib/src/components/noticebar/brn_notice_bar_with_button.dart index 3f23a418..7e1e59fd 100644 --- a/lib/src/components/noticebar/brn_notice_bar_with_button.dart +++ b/lib/src/components/noticebar/brn_notice_bar_with_button.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'package:bruno/src/components/noticebar/brn_marquee_text.dart'; import 'package:flutter/material.dart'; @@ -13,52 +11,52 @@ class BrnNoticeBarWithButton extends StatelessWidget { final String content; /// 通知的背景色 - final Color backgroundColor; + final Color? backgroundColor; /// 通知的文字颜色 - final Color contentTextColor; + final Color? contentTextColor; /// 左边标签的文字 - final String leftTagText; + final String? leftTagText; /// 左边标签的文字颜色 - final Color leftTagTextColor; + final Color? leftTagTextColor; /// 左边标签的背景颜色 - final Color leftTagBackgroundColor; + final Color? leftTagBackgroundColor; /// 自定义左边的控件 - final Widget leftWidget; + final Widget? leftWidget; ///右边按钮的文字 - final String rightButtonText; + final String? rightButtonText; ///右边按钮的文字颜色 - final Color rightButtonTextColor; + final Color? rightButtonTextColor; ///右边按钮的边框颜色 - final Color rightButtonBorderColor; + final Color? rightButtonBorderColor; /// 自定义右边的控件 - final Widget rightWidget; + final Widget? rightWidget; /// 是否跑马灯 /// 默认值false final bool marquee; /// 右边按钮点击回调 - final VoidCallback onRightButtonTap; + final VoidCallback? onRightButtonTap; /// 最小高度。leftWidget、rightWidget 都为空时,限制的最小高度。 /// 可以通过该属性控制组件高度,内容会自动垂直居中。默认值 54。 final double minHeight; /// 内容的内边距 - final EdgeInsets padding; + final EdgeInsets? padding; const BrnNoticeBarWithButton( - {Key key, - @required this.content, + {Key? key, + required this.content, this.backgroundColor, this.contentTextColor, this.leftTagText, @@ -73,8 +71,7 @@ class BrnNoticeBarWithButton extends StatelessWidget { this.rightWidget, this.padding, this.minHeight = 54}) - : assert(content != null), - super(key: key); + : super(key: key); @override Widget build(BuildContext context) { @@ -99,7 +96,7 @@ class BrnNoticeBarWithButton extends StatelessWidget { /// 左边的标签 Widget _buildLeftTag() { if (leftWidget != null) { - return leftWidget; + return leftWidget!; } if (leftTagText?.isEmpty ?? true) { @@ -115,7 +112,7 @@ class BrnNoticeBarWithButton extends StatelessWidget { borderRadius: BorderRadius.circular(2), ), child: Text( - leftTagText, + leftTagText!, style: TextStyle( color: leftTagTextColor ?? Colors.white, fontSize: 11, @@ -127,14 +124,14 @@ class BrnNoticeBarWithButton extends StatelessWidget { } Widget _buildContent() { - if (content?.isEmpty ?? true) { + if (content.isEmpty) { return Container(); } if (marquee) { return BrnMarqueeText( height: 20, - text: content ?? '', + text: content, textStyle: TextStyle( color: contentTextColor ?? Color(0xFF333333), fontSize: 14, @@ -142,7 +139,7 @@ class BrnNoticeBarWithButton extends StatelessWidget { ); } else { return Text( - content ?? '', + content, overflow: TextOverflow.ellipsis, style: TextStyle( color: contentTextColor ?? Color(0xFF333333), @@ -155,7 +152,7 @@ class BrnNoticeBarWithButton extends StatelessWidget { /// 右边的按钮 Widget _buildRightBtn() { if (rightWidget != null) { - return rightWidget; + return rightWidget!; } if (rightButtonText?.isEmpty ?? true) { @@ -164,7 +161,7 @@ class BrnNoticeBarWithButton extends StatelessWidget { return GestureDetector( onTap: () { if (onRightButtonTap != null) { - onRightButtonTap(); + onRightButtonTap!(); } }, child: Padding( @@ -183,7 +180,7 @@ class BrnNoticeBarWithButton extends StatelessWidget { borderRadius: BorderRadius.circular(4), ), child: Text( - rightButtonText, + rightButtonText!, style: TextStyle( color: rightButtonTextColor ?? Color(0xFFFA5741), fontSize: 12, diff --git a/lib/src/components/selectcity/brn_az_common.dart b/lib/src/components/selectcity/brn_az_common.dart index 9b82fb2b..82db6329 100644 --- a/lib/src/components/selectcity/brn_az_common.dart +++ b/lib/src/components/selectcity/brn_az_common.dart @@ -1,19 +1,17 @@ -// @dart=2.9 - import 'package:flutter/material.dart'; /// ISuspension Bean. abstract class ISuspensionBean { - bool isShowSuspension; - String name; - String tag; //Suspension Tag + bool isShowSuspension = false; + String name = ""; + String tag = ""; //Suspension Tag } /// AzListView Header. class AzListViewHeader { AzListViewHeader({ - @required this.height, - @required this.builder, + required this.height, + required this.builder, this.tag = "↑", }); @@ -26,7 +24,7 @@ class AzListViewHeader { class SuspensionUtil { /// sort list by suspension tag. /// 根据[A-Z]排序。 - static void sortListBySuspensionTag(List list) { + static void sortListBySuspensionTag(List? list) { if (list == null || list.isEmpty) return; list.sort((a, b) { if (a.tag == "@" || b.tag == "#") { @@ -41,10 +39,10 @@ class SuspensionUtil { /// get index data list by suspension tag. /// 获取索引列表。 - static List getTagIndexList(List list) { - List indexData = List(); + static List getTagIndexList(List? list) { + List indexData = []; if (list != null && list.isNotEmpty) { - String tempTag; + String? tempTag; for (int i = 0, length = list.length; i < length; i++) { String tag = list[i].tag; if (tag.length > 2) tag = tag.substring(0, 2); @@ -58,11 +56,11 @@ class SuspensionUtil { } /// set show suspension status. - static void setShowSuspensionStatus(List list) { + static void setShowSuspensionStatus(List? list) { if (list == null || list.isEmpty) return; - String tempTag; + String? tempTag; for (int i = 0, length = list.length; i < length; i++) { - String tag = list[i].tag; + String? tag = list[i].tag; if (tempTag != tag) { tempTag = tag; list[i].isShowSuspension = true; diff --git a/lib/src/components/selectcity/brn_az_listview.dart b/lib/src/components/selectcity/brn_az_listview.dart index 2f976e4c..5243f172 100644 --- a/lib/src/components/selectcity/brn_az_listview.dart +++ b/lib/src/components/selectcity/brn_az_listview.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'package:bruno/src/components/selectcity/brn_az_common.dart'; import 'package:bruno/src/components/selectcity/brn_index_bar.dart'; import 'package:bruno/src/components/selectcity/brn_suspension_view.dart'; @@ -20,7 +18,7 @@ typedef Widget IndexHintBuilder(BuildContext context, String hint); /// _Header. class _Header extends ISuspensionBean { - String tag; + String tag = ""; String getSuspensionTag() => tag; @@ -31,15 +29,15 @@ class _Header extends ISuspensionBean { /// AzListView. class AzListView extends StatefulWidget { AzListView( - {Key key, + {Key? key, this.data, this.topData, - this.itemBuilder, + required this.itemBuilder, this.controller, this.physics, this.shrinkWrap = true, this.padding = EdgeInsets.zero, - this.suspensionWidget, + required this.suspensionWidget, this.isUseRealIndex = true, this.itemHeight = 50, this.suspensionHeight = 40, @@ -48,20 +46,19 @@ class AzListView extends StatefulWidget { this.indexBarBuilder, this.indexHintBuilder, this.showIndexHint = true}) - : assert(itemBuilder != null), - super(key: key); + : super(key: key); ///with ISuspensionBean Data - final List data; + final List? data; ///with ISuspensionBean topData, Do not participate in [A-Z] sorting (such as hotList). - final List topData; + final List? topData; final ItemWidgetBuilder itemBuilder; - final ScrollController controller; + final ScrollController? controller; - final ScrollPhysics physics; + final ScrollPhysics? physics; final bool shrinkWrap; @@ -80,13 +77,13 @@ class AzListView extends StatefulWidget { final int suspensionHeight; ///on sus tag change callback. - final ValueChanged onSusTagChanged; + final ValueChanged? onSusTagChanged; - final AzListViewHeader header; + final AzListViewHeader? header; - final IndexBarBuilder indexBarBuilder; + final IndexBarBuilder? indexBarBuilder; - final IndexHintBuilder indexHintBuilder; + final IndexHintBuilder? indexHintBuilder; final bool showIndexHint; @@ -100,12 +97,12 @@ class _AzListViewState extends State { //右侧索引tag 与 距离offset的value,比如 a---0, b---item*个数,c---a+b Map _suspensionSectionMap = Map(); - List _cityList = List(); - List _indexTagList = List(); + List _cityList = []; + List _indexTagList = []; bool _isShowIndexBarHint = false; String _indexBarHint = ""; - ScrollController _scrollController; + late ScrollController _scrollController; @override void initState() { @@ -115,7 +112,7 @@ class _AzListViewState extends State { @override void dispose() { - _scrollController?.dispose(); + _scrollController.dispose(); super.dispose(); } @@ -123,7 +120,7 @@ class _AzListViewState extends State { setState(() { _indexBarHint = model.tag; _isShowIndexBarHint = model.isTouchDown; - int offset = _suspensionSectionMap[model.tag]; + int? offset = _suspensionSectionMap[model.tag]; if (offset != null) { _scrollController.jumpTo(offset .toDouble() @@ -134,10 +131,10 @@ class _AzListViewState extends State { void _init() { _cityList.clear(); - if (widget.topData != null && widget.topData.isNotEmpty) { - _cityList.addAll(widget.topData); + if (widget.topData != null && widget.topData!.isNotEmpty) { + _cityList.addAll(widget.topData!); } - List list = widget.data; + List? list = widget.data; if (list != null && list.isNotEmpty) { // SuspensionUtil.sortListBySuspensionTag(list); _cityList.addAll(list); @@ -146,7 +143,7 @@ class _AzListViewState extends State { SuspensionUtil.setShowSuspensionStatus(_cityList); if (widget.header != null) { - _cityList.insert(0, _Header()..tag = widget.header.tag); + _cityList.insert(0, _Header()..tag = widget.header!.tag); } _indexTagList.clear(); if (widget.isUseRealIndex) { @@ -171,8 +168,8 @@ class _AzListViewState extends State { itemBuilder: (BuildContext context, int index) { if (index == 0 && _cityList[index] is _Header) { return SizedBox( - height: widget.header.height.toDouble(), - child: widget.header.builder(context)); + height: widget.header!.height.toDouble(), + child: widget.header!.builder(context)); } return widget.itemBuilder(context, _cityList[index]); }), @@ -195,7 +192,7 @@ class _AzListViewState extends State { onTouch: _onIndexBarTouch, ); } else { - indexBar = widget.indexBarBuilder( + indexBar = widget.indexBarBuilder!( context, _indexTagList, _onIndexBarTouch, @@ -207,7 +204,7 @@ class _AzListViewState extends State { )); Widget indexHint; if (widget.indexHintBuilder != null) { - indexHint = widget.indexHintBuilder(context, '$_indexBarHint'); + indexHint = widget.indexHintBuilder!(context, '$_indexBarHint'); } else { indexHint = Card( color: Colors.black54, diff --git a/lib/src/components/selectcity/brn_base_azlistview_page.dart b/lib/src/components/selectcity/brn_base_azlistview_page.dart index a73c1027..03d23313 100644 --- a/lib/src/components/selectcity/brn_base_azlistview_page.dart +++ b/lib/src/components/selectcity/brn_base_azlistview_page.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'dart:async'; import 'package:bruno/src/components/empty/brn_empty_status.dart'; @@ -27,10 +25,10 @@ abstract class BaseAZListViewPage extends StatefulWidget { Widget buildItemWidget(ISuspensionBean item); //悬浮的widget - Widget buildSuspensionWidget(String tag); + Widget buildSuspensionWidget(String? tag); List getTopData() { - return List(); + return []; } //item的高度 默认50 @@ -41,16 +39,19 @@ abstract class BaseAZListViewPage extends StatefulWidget { //每个modal 对应的 tag,默认是拼音来设置 String createTagByModal(ISuspensionBean bean) { - String pinyin = PinyinHelper.getPinyinE(bean.name); - return pinyin.substring(0, 1).toUpperCase(); + if (bean.name.isNotEmpty) { + String pinyin = PinyinHelper.getPinyinE(bean.name); + return pinyin.substring(0, 1).toUpperCase(); + } + return ""; } } class _BaseAZListViewPageState extends State { - String suspensionTag = ""; + String? suspensionTag = ""; - List _dataList = List(); - StreamController streamController; + List _dataList = []; + late StreamController streamController; @override void initState() { @@ -72,14 +73,15 @@ class _BaseAZListViewPageState extends State { if (snapShot.connectionState == ConnectionState.done) { if (snapShot.hasError) { return BrnAbnormalStateUtils.getEmptyWidgetByState( - context, AbnormalState.networkConnectError,action: (index) { + context, AbnormalState.networkConnectError, + action: (index) { setState(() {}); }); } else { return buildContentBody(snapShot.data); } } - return null; + return Container(); }, )); } @@ -98,7 +100,7 @@ class _BaseAZListViewPageState extends State { if (_dataList.isEmpty && top.isEmpty) { return BrnAbnormalStateUtils.getEmptyWidgetByState( - context, AbnormalState.noData,); + context, AbnormalState.noData); } suspensionTag = top.isEmpty ? _dataList[0].tag : top[0].tag; @@ -109,7 +111,7 @@ class _BaseAZListViewPageState extends State { child: StreamBuilder( initialData: suspensionTag, stream: streamController.stream, - builder: (context, snapShot) { + builder: (context, AsyncSnapshot snapShot) { return AzListView( data: _dataList, topData: top, @@ -128,14 +130,14 @@ class _BaseAZListViewPageState extends State { ); } - Widget _buildSusWidget(String susTag) { + Widget _buildSusWidget(String? susTag) { return Container( height: widget.getSuspensionHeight(), child: widget.buildSuspensionWidget(susTag), ); } - void _handleList(List list) { + void _handleList(List? list) { if (list == null || list.isEmpty) return; for (int i = 0, length = list.length; i < length; i++) { String tag = widget.createTagByModal(list[i]); @@ -154,7 +156,7 @@ class _BaseAZListViewPageState extends State { } Widget _buildListItem(ISuspensionBean model) { - String susTag = model.tag; + String? susTag = model.tag; return Column( children: [ //当offstage为true,当前控件不会被绘制在屏幕上 diff --git a/lib/src/components/selectcity/brn_index_bar.dart b/lib/src/components/selectcity/brn_index_bar.dart index e2703925..3db2109e 100644 --- a/lib/src/components/selectcity/brn_index_bar.dart +++ b/lib/src/components/selectcity/brn_index_bar.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'package:flutter/material.dart'; /// IndexBar touch callback IndexModel. @@ -7,11 +5,9 @@ typedef void IndexBarTouchCallback(IndexBarDetails model); /// IndexModel. class IndexBarDetails { - String tag; //current touch tag. - int position; //current touch position. - bool isTouchDown; //is touch down. - - IndexBarDetails({this.tag, this.position, this.isTouchDown}); + String tag = ""; //current touch tag. + int position = -1; //current touch position. + bool isTouchDown = false; //is touch down. } ///Default Index data. @@ -48,9 +44,9 @@ const List INDEX_DATA_DEF = const [ /// IndexBar. class IndexBar extends StatefulWidget { IndexBar( - {Key key, + {Key? key, this.data = INDEX_DATA_DEF, - @required this.onTouch, + required this.onTouch, this.width = 30, this.itemHeight = 16, this.color = Colors.transparent, @@ -104,14 +100,12 @@ class _SuspensionListViewIndexBarState extends State { textStyle: widget.textStyle, touchDownTextStyle: widget.touchDownTextStyle, onTouch: (details) { - if (widget.onTouch != null) { - if (_isTouchDown != details.isTouchDown) { - setState(() { - _isTouchDown = details.isTouchDown; - }); - } - widget.onTouch(details); + if (_isTouchDown != details.isTouchDown) { + setState(() { + _isTouchDown = details.isTouchDown; + }); } + widget.onTouch(details); }, ), ); @@ -130,30 +124,29 @@ class _IndexBar extends StatefulWidget { final int itemHeight; /// IndexBar text style. - final TextStyle textStyle; + final TextStyle? textStyle; - final TextStyle touchDownTextStyle; + final TextStyle? touchDownTextStyle; /// Item touch callback. final IndexBarTouchCallback onTouch; _IndexBar( - {Key key, + {Key? key, this.data = INDEX_DATA_DEF, - @required this.onTouch, + required this.onTouch, this.width = 30, this.itemHeight = 16, this.textStyle, this.touchDownTextStyle}) - : assert(onTouch != null), - super(key: key); + : super(key: key); @override _IndexBarState createState() => _IndexBarState(); } class _IndexBarState extends State<_IndexBar> { - List _indexSectionList = List(); + List _indexSectionList = []; int _widgetTop = -1; int _lastIndex = 0; bool _widgetTopChange = false; @@ -176,27 +169,25 @@ class _IndexBarState extends State<_IndexBar> { _indexSectionList.clear(); _indexSectionList.add(0); int tempHeight = 0; - widget.data?.forEach((value) { + widget.data.forEach((value) { tempHeight = tempHeight + widget.itemHeight; _indexSectionList.add(tempHeight); }); } _triggerTouchEvent() { - if (widget.onTouch != null) { - widget.onTouch(_indexModel); - } + widget.onTouch(_indexModel); } @override Widget build(BuildContext context) { - TextStyle _style = widget.textStyle; + TextStyle? _style = widget.textStyle; if (_indexModel.isTouchDown == true) { _style = widget.touchDownTextStyle; } _init(); - List children = List(); + List children = []; widget.data.forEach((v) { children.add(SizedBox( width: widget.width.toDouble(), @@ -209,7 +200,7 @@ class _IndexBarState extends State<_IndexBar> { onVerticalDragDown: (DragDownDetails details) { if (_widgetTop == -1 || _widgetTopChange) { _widgetTopChange = false; - RenderBox box = context.findRenderObject(); + RenderBox? box = context.findRenderObject() as RenderBox; Offset topLeftPosition = box.localToGlobal(Offset.zero); _widgetTop = topLeftPosition.dy.toInt(); } diff --git a/lib/src/components/selectcity/brn_select_city_model.dart b/lib/src/components/selectcity/brn_select_city_model.dart index d3806cbd..d8c28a6b 100644 --- a/lib/src/components/selectcity/brn_select_city_model.dart +++ b/lib/src/components/selectcity/brn_select_city_model.dart @@ -1,25 +1,21 @@ -// @dart=2.9 - import 'package:bruno/src/components/selectcity/brn_az_common.dart'; class BrnSelectCityModel extends ISuspensionBean { - String name; - String tagIndex; - String namePinyin; - String tag; - String cityCode; + String name = ""; + String tagIndex = ""; + String? namePinyin; + String tag = ""; + String cityCode = ""; BrnSelectCityModel({ - this.name, - this.tagIndex, + required this.name, + this.tagIndex = "", this.namePinyin, - this.tag, - this.cityCode, + this.tag = "", + this.cityCode = "", }); - BrnSelectCityModel.fromJson(Map json) - : name = json['name'] == null ? "" : json['name'], - cityCode = json['cityCode'] == null ? "" : json['cityCode']; + BrnSelectCityModel.fromJson(Map json); Map toJson() => { 'name': name, 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 ba17a40d..8076d03a 100644 --- a/lib/src/components/selectcity/brn_single_select_city_page.dart +++ b/lib/src/components/selectcity/brn_single_select_city_page.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'dart:convert'; import 'package:bruno/src/components/empty/brn_empty_status.dart'; @@ -20,10 +18,10 @@ import 'package:lpinyin/lpinyin.dart'; /// 功能:多可以自定制导航栏文案,搜索文案信息,定位信息,右侧可快速滑动查看城市 class BrnSingleSelectCityPage extends StatefulWidget { /// 页面标题,默认空 - final String appBarTitle; + final String? appBarTitle; /// 热门推荐标题,默认空 - final String hotCityTitle; + final String? hotCityTitle; /// 是否展示searchBar,默认 true final bool showSearchBar; @@ -32,18 +30,18 @@ class BrnSingleSelectCityPage extends StatefulWidget { final String locationText; /// 城市列表 - final List cityList; + final List? cityList; /// 热门推荐城市列表 final List hotCityList; /// 单选项 点击的回调 - final ValueChanged onValueChanged; + final ValueChanged? onValueChanged; BrnSingleSelectCityPage({ this.appBarTitle = '', this.hotCityTitle = '', - this.hotCityList, + required this.hotCityList, this.cityList, this.showSearchBar = true, this.locationText = '', @@ -75,7 +73,7 @@ class _BrnSingleSelectCityPageState extends State { String _searchText = ""; /// search的TextController - BrnSearchTextController _brnSearchTextController; + late BrnSearchTextController _brnSearchTextController; @override void initState() { @@ -85,7 +83,7 @@ class _BrnSingleSelectCityPageState extends State { } void _loadData() async { - if (widget.cityList == null || widget.cityList.isEmpty) { + if (widget.cityList == null || widget.cityList!.isEmpty) { //加载城市列表 rootBundle .loadString( @@ -100,13 +98,13 @@ class _BrnSingleSelectCityPageState extends State { setState(() {}); }); } else { - _cityList = widget.cityList; + _cityList = widget.cityList!; _handleList(_cityList); setState(() {}); } } - void _handleList(List list) { + void _handleList(List? list) { if (list == null || list.isEmpty) return; for (int i = 0, length = list.length; i < length; i++) { String pinyin = PinyinHelper.getPinyinE(list[i].name); @@ -153,10 +151,12 @@ class _BrnSingleSelectCityPageState extends State { runAlignment: WrapAlignment.start, spacing: 10.0, children: hotCityList.map((e) { - return OutlineButton( - padding: EdgeInsets.all(0), - borderSide: BorderSide(color: Color(0xFFF8F8F8), width: .5), - color: Color(0xFFF8F8F8), + return OutlinedButton( + style: OutlinedButton.styleFrom( + padding: EdgeInsets.all(0), + side: BorderSide(color: Color(0xFFF8F8F8), width: .5), + backgroundColor: Color(0xFFF8F8F8), + ), child: Container( alignment: Alignment.center, height: 36.0, @@ -176,7 +176,7 @@ class _BrnSingleSelectCityPageState extends State { onPressed: () { debugPrint("OnItemClick: $e"); if (widget.onValueChanged != null) { - widget.onValueChanged(e); + widget.onValueChanged!(e); } Navigator.pop(context, e); }, @@ -188,7 +188,7 @@ class _BrnSingleSelectCityPageState extends State { ); } - Widget _buildSusWidget(String susTag) { + Widget _buildSusWidget(String? susTag) { return Container( height: _suspensionHeight.toDouble(), padding: const EdgeInsets.only(left: 15.0), @@ -206,7 +206,7 @@ class _BrnSingleSelectCityPageState extends State { } Widget _buildListItem(BrnSelectCityModel model) { - String susTag = model.getSuspensionTag(); + String? susTag = model.getSuspensionTag(); return Column( children: [ Offstage( @@ -220,7 +220,7 @@ class _BrnSingleSelectCityPageState extends State { onTap: () { debugPrint("OnItemClick: $model"); if (widget.onValueChanged != null) { - widget.onValueChanged(model); + widget.onValueChanged!(model); } Navigator.pop(context, model); }, @@ -236,7 +236,7 @@ class _BrnSingleSelectCityPageState extends State { hintText: '请输入搜索信息', onTextChange: (text) { _searchText = text; - _showCityStack = (text.length == 0 || text == null) ? true : false; + _showCityStack = text.isEmpty; setState(() {}); }, onTextCommit: (text) { @@ -272,12 +272,13 @@ class _BrnSingleSelectCityPageState extends State { @override Widget build(BuildContext context) { return Scaffold( + resizeToAvoidBottomInset: false, appBar: BrnAppBar(title: widget.appBarTitle ?? '城市选择'), body: Container( decoration: BoxDecoration(color: Colors.white), child: Column( children: [ - widget.locationText.isEmpty || widget.locationText == null + widget.locationText.isEmpty ? Container() : _buildLocationBar(widget.locationText), widget.showSearchBar ? _buildSearchBar() : Container(), @@ -302,13 +303,16 @@ class _BrnSingleSelectCityPageState extends State { headerHeight = 0; } if (_suspensionTag.isEmpty || _suspensionTag == '') { - _suspensionTag = _cityList.first.tag; + if (_cityList.isNotEmpty) { + _suspensionTag = _cityList.first.tag; + } } return Expanded( flex: 1, child: AzListView( data: _cityList, - itemBuilder: (context, model) => _buildListItem(model), + itemBuilder: (context, model) => + _buildListItem(model as BrnSelectCityModel), suspensionWidget: _buildSusWidget(_suspensionTag), isUseRealIndex: true, itemHeight: _itemHeight, diff --git a/lib/src/components/selectcity/brn_suspension_view.dart b/lib/src/components/selectcity/brn_suspension_view.dart index a1bdabd5..34f0bcbc 100644 --- a/lib/src/components/selectcity/brn_suspension_view.dart +++ b/lib/src/components/selectcity/brn_suspension_view.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'package:bruno/src/components/selectcity/brn_az_common.dart'; import 'package:flutter/material.dart'; @@ -27,27 +25,25 @@ class SuspensionView extends StatefulWidget { final int itemHeight; /// on sus tag change callback. - final ValueChanged onSusTagChanged; + final ValueChanged? onSusTagChanged; /// on sus section callback. - final OnSusSectionCallBack onSusSectionInited; + final OnSusSectionCallBack? onSusSectionInited; - final AzListViewHeader header; + final AzListViewHeader? header; SuspensionView({ - Key key, - @required this.data, - @required this.contentWidget, - @required this.suspensionWidget, - @required this.controller, + Key? key, + required this.data, + required this.contentWidget, + required this.suspensionWidget, + required this.controller, this.suspensionHeight = 40, this.itemHeight = 50, this.onSusTagChanged, this.onSusSectionInited, this.header, - }) : assert(contentWidget != null), - assert(controller != null), - super(key: key); + }) : super(key: key); @override _SuspensionWidgetState createState() => _SuspensionWidgetState(); @@ -55,25 +51,25 @@ class SuspensionView extends StatefulWidget { class _SuspensionWidgetState extends State { int _suspensionTop = 0; - int _lastIndex; - int _suSectionListLength; + int _lastIndex = -1; + late int _suSectionListLength; - List _suspensionSectionList = List(); + List _suspensionSectionList = []; Map _suspensionSectionMap = Map(); @override void initState() { super.initState(); if (widget.header != null) { - _suspensionTop = -widget.header.height; + _suspensionTop = -widget.header!.height; } - widget.controller?.addListener(_handleScrollerListenerTick); + widget.controller.addListener(_handleScrollerListenerTick); } @override void dispose() { super.dispose(); - widget.controller?.removeListener(_handleScrollerListenerTick); + widget.controller.removeListener(_handleScrollerListenerTick); } void _handleScrollerListenerTick() { @@ -82,17 +78,16 @@ class _SuspensionWidgetState extends State { if (_index != -1 && _lastIndex != _index) { _lastIndex = _index; if (widget.onSusTagChanged != null) { - widget.onSusTagChanged(_suspensionSectionMap.keys.toList()[_index]); + widget.onSusTagChanged!(_suspensionSectionMap.keys.toList()[_index]); } } } int _getIndex(int offset) { - if (widget.header != null && offset < widget.header.height) { - if (_suspensionTop != -widget.header.height && - widget.suspensionWidget != null) { + if (widget.header != null && offset < widget.header!.height) { + if (_suspensionTop != -widget.header!.height) { setState(() { - _suspensionTop = -widget.header.height; + _suspensionTop = -widget.header!.height; }); } return 0; @@ -104,7 +99,7 @@ class _SuspensionWidgetState extends State { } else { space = 0; } - if (_suspensionTop != space && widget.suspensionWidget != null) { + if (_suspensionTop != space) { setState(() { _suspensionTop = space; }); @@ -124,15 +119,15 @@ class _SuspensionWidgetState extends State { void _init() { _suspensionSectionMap.clear(); int offset = 0; - String tag; + String? tag; if (widget.header != null) { - _suspensionSectionMap[widget.header.tag] = 0; - offset = widget.header.height; + _suspensionSectionMap[widget.header!.tag] = 0; + offset = widget.header!.height; } - widget.data?.forEach((v) { + widget.data.forEach((v) { if (tag != v.tag) { tag = v.tag; - _suspensionSectionMap.putIfAbsent(tag, () => offset); + _suspensionSectionMap.putIfAbsent(tag!, () => offset); offset = offset + widget.suspensionHeight + widget.itemHeight; } else { offset = offset + widget.itemHeight; @@ -143,7 +138,7 @@ class _SuspensionWidgetState extends State { ..addAll(_suspensionSectionMap.values); _suSectionListLength = _suspensionSectionList.length; if (widget.onSusSectionInited != null) { - widget.onSusSectionInited(_suspensionSectionMap); + widget.onSusSectionInited!(_suspensionSectionMap); } } @@ -153,15 +148,15 @@ class _SuspensionWidgetState extends State { var children = [ widget.contentWidget, ]; - if (widget.suspensionWidget != null) { - children.add(Positioned( - ///-0.1修复部分手机丢失精度问题 - top: _suspensionTop.toDouble() - 0.1, - left: 0.0, - right: 0.0, - child: widget.suspensionWidget, - )); - } + + children.add(Positioned( + ///-0.1修复部分手机丢失精度问题 + top: _suspensionTop.toDouble() - 0.1, + left: 0.0, + right: 0.0, + child: widget.suspensionWidget, + )); + return Stack(children: children); } }