diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 400a7ec..836d4b1 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ + diff --git a/lib/app/res/path_unit.dart b/lib/app/res/path_unit.dart index 75cdce2..72237c1 100644 --- a/lib/app/res/path_unit.dart +++ b/lib/app/res/path_unit.dart @@ -12,7 +12,7 @@ class PathUnit{ static const categoryDataSync = '/categoryData/sync'; static const categoryData = '/categoryData'; - static const appInfo = '/appInfo/name/FlutterUnit'; + static const appInfo = '/appInfo/name'; static const login = '/login'; diff --git a/lib/app/utils/convert.dart b/lib/app/utils/convert.dart index c02c326..c4da6af 100644 --- a/lib/app/utils/convert.dart +++ b/lib/app/utils/convert.dart @@ -36,14 +36,13 @@ class Convert { }; static String convertFileSize(int size){ - if(size==null) return '0 kb'; double result = size / 1024.0; if(result<1024){ - return "${result.toStringAsFixed(2)}Kb"; + return "${result.toStringAsFixed(2)} Kb"; }else if(result>1024&&result<1024*1024){ - return "${(result/1024).toStringAsFixed(2)}Mb"; + return "${(result/1024).toStringAsFixed(2)} Mb"; }else{ - return "${(result/1024/1024).toStringAsFixed(2)}Gb"; + return "${(result/1024/1024).toStringAsFixed(2)} Gb"; } } diff --git a/lib/app/views/about/version/app_version_checker.dart b/lib/app/views/about/version/app_version_checker.dart deleted file mode 100644 index d66c925..0000000 --- a/lib/app/views/about/version/app_version_checker.dart +++ /dev/null @@ -1,169 +0,0 @@ -import 'dart:io'; - -import 'package:dio/dio.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import 'package:flutter_unit/app/utils/Toast.dart'; -import 'package:flutter_unit/app/utils/convert.dart'; -import 'package:flutter_unit/app/utils/http_utils/http_util.dart'; -import 'package:flutter_unit/app/utils/http_utils/result_bean.dart'; -import 'package:flutter_unit/point_system/api/app_info.dart'; -// import 'package:install_plugin/install_plugin.dart'; -import 'package:package_info_plus/package_info_plus.dart'; -import 'package:path/path.dart' as path; -import 'package:path_provider/path_provider.dart'; - -class AppVersionChecker extends StatefulWidget { - const AppVersionChecker({Key? key}) : super(key: key); - - @override - _AppVersionCheckerState createState() => _AppVersionCheckerState(); -} - -enum VersionState { none, loading, shouldUpdate, downloading } - -class _AppVersionCheckerState extends State { - final TextStyle labelStyle = TextStyle(fontSize: 13); - String oldVersion = ''; - String newVersion = ''; - int totalSize =0; - String url = 'http://toly1994.com/file/FlutterUnit.apk'; - ValueNotifier versionState = - ValueNotifier(VersionState.none); - - ValueNotifier progress = ValueNotifier(0); - - _doDownload() async { - // Directory? dir = await getExternalStorageDirectory(); - // if(dir ==null) return; - // - // String dstPath = path.join(dir.path, 'FlutterUnit.apk'); - // - // if(File(dstPath).existsSync()){ - // InstallPlugin.installApk(dstPath, 'com.toly1994.flutter_unit'); - // return; - // } - - // versionState.value = VersionState.downloading; - // - // await HttpUtil.getInstance().client.download(url, dstPath, - // onReceiveProgress: _onReceiveProgress, - // options: Options(receiveTimeout: 24 * 60 * 60 * 1000)); - // versionState.value = VersionState.none; - // InstallPlugin.installApk(dstPath, 'com.toly1994.flutter_unit'); - } - - void _onReceiveProgress(int count, int total) { - totalSize = total; - progress.value = count / total; - } - - @override - Widget build(BuildContext context) { - return ListTile( - title: Text('检查新版本', style: labelStyle), - trailing: ValueListenableBuilder( - valueListenable: versionState, - builder: _buildTrailByState, - ), - onTap: () async { - if (versionState.value == VersionState.shouldUpdate && - Platform.isAndroid) { - _doDownload(); - return; - } - - if (versionState.value == VersionState.downloading) { - return; - } - - versionState.value = VersionState.loading; - ResultBean result = await AppInfoApi.getAppVersion(); - PackageInfo packageInfo = await PackageInfo.fromPlatform(); - - if (result.status&&result.data!=null) { - print('${result.data!.appName}:${result.data!.appVersion}'); - if (packageInfo.version == result.data!.appVersion) { - Toast.success(context, '当前应用已是最新版本!'); - versionState.value = VersionState.none; - } else { - oldVersion = packageInfo.version; - newVersion = result.data!.appVersion; - Toast.green(context, '检测到新版本【${result.data!.appVersion}】,可点击更新!'); - versionState.value = VersionState.shouldUpdate; - } - } else { - print('${result.msg}'); - versionState.value = VersionState.none; - } - }, - ); - } - - Widget _buildTrailByState( - BuildContext context, VersionState value, Widget? child) { - switch (value) { - case VersionState.none: - return const SizedBox(); - case VersionState.loading: - return const CupertinoActivityIndicator(); - case VersionState.shouldUpdate: - return Wrap( - alignment: WrapAlignment.center, - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Text( - '$oldVersion --> $newVersion ', - style: TextStyle(height: 1, fontSize: 12, color: Colors.grey), - ), - const SizedBox( - width: 5, - ), - const Icon( - Icons.update, - color: Colors.green, - ) - ]); - case VersionState.downloading: - return ValueListenableBuilder( - valueListenable: progress, builder: _buildProgress); - } - return const SizedBox(); - } - - Widget _buildProgress(BuildContext context, double value, Widget? child) { - return Wrap( - alignment: WrapAlignment.center, - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Column( - children: [ - Text( - '${(value * 100).toStringAsFixed(2)} %', - style: TextStyle(height: 1, fontSize: 12, color: Colors.grey), - ), - const SizedBox( - height: 5, - ), - Text( - '${Convert.convertFileSize((totalSize * value).floor())}/${Convert.convertFileSize(totalSize)}', - style: TextStyle(height: 1, fontSize: 10, color: Colors.grey), - ), - ], - ), - const SizedBox( - width: 15, - ), - SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator( - strokeWidth: 2, - backgroundColor: Colors.grey, - value: value, - ), - ) - ]); - } -} diff --git a/lib/app/views/about/version_info.dart b/lib/app/views/about/version_info.dart index 1f0ca51..a99d585 100644 --- a/lib/app/views/about/version_info.dart +++ b/lib/app/views/about/version_info.dart @@ -6,9 +6,10 @@ import 'package:flutter_unit/app/router/unit_router.dart'; import 'package:flutter_unit/components/permanent/circle_image.dart'; import 'package:flutter_unit/components/permanent/feedback_widget.dart'; +import 'package:flutter_unit/update_part/views/app_update_panel.dart'; import 'package:url_launcher/url_launcher.dart'; -import 'version/app_version_checker.dart'; + import 'version/version_shower.dart'; /// create by 张风捷特烈 on 2020/6/16 @@ -79,7 +80,7 @@ class VersionInfo extends StatelessWidget { onTap: () => Navigator.of(context).pushNamed(UnitRouter.about_app), ), Divider(height: 1,indent: 10), - const AppVersionChecker(), + const AppUpdatePanel(), Divider(height: 1,indent: 10), ListTile( title: Text('检查数据库新版本',style: labelStyle), diff --git a/lib/app/views/navigation/bloc_wrapper.dart b/lib/app/views/navigation/bloc_wrapper.dart index 179c834..c0b6fdd 100644 --- a/lib/app/views/navigation/bloc_wrapper.dart +++ b/lib/app/views/navigation/bloc_wrapper.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_unit/app/blocs/global/global_bloc.dart'; import 'package:flutter_unit/app/blocs/global/global_event.dart'; +import 'package:flutter_unit/bloc_exp.dart'; import 'package:flutter_unit/point_system/blocs/point_system_bloc.dart'; import 'package:flutter_unit/widget_system/repositories/repositories.dart'; import 'package:flutter_unit/user_system/bloc/authentic/bloc.dart'; @@ -65,6 +66,7 @@ class _BlocWrapperState extends State { create: (_) => SearchBloc(repository: repository)), BlocProvider(create: (_) => PointBloc()), + BlocProvider(create: (_) => UpdateBloc()), BlocProvider(create: (_) => PointCommentBloc()), ], child: widget.child); diff --git a/lib/app/views/navigation/unit_navigation.dart b/lib/app/views/navigation/unit_navigation.dart index 63c66e2..18d17d2 100644 --- a/lib/app/views/navigation/unit_navigation.dart +++ b/lib/app/views/navigation/unit_navigation.dart @@ -1,24 +1,22 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/bloc_exp.dart'; + import 'package:flutter_unit/app/res/cons.dart'; import 'package:flutter_unit/app/router/unit_router.dart'; - -import 'package:flutter_unit/painter_system/gallery_unit.dart'; -import 'package:flutter_unit/user_system/pages/user/user_page.dart'; import 'package:flutter_unit/components/project/nav/unit_bottom_bar.dart'; import 'package:flutter_unit/components/project/overlay_tool_wrapper.dart'; +import 'package:flutter_unit/painter_system/gallery_unit.dart'; +import 'package:flutter_unit/user_system/pages/user/user_page.dart'; import 'package:flutter_unit/widget_system/blocs/widget_system_bloc.dart'; - import 'package:flutter_unit/widget_system/views/widget_system_view.dart'; - import '../../blocs/color_change_bloc.dart'; /// create by 张风捷特烈 on 2020-04-11 /// contact me by email 1981462002@qq.com /// 说明: 主题结构 左右滑页 + 底部导航栏 - class UnitNavigation extends StatefulWidget { const UnitNavigation(); @@ -33,6 +31,12 @@ class _UnitNavigationState extends State { // 禁止 PageView 滑动 final ScrollPhysics _neverScroll = const NeverScrollableScrollPhysics(); + @override + void initState() { + super.initState(); + BlocProvider.of(context).add(CheckUpdate(appName: 'FlutterUnit')); + } + @override void dispose() { _controller.dispose(); //释放控制器 @@ -95,12 +99,14 @@ class _UnitNavigationState extends State { ); // 点击底部按钮事件,切换页面 - _onTapBottomNav(int index) { - _controller.animateToPage(index, duration: const Duration(milliseconds: 200), curve: Curves.linear); - if(index!=0){ + void _onTapBottomNav(int index) { + _controller.animateToPage(index, + duration: const Duration(milliseconds: 200), curve: Curves.linear); + if (index != 0) { context.read().change(Theme.of(context).primaryColor); - }else{ - Color color = Cons.tabColors[context.read().state.family.index]; + } else { + Color color = + Cons.tabColors[context.read().state.family.index]; context.read().change(color); } diff --git a/lib/bloc_exp.dart b/lib/bloc_exp.dart new file mode 100644 index 0000000..7383950 --- /dev/null +++ b/lib/bloc_exp.dart @@ -0,0 +1,5 @@ +library bloc_exp; + +export 'update_part/bloc/bloc.dart'; +export 'update_part/bloc/event.dart'; +export 'update_part/bloc/state.dart'; \ No newline at end of file diff --git a/lib/components/project/nav/unit_bottom_bar.dart b/lib/components/project/nav/unit_bottom_bar.dart index 85464b8..a9cfa42 100644 --- a/lib/components/project/nav/unit_bottom_bar.dart +++ b/lib/components/project/nav/unit_bottom_bar.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_unit/app/res/size_unit.dart'; import 'package:flutter_unit/app/res/toly_icon.dart'; +import 'package:flutter_unit/update_part/views/update_red_point.dart'; import 'package:flutter_unit/components/permanent/feedback_widget.dart'; /// create by 张风捷特烈 on 2020-04-11 @@ -138,14 +139,22 @@ class _UnitBottomBarState extends State { child: FeedbackWidget( onPressed: () => _updateIndex(3), onLongPressed: () => _onLongPress(context, 3), - child: Container( - padding: paddingR, - height: SizeUnit.bottom_nav_height, - child: Icon( - TolyIcon.yonghu, - size: getIconSizeByPosition(3), - color: getIconColorByPosition(3), - )), + child: Stack( + children: [ + Container( + padding: paddingR, + height: SizeUnit.bottom_nav_height, + child: Icon( + TolyIcon.yonghu, + size: getIconSizeByPosition(3), + color: getIconColorByPosition(3), + )), + Positioned( + left: 20, + top: 5, + child: const UpdateRedPoint()) + ], + ), ), ), ], @@ -169,6 +178,7 @@ class _UnitBottomBarState extends State { void _onLongPress(BuildContext context, int index) { widget.onItemLongTap?.call(context, index); - } + + } diff --git a/lib/point_system/api/app_info.dart b/lib/point_system/api/app_info.dart index 777eea3..c143552 100644 --- a/lib/point_system/api/app_info.dart +++ b/lib/point_system/api/app_info.dart @@ -1,14 +1,15 @@ +import 'package:equatable/equatable.dart'; import 'package:flutter_unit/app/res/path_unit.dart'; import 'package:flutter_unit/app/utils/http_utils/http_util.dart'; import 'package:flutter_unit/app/utils/http_utils/result_bean.dart'; class AppInfoApi { - static Future> getAppVersion() async { + static Future> getAppVersion({required String appName}) async { String errorMsg = ""; var result = await HttpUtil.getInstance() .client - .get(PathUnit.appInfo) + .get(PathUnit.appInfo+"/$appName") .catchError((err) { errorMsg = err.toString(); }); @@ -22,6 +23,7 @@ class AppInfoApi { appName: result.data['data']['appName'], appVersion: result.data['data']['appVersion'], appUrl: result.data['data']['appUrl'], + appSize: result.data['data']['appSize'], )); } else { return ResultBean.ok(null); @@ -31,14 +33,24 @@ class AppInfoApi { } } -class AppInfo{ +class AppInfo extends Equatable{ final String appName; final String appVersion; final String appUrl; + final int appSize; AppInfo({ required this.appName, required this.appVersion, required this.appUrl, + required this.appSize, }); + + @override + List get props => [appName,appVersion,appUrl,appSize]; + + @override + String toString() { + return 'AppInfo{appName: $appName, appVersion: $appVersion, appUrl: $appUrl, appSize: $appSize}'; + } } \ No newline at end of file diff --git a/lib/update_part/bloc/bloc.dart b/lib/update_part/bloc/bloc.dart new file mode 100644 index 0000000..fb0f867 --- /dev/null +++ b/lib/update_part/bloc/bloc.dart @@ -0,0 +1,72 @@ +import 'dart:async'; + +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/utils/http_utils/result_bean.dart'; +import 'package:flutter_unit/point_system/api/app_info.dart'; +import 'package:package_info_plus/package_info_plus.dart'; +import 'package:r_upgrade/r_upgrade.dart'; + +import 'event.dart'; +import 'state.dart'; + +class UpdateBloc extends Bloc { + UpdateBloc() : super(const NoUpdateState()) { + on(_onCheckUpdate); + on(_onResetNoUpdate); + on(_onDownloadEvent); + on(_onDownloadingEvent); + } + + void _onCheckUpdate(CheckUpdate event, Emitter emit) async { + emit(CheckLoadingState()); + // await Future.delayed(Duration(seconds: 1)); + // 检测更新逻辑 + ResultBean result = + await AppInfoApi.getAppVersion(appName: event.appName); + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + + if (result.status && result.data != null) { + if (packageInfo.version == result.data!.appVersion) { + emit(NoUpdateState( + isChecked: true, + checkTime: DateTime.now().millisecondsSinceEpoch, + )); + } else { + if (result.data != null) { + emit(ShouldUpdateState( + oldVersion: packageInfo.version, info: result.data!)); + } + } + } else { + emit(CheckErrorState(error: result.msg)); + } + } + + void _onResetNoUpdate(ResetNoUpdate event, Emitter emit) { + emit(const NoUpdateState()); + } + + late int? id; + late StreamSubscription? subscription; + + void _onDownloadEvent(DownloadEvent event, Emitter emit) async{ + id = await RUpgrade.upgrade(event.appInfo.appUrl, + fileName: '${event.appInfo.appName}.apk', isAutoRequestInstall: true); + subscription = RUpgrade.stream.listen((DownloadInfo info) { + double progress = (info.percent ?? 0) / 100; + if (info.status! == DownloadStatus.STATUS_SUCCESSFUL) { + progress = 1; + subscription?.cancel(); + add(ResetNoUpdate()); + } + add(DownloadingEvent(state: DownloadingState( + appSize: event.appInfo.appSize, + progress: progress + ))); + }); + } + + void _onDownloadingEvent(DownloadingEvent event, Emitter emit) { + emit(event.state); + } +} diff --git a/lib/update_part/bloc/event.dart b/lib/update_part/bloc/event.dart new file mode 100644 index 0000000..4c0e36c --- /dev/null +++ b/lib/update_part/bloc/event.dart @@ -0,0 +1,43 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter_unit/bloc_exp.dart'; +import 'package:flutter_unit/point_system/api/app_info.dart'; + +abstract class UpdateEvent extends Equatable { + const UpdateEvent(); +} + +// 检查更新 ---> 校验,转换状态 +class CheckUpdate extends UpdateEvent { + final String appName; + + const CheckUpdate({required this.appName}); + + @override + List get props => [appName]; +} + +class DownloadEvent extends UpdateEvent { + final AppInfo appInfo; + + const DownloadEvent({required this.appInfo}); + + @override + List get props => [appInfo]; +} + +class DownloadingEvent extends UpdateEvent { + final DownloadingState state; + + const DownloadingEvent({required this.state}); + + @override + List get props => [state]; +} + +// 将状态重置为 NoUpdateState +class ResetNoUpdate extends UpdateEvent { + const ResetNoUpdate(); + + @override + List get props => []; +} diff --git a/lib/update_part/bloc/state.dart b/lib/update_part/bloc/state.dart new file mode 100644 index 0000000..68052ed --- /dev/null +++ b/lib/update_part/bloc/state.dart @@ -0,0 +1,61 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter_unit/point_system/api/app_info.dart'; + +abstract class UpdateState extends Equatable { + const UpdateState(); +} + +class NoUpdateState extends UpdateState { + final bool isChecked; + final int checkTime; + + const NoUpdateState({this.isChecked = false, this.checkTime = 0}); + + @override + List get props => [isChecked, checkTime]; +} + +class CheckLoadingState extends UpdateState { + const CheckLoadingState(); + @override + List get props => []; +} + +class DownloadingState extends UpdateState { + final double progress; + final int appSize; + + const DownloadingState({required this.progress, required this.appSize}); + + @override + List get props => [progress, appSize]; +} + +class CheckErrorState extends UpdateState { + final String error; + + const CheckErrorState({required this.error}); + + @override + List get props => [error]; + + @override + String toString() { + return 'CheckErrorState{error: $error}'; + } +} + +class ShouldUpdateState extends UpdateState { + final String oldVersion; + final AppInfo info; + + const ShouldUpdateState({required this.oldVersion, required this.info}); + + @override + List get props => [oldVersion, info]; + + @override + String toString() { + return 'ShouldUpdateState{oldVersion: $oldVersion, info: $info}'; + } +} diff --git a/lib/update_part/views/app_update_panel.dart b/lib/update_part/views/app_update_panel.dart new file mode 100644 index 0000000..dfbdb46 --- /dev/null +++ b/lib/update_part/views/app_update_panel.dart @@ -0,0 +1,108 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/app/utils/Toast.dart'; +import 'package:flutter_unit/app/utils/convert.dart'; +import 'package:flutter_unit/bloc_exp.dart'; + +class AppUpdatePanel extends StatelessWidget { + const AppUpdatePanel(); + + @override + Widget build(BuildContext context) { + return BlocConsumer( + builder: _buildByUpdateState, + listener: _listenerByUpdateState, + ); + } + + Widget _buildProgress(BuildContext context, double progress, int appSize) { + return Wrap( + alignment: WrapAlignment.center, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Column( + children: [ + Text( + '${(progress * 100).toStringAsFixed(2)} %', + style: TextStyle(height: 1, fontSize: 12, color: Colors.grey), + ), + const SizedBox( + height: 5, + ), + Text( + '${Convert.convertFileSize((appSize * progress).floor())}/${Convert.convertFileSize(appSize)}', + style: TextStyle(height: 1, fontSize: 10, color: Colors.grey), + ), + ], + ), + const SizedBox( + width: 15, + ), + SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + backgroundColor: Colors.grey, + value: progress, + ), + ) + ]); + } + + Widget _buildByUpdateState(BuildContext context, UpdateState state) { + String info = '检查新版本'; + Widget trail = const SizedBox.shrink(); + if (state is ShouldUpdateState) { + info = "下载新版本"; + trail = Wrap( + alignment: WrapAlignment.center, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Text( + '${state.oldVersion} --> ${state.info.appVersion} ', + style: TextStyle(height: 1, fontSize: 12, color: Colors.grey), + ), + const SizedBox(width: 5), + const Icon(Icons.update, color: Colors.green) + ]); + } + if (state is CheckLoadingState) { + trail = CupertinoActivityIndicator(); + } + if (state is DownloadingState) { + info = "新版本下载中..."; + trail = _buildProgress(context, state.progress, state.appSize); + } + + return ListTile( + title: Text( + info, + style: const TextStyle(fontSize: 13), + ), + trailing: trail, + onTap: () => _tapByState(state, context), + ); + } + + void _tapByState(UpdateState state, BuildContext context) { + if (state is NoUpdateState) { + BlocProvider.of(context) + .add(CheckUpdate(appName: 'FlutterUnit')); + } + if (state is ShouldUpdateState) { + // 处理下载的事件 + BlocProvider.of(context) + .add(DownloadEvent(appInfo: state.info)); + } + } + + void _listenerByUpdateState(BuildContext context, UpdateState state) { + if (state is NoUpdateState) { + if (state.isChecked) { + Toast.success(context, '当前应用已是最新版本!'); + } + } + } +} diff --git a/lib/update_part/views/update_red_point.dart b/lib/update_part/views/update_red_point.dart new file mode 100644 index 0000000..dbb8dfb --- /dev/null +++ b/lib/update_part/views/update_red_point.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_unit/bloc_exp.dart'; + + +class UpdateRedPoint extends StatelessWidget { + const UpdateRedPoint({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + Widget radPoint = Container( + width: 8, + height: 8, + decoration: BoxDecoration(color: Colors.red, shape: BoxShape.circle), + ); + return BlocBuilder( + builder: (BuildContext context, UpdateState state) { + if (state is ShouldUpdateState) { + return radPoint; + } else { + return const SizedBox.shrink(); + } + }, + ); + } +} diff --git a/lib/user_system/pages/user/page_item.dart b/lib/user_system/pages/user/page_item.dart index fde1f51..5b7859a 100644 --- a/lib/user_system/pages/user/page_item.dart +++ b/lib/user_system/pages/user/page_item.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_unit/app/res/style/behavior/no_scroll_behavior.dart'; import 'package:flutter_unit/app/res/toly_icon.dart'; import 'package:flutter_unit/app/router/unit_router.dart'; +import 'package:flutter_unit/update_part/views/update_red_point.dart'; /// create by 张风捷特烈 on 2020-03-26 /// contact me by email 1981462002@qq.com @@ -27,12 +28,19 @@ class MePageItem extends StatelessWidget { height: 10, ), _buildItem(context, TolyIcon.icon_them, '应用设置', UnitRouter.setting), - _buildItem(context, TolyIcon.icon_layout, '数据管理', UnitRouter.data_manage), - _buildItem(context, TolyIcon.icon_collect, '我的收藏', UnitRouter.collect), + _buildItem( + context, TolyIcon.icon_layout, '数据管理', UnitRouter.data_manage), + _buildItem( + context, TolyIcon.icon_collect, '我的收藏', UnitRouter.collect), Divider( height: 1, ), - _buildItem(context, Icons.update, '版本信息', UnitRouter.version_info), + Stack( + children: [ + _buildItem(context, Icons.update, '版本信息', UnitRouter.version_info,), + Positioned(left: 40, top: 10, child: UpdateRedPoint()) + ], + ), _buildItem(context, Icons.info, '关于应用', UnitRouter.about_app), Divider( height: 1, @@ -51,7 +59,11 @@ class MePageItem extends StatelessWidget { icon, color: Theme.of(context).primaryColor, ), - title: Text(title), + title: Stack( + children: [ + Text(title), + ], + ), trailing: Icon(Icons.chevron_right, color: Theme.of(context).primaryColor), onTap: () { diff --git a/pubspec.lock b/pubspec.lock index 66e702c..b741b98 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -345,6 +345,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "6.0.1" + r_upgrade: + dependency: "direct main" + description: + name: r_upgrade + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.3.7+3" share_plus: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 671ba1b..13d76a1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_unit description: A new Flutter application. -version: 1.6.0 +version: 1.6.1 author: 张风捷特烈 <1981462002@qq.com> homepage: https://juejin.cn/user/149189281194766/posts @@ -16,6 +16,7 @@ dependencies: stream_transform: ^2.0.0 equatable: ^2.0.3 # 相等辅助 package_info_plus: ^1.3.0 # 应用包信息 + r_upgrade: ^0.3.7+3 sqflite: ^2.0.2 # 数据库 shared_preferences: ^2.0.13 # xml 固化 jwt_decoder: ^2.0.1 # jwt 解析