Showing
19 changed files
with
215 additions
and
847 deletions
| ... | @@ -3,6 +3,7 @@ import 'package:Parlando/account/view_models/account_view_model.dart'; | ... | @@ -3,6 +3,7 @@ import 'package:Parlando/account/view_models/account_view_model.dart'; |
| 3 | import 'package:Parlando/apis/api_response.dart'; | 3 | import 'package:Parlando/apis/api_response.dart'; |
| 4 | import 'package:Parlando/login/login_router.dart'; | 4 | import 'package:Parlando/login/login_router.dart'; |
| 5 | import 'package:Parlando/res/constant.dart'; | 5 | import 'package:Parlando/res/constant.dart'; |
| 6 | +import 'package:Parlando/routers/routers.dart'; | ||
| 6 | import 'package:cached_network_image/cached_network_image.dart'; | 7 | import 'package:cached_network_image/cached_network_image.dart'; |
| 7 | import 'package:flustars/flustars.dart'; | 8 | import 'package:flustars/flustars.dart'; |
| 8 | import 'package:flutter/material.dart'; | 9 | import 'package:flutter/material.dart'; |
| ... | @@ -121,6 +122,8 @@ class _AccountPageState extends State<AccountPage> { | ... | @@ -121,6 +122,8 @@ class _AccountPageState extends State<AccountPage> { |
| 121 | likeButton, | 122 | likeButton, |
| 122 | avatar, | 123 | avatar, |
| 123 | Positioned( | 124 | Positioned( |
| 125 | + left: 64.px, | ||
| 126 | + bottom: 10.px, | ||
| 124 | child: GestureDetector( | 127 | child: GestureDetector( |
| 125 | child: CircleAvatar( | 128 | child: CircleAvatar( |
| 126 | backgroundColor: Colors.red.withOpacity(0.4), | 129 | backgroundColor: Colors.red.withOpacity(0.4), |
| ... | @@ -136,8 +139,6 @@ class _AccountPageState extends State<AccountPage> { | ... | @@ -136,8 +139,6 @@ class _AccountPageState extends State<AccountPage> { |
| 136 | context, AccountRouter.accountEditPage); | 139 | context, AccountRouter.accountEditPage); |
| 137 | }, | 140 | }, |
| 138 | ), | 141 | ), |
| 139 | - left: 64.px, | ||
| 140 | - bottom: 10.px, | ||
| 141 | ), | 142 | ), |
| 142 | ], | 143 | ], |
| 143 | ), | 144 | ), |
| ... | @@ -249,6 +250,51 @@ class _AccountPageState extends State<AccountPage> { | ... | @@ -249,6 +250,51 @@ class _AccountPageState extends State<AccountPage> { |
| 249 | ], | 250 | ], |
| 250 | ), | 251 | ), |
| 251 | ), | 252 | ), |
| 253 | + bottomNavigationBar: Consumer( | ||
| 254 | + builder: (_, provider, __) { | ||
| 255 | + return BottomAppBar( | ||
| 256 | + color: Colors.grey, | ||
| 257 | + child: Row( | ||
| 258 | + mainAxisSize: MainAxisSize.max, | ||
| 259 | + mainAxisAlignment: MainAxisAlignment.spaceAround, | ||
| 260 | + children: <Widget>[ | ||
| 261 | + InkWell( | ||
| 262 | + onTap: () { | ||
| 263 | + NavigatorUtils.push(context, Routes.home, | ||
| 264 | + clearStack: true); | ||
| 265 | + }, | ||
| 266 | + child: Container( | ||
| 267 | + alignment: Alignment.center, | ||
| 268 | + height: 36.0, | ||
| 269 | + child: Text( | ||
| 270 | + ParlandoLocalizations.of(context) | ||
| 271 | + .onePoemBottomNavigationBarItemTitle, | ||
| 272 | + style: const TextStyle( | ||
| 273 | + color: Colors.white54, | ||
| 274 | + fontSize: 15.0, | ||
| 275 | + ), | ||
| 276 | + ), | ||
| 277 | + ), | ||
| 278 | + ), | ||
| 279 | + InkWell( | ||
| 280 | + onTap: () {}, | ||
| 281 | + child: Container( | ||
| 282 | + alignment: Alignment.center, | ||
| 283 | + height: 36.0, | ||
| 284 | + child: Text( | ||
| 285 | + ParlandoLocalizations.of(context) | ||
| 286 | + .profileBottomNavigationBarItemTitle, | ||
| 287 | + style: const TextStyle( | ||
| 288 | + color: Colors.white54, | ||
| 289 | + fontSize: 15.0, | ||
| 290 | + ), | ||
| 291 | + ), | ||
| 292 | + ), | ||
| 293 | + ), | ||
| 294 | + ]), | ||
| 295 | + ); | ||
| 296 | + }, | ||
| 297 | + ), | ||
| 252 | ); | 298 | ); |
| 253 | case Status.ERROR: | 299 | case Status.ERROR: |
| 254 | return Center( | 300 | return Center( | ... | ... |
| ... | @@ -41,7 +41,7 @@ class _PermissionRequestWidgetState extends State<PermissionRequestWidget> | ... | @@ -41,7 +41,7 @@ class _PermissionRequestWidgetState extends State<PermissionRequestWidget> |
| 41 | checkPermission(); | 41 | checkPermission(); |
| 42 | //注册观察者 | 42 | //注册观察者 |
| 43 | if (WidgetsBinding.instance != null) { | 43 | if (WidgetsBinding.instance != null) { |
| 44 | - WidgetsBinding.instance!.addObserver(this); | 44 | + WidgetsBinding.instance.addObserver(this); |
| 45 | } | 45 | } |
| 46 | } | 46 | } |
| 47 | 47 | ||
| ... | @@ -164,7 +164,7 @@ class _PermissionRequestWidgetState extends State<PermissionRequestWidget> | ... | @@ -164,7 +164,7 @@ class _PermissionRequestWidgetState extends State<PermissionRequestWidget> |
| 164 | void dispose() { | 164 | void dispose() { |
| 165 | //注销观察者 | 165 | //注销观察者 |
| 166 | if (WidgetsBinding.instance != null) { | 166 | if (WidgetsBinding.instance != null) { |
| 167 | - WidgetsBinding.instance!.removeObserver(this); | 167 | + WidgetsBinding.instance.removeObserver(this); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | super.dispose(); | 170 | super.dispose(); | ... | ... |
| 1 | -import 'package:Parlando/events/trans_event.dart'; | 1 | +import 'package:Parlando/common/permission_request_widget.dart'; |
| 2 | -import 'package:Parlando/poem/poem_router.dart'; | ||
| 3 | import 'package:Parlando/routers/fluro_navigator.dart'; | 2 | import 'package:Parlando/routers/fluro_navigator.dart'; |
| 4 | -import 'package:Parlando/widgets/radial/flutter_radial_menu.dart'; | ||
| 5 | import 'package:flutter/material.dart'; | 3 | import 'package:flutter/material.dart'; |
| 6 | import 'package:Parlando/account/page/account_page.dart'; | 4 | import 'package:Parlando/account/page/account_page.dart'; |
| 7 | import 'package:Parlando/poem/page/poem_page.dart'; | 5 | import 'package:Parlando/poem/page/poem_page.dart'; |
| 8 | import 'package:Parlando/widgets/double_tap_back_exit_app.dart'; | 6 | import 'package:Parlando/widgets/double_tap_back_exit_app.dart'; |
| 9 | import 'package:provider/provider.dart'; | 7 | import 'package:provider/provider.dart'; |
| 10 | -import 'package:flutter_gen/gen_l10n/Parlando_localizations.dart'; | ||
| 11 | import 'provider/home_provider.dart'; | 8 | import 'provider/home_provider.dart'; |
| 9 | +import 'package:permission_handler/permission_handler.dart'; | ||
| 12 | 10 | ||
| 13 | class Home extends StatefulWidget { | 11 | class Home extends StatefulWidget { |
| 14 | const Home({Key? key}) : super(key: key); | 12 | const Home({Key? key}) : super(key: key); |
| ... | @@ -17,56 +15,42 @@ class Home extends StatefulWidget { | ... | @@ -17,56 +15,42 @@ class Home extends StatefulWidget { |
| 17 | _HomeState createState() => _HomeState(); | 15 | _HomeState createState() => _HomeState(); |
| 18 | } | 16 | } |
| 19 | 17 | ||
| 20 | -enum MenuOptions { | ||
| 21 | - audio, | ||
| 22 | - video, | ||
| 23 | -} | ||
| 24 | - | ||
| 25 | class _HomeState extends State<Home> with RestorationMixin { | 18 | class _HomeState extends State<Home> with RestorationMixin { |
| 26 | late List<Widget> _pageList; | 19 | late List<Widget> _pageList; |
| 27 | final PageController _pageController = PageController(); | 20 | final PageController _pageController = PageController(); |
| 28 | 21 | ||
| 29 | HomeProvider provider = HomeProvider(); | 22 | HomeProvider provider = HomeProvider(); |
| 30 | - final GlobalKey<RadialMenuState> _menuKey = GlobalKey<RadialMenuState>(); | ||
| 31 | - final List<RadialMenuItem<MenuOptions>> items = <RadialMenuItem<MenuOptions>>[ | ||
| 32 | - const RadialMenuItem<MenuOptions>( | ||
| 33 | - tooltip: 'audio', | ||
| 34 | - value: MenuOptions.audio, | ||
| 35 | - child: Icon( | ||
| 36 | - Icons.mic_none_outlined, | ||
| 37 | - ), | ||
| 38 | - iconColor: Colors.white, | ||
| 39 | - backgroundColor: Colors.blue, | ||
| 40 | - ), | ||
| 41 | - const RadialMenuItem<MenuOptions>( | ||
| 42 | - tooltip: "video", | ||
| 43 | - value: MenuOptions.video, | ||
| 44 | - child: Icon( | ||
| 45 | - Icons.video_call_outlined, | ||
| 46 | - ), | ||
| 47 | - iconColor: Colors.white, | ||
| 48 | - backgroundColor: Colors.green, | ||
| 49 | - ), | ||
| 50 | - ]; | ||
| 51 | - | ||
| 52 | - void _onItemSelected(MenuOptions value) { | ||
| 53 | - if (value == MenuOptions.video) { | ||
| 54 | - NavigatorUtils.push( | ||
| 55 | - context, | ||
| 56 | - '${PoemRouter.poemRecordAudioPage}?id=100', | ||
| 57 | - ); | ||
| 58 | - } else if (value == MenuOptions.audio) { | ||
| 59 | - NavigatorUtils.push( | ||
| 60 | - context, | ||
| 61 | - '${PoemRouter.poemRecordVideoPage}?data=100', | ||
| 62 | - ); | ||
| 63 | - } | ||
| 64 | - } | ||
| 65 | 23 | ||
| 66 | @override | 24 | @override |
| 67 | void initState() { | 25 | void initState() { |
| 68 | super.initState(); | 26 | super.initState(); |
| 69 | initData(); | 27 | initData(); |
| 28 | + List<String> list = [ | ||
| 29 | + "为您更好的体验应用,所以需要获取您的手机摄像头权限,以保存您的一些偏好设置", | ||
| 30 | + "您已拒绝权限,所以无法保存您的一些偏好设置,将无法使用APP", | ||
| 31 | + "您已拒绝权限,请在设置中心中同意APP的权限请求", | ||
| 32 | + "其他错误" | ||
| 33 | + ]; | ||
| 34 | + | ||
| 35 | + Future.delayed( | ||
| 36 | + Duration.zero, | ||
| 37 | + () { | ||
| 38 | + NavigatorUtils.pushPageByFade( | ||
| 39 | + context: context, | ||
| 40 | + //目标页面 | ||
| 41 | + targetPage: PermissionRequestWidget( | ||
| 42 | + //所需要申请的权限 | ||
| 43 | + permission: Permission.camera, | ||
| 44 | + //显示关闭应用按钮 | ||
| 45 | + isCloseApp: true, | ||
| 46 | + //提示文案 | ||
| 47 | + permissionList: list, | ||
| 48 | + ), | ||
| 49 | + //权限申请结果 | ||
| 50 | + dismissCallBack: (value) {}, | ||
| 51 | + ); | ||
| 52 | + }, | ||
| 53 | + ); | ||
| 70 | } | 54 | } |
| 71 | 55 | ||
| 72 | @override | 56 | @override |
| ... | @@ -88,87 +72,6 @@ class _HomeState extends State<Home> with RestorationMixin { | ... | @@ -88,87 +72,6 @@ class _HomeState extends State<Home> with RestorationMixin { |
| 88 | create: (_) => provider, | 72 | create: (_) => provider, |
| 89 | child: DoubleTapBackExitApp( | 73 | child: DoubleTapBackExitApp( |
| 90 | child: Scaffold( | 74 | child: Scaffold( |
| 91 | - floatingActionButton: FloatingActionButton( | ||
| 92 | - onPressed: () { | ||
| 93 | - eventBus.fire(TransEvent()); | ||
| 94 | - NavigatorUtils.push( | ||
| 95 | - context, | ||
| 96 | - '${PoemRouter.poemRecordVideoPage}?data=100', | ||
| 97 | - ); | ||
| 98 | - }, | ||
| 99 | - tooltip: "发一言", | ||
| 100 | - backgroundColor: Colors.white, | ||
| 101 | - child: const Icon( | ||
| 102 | - Icons.video_call_outlined, | ||
| 103 | - color: Colors.black45, | ||
| 104 | - ), | ||
| 105 | - ), | ||
| 106 | - // floatingActionButton: SizedBox( | ||
| 107 | - // height: 60, | ||
| 108 | - // child: RadialMenu( | ||
| 109 | - // key: _menuKey, | ||
| 110 | - // items: items, | ||
| 111 | - // radius: 80.0, | ||
| 112 | - // onSelected: _onItemSelected, | ||
| 113 | - // progressAnimationDuration:const Duration(milliseconds: 1), | ||
| 114 | - // ), | ||
| 115 | - // ), | ||
| 116 | - floatingActionButtonLocation: | ||
| 117 | - FloatingActionButtonLocation.centerDocked, | ||
| 118 | - bottomNavigationBar: Consumer<HomeProvider>( | ||
| 119 | - builder: (_, provider, __) { | ||
| 120 | - return BottomAppBar( | ||
| 121 | - color: Colors.black45, | ||
| 122 | - child: Row( | ||
| 123 | - mainAxisSize: MainAxisSize.max, | ||
| 124 | - mainAxisAlignment: MainAxisAlignment.spaceAround, | ||
| 125 | - children: <Widget>[ | ||
| 126 | - InkWell( | ||
| 127 | - onTap: () { | ||
| 128 | - _pageController.animateToPage( | ||
| 129 | - 0, | ||
| 130 | - duration: const Duration(milliseconds: 100), | ||
| 131 | - curve: Curves.easeOutSine, | ||
| 132 | - ); | ||
| 133 | - }, | ||
| 134 | - child: Container( | ||
| 135 | - alignment: Alignment.center, | ||
| 136 | - height: 36.0, | ||
| 137 | - child: Text( | ||
| 138 | - ParlandoLocalizations.of(context) | ||
| 139 | - .onePoemBottomNavigationBarItemTitle, | ||
| 140 | - style: const TextStyle( | ||
| 141 | - color: Colors.white54, | ||
| 142 | - fontSize: 15.0, | ||
| 143 | - ), | ||
| 144 | - ), | ||
| 145 | - ), | ||
| 146 | - ), | ||
| 147 | - InkWell( | ||
| 148 | - onTap: () { | ||
| 149 | - _pageController.animateToPage( | ||
| 150 | - 1, | ||
| 151 | - duration: const Duration(milliseconds: 100), | ||
| 152 | - curve: Curves.easeOutSine, | ||
| 153 | - ); | ||
| 154 | - }, | ||
| 155 | - child: Container( | ||
| 156 | - alignment: Alignment.center, | ||
| 157 | - height: 36.0, | ||
| 158 | - child: Text( | ||
| 159 | - ParlandoLocalizations.of(context) | ||
| 160 | - .profileBottomNavigationBarItemTitle, | ||
| 161 | - style: const TextStyle( | ||
| 162 | - color: Colors.white54, | ||
| 163 | - fontSize: 15.0, | ||
| 164 | - ), | ||
| 165 | - ), | ||
| 166 | - ), | ||
| 167 | - ), | ||
| 168 | - ]), | ||
| 169 | - ); | ||
| 170 | - }, | ||
| 171 | - ), | ||
| 172 | // 使用PageView的原因参看 https://zhuanlan.zhihu.com/p/58582876 | 75 | // 使用PageView的原因参看 https://zhuanlan.zhihu.com/p/58582876 |
| 173 | body: PageView( | 76 | body: PageView( |
| 174 | physics: const NeverScrollableScrollPhysics(), // 禁止滑动 | 77 | physics: const NeverScrollableScrollPhysics(), // 禁止滑动 | ... | ... |
| ... | @@ -34,7 +34,7 @@ class _SplashPageState extends State<SplashPage> { | ... | @@ -34,7 +34,7 @@ class _SplashPageState extends State<SplashPage> { |
| 34 | @override | 34 | @override |
| 35 | void initState() { | 35 | void initState() { |
| 36 | super.initState(); | 36 | super.initState(); |
| 37 | - WidgetsBinding.instance!.addPostFrameCallback((_) async { | 37 | + WidgetsBinding.instance.addPostFrameCallback((_) async { |
| 38 | /// 两种初始化方案,另一种见 main.dart | 38 | /// 两种初始化方案,另一种见 main.dart |
| 39 | /// 两种方法各有优劣 | 39 | /// 两种方法各有优劣 |
| 40 | await SpUtil.getInstance(); | 40 | await SpUtil.getInstance(); | ... | ... |
| ... | @@ -8,7 +8,6 @@ import 'package:flustars/flustars.dart'; | ... | @@ -8,7 +8,6 @@ import 'package:flustars/flustars.dart'; |
| 8 | import 'package:flutter/gestures.dart'; | 8 | import 'package:flutter/gestures.dart'; |
| 9 | import 'package:flutter/material.dart'; | 9 | import 'package:flutter/material.dart'; |
| 10 | import 'package:flutter/services.dart'; | 10 | import 'package:flutter/services.dart'; |
| 11 | -import 'package:Parlando/common/permission_request_widget.dart'; | ||
| 12 | import 'package:Parlando/common/protocol_model.dart'; | 11 | import 'package:Parlando/common/protocol_model.dart'; |
| 13 | import 'package:Parlando/home/webview_page.dart'; | 12 | import 'package:Parlando/home/webview_page.dart'; |
| 14 | import 'package:Parlando/login/widgets/my_text_field.dart'; | 13 | import 'package:Parlando/login/widgets/my_text_field.dart'; |
| ... | @@ -29,8 +28,6 @@ import '../login_router.dart'; | ... | @@ -29,8 +28,6 @@ import '../login_router.dart'; |
| 29 | import 'package:flutter_gen/gen_l10n/Parlando_localizations.dart'; | 28 | import 'package:flutter_gen/gen_l10n/Parlando_localizations.dart'; |
| 30 | import 'package:Parlando/extension/int_extension.dart'; | 29 | import 'package:Parlando/extension/int_extension.dart'; |
| 31 | 30 | ||
| 32 | -import 'package:permission_handler/permission_handler.dart'; | ||
| 33 | - | ||
| 34 | /// design/1注册登录/index.html | 31 | /// design/1注册登录/index.html |
| 35 | class LoginPage extends StatefulWidget { | 32 | class LoginPage extends StatefulWidget { |
| 36 | const LoginPage({Key? key}) : super(key: key); | 33 | const LoginPage({Key? key}) : super(key: key); |
| ... | @@ -63,41 +60,13 @@ class _LoginPageState extends State<LoginPage> | ... | @@ -63,41 +60,13 @@ class _LoginPageState extends State<LoginPage> |
| 63 | @override | 60 | @override |
| 64 | void initState() { | 61 | void initState() { |
| 65 | super.initState(); | 62 | super.initState(); |
| 66 | - WidgetsBinding.instance!.addPostFrameCallback((_) { | 63 | + WidgetsBinding.instance.addPostFrameCallback((_) { |
| 67 | /// 显示状态栏和导航栏 | 64 | /// 显示状态栏和导航栏 |
| 68 | SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, | 65 | SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, |
| 69 | overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); | 66 | overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); |
| 70 | }); | 67 | }); |
| 71 | _nameController.text = SpUtil.getString(Constant.phone).nullSafe; | 68 | _nameController.text = SpUtil.getString(Constant.phone).nullSafe; |
| 72 | - | 69 | + showPrivacyPage(); |
| 73 | - List<String> _list = [ | ||
| 74 | - "为您更好的体验应用,所以需要获取您的手机文件存储权限,以保存您的一些偏好设置", | ||
| 75 | - "您已拒绝权限,所以无法保存您的一些偏好设置,将无法使用APP", | ||
| 76 | - "您已拒绝权限,请在设置中心中同意APP的权限请求", | ||
| 77 | - "其他错误" | ||
| 78 | - ]; | ||
| 79 | - | ||
| 80 | - // Future.delayed( | ||
| 81 | - // Duration.zero, | ||
| 82 | - // () { | ||
| 83 | - // NavigatorUtils.pushPageByFade( | ||
| 84 | - // context: context, | ||
| 85 | - // //目标页面 | ||
| 86 | - // targetPage: PermissionRequestWidget( | ||
| 87 | - // //所需要申请的权限 | ||
| 88 | - // permission: Permission.camera, | ||
| 89 | - // //显示关闭应用按钮 | ||
| 90 | - // isCloseApp: true, | ||
| 91 | - // //提示文案 | ||
| 92 | - // permissionList: _list, | ||
| 93 | - // ), | ||
| 94 | - // //权限申请结果 | ||
| 95 | - // dismissCallBack: (value) { | ||
| 96 | - // showPrivacyPage(); | ||
| 97 | - // }, | ||
| 98 | - // ); | ||
| 99 | - // }, | ||
| 100 | - // ); | ||
| 101 | } | 70 | } |
| 102 | 71 | ||
| 103 | void showPrivacyPage() async { | 72 | void showPrivacyPage() async { | ... | ... |
| ... | @@ -85,7 +85,7 @@ class _PoemDetailPageState extends State<PoemDetailPage> { | ... | @@ -85,7 +85,7 @@ class _PoemDetailPageState extends State<PoemDetailPage> { |
| 85 | void initState() { | 85 | void initState() { |
| 86 | super.initState(); | 86 | super.initState(); |
| 87 | // 获取Build完成状态监听 | 87 | // 获取Build完成状态监听 |
| 88 | - WidgetsBinding.instance!.addPostFrameCallback((_) { | 88 | + WidgetsBinding.instance.addPostFrameCallback((_) { |
| 89 | _showHint(); | 89 | _showHint(); |
| 90 | }); | 90 | }); |
| 91 | } | 91 | } | ... | ... |
| ... | @@ -48,7 +48,7 @@ class _PoemPageState extends State<PoemPage> with WidgetsBindingObserver { | ... | @@ -48,7 +48,7 @@ class _PoemPageState extends State<PoemPage> with WidgetsBindingObserver { |
| 48 | 48 | ||
| 49 | @override | 49 | @override |
| 50 | void dispose() { | 50 | void dispose() { |
| 51 | - WidgetsBinding.instance!.removeObserver(this); | 51 | + WidgetsBinding.instance.removeObserver(this); |
| 52 | _videoListController.currentPlayer.pause(); | 52 | _videoListController.currentPlayer.pause(); |
| 53 | bus.cancel(); | 53 | bus.cancel(); |
| 54 | super.dispose(); | 54 | super.dispose(); |
| ... | @@ -57,16 +57,16 @@ class _PoemPageState extends State<PoemPage> with WidgetsBindingObserver { | ... | @@ -57,16 +57,16 @@ class _PoemPageState extends State<PoemPage> with WidgetsBindingObserver { |
| 57 | @override | 57 | @override |
| 58 | void initState() { | 58 | void initState() { |
| 59 | videoDataList = UserVideo.fetchVideo(); | 59 | videoDataList = UserVideo.fetchVideo(); |
| 60 | - WidgetsBinding.instance!.addObserver(this); | 60 | + WidgetsBinding.instance.addObserver(this); |
| 61 | _videoListController.init( | 61 | _videoListController.init( |
| 62 | pageController: _pageController, | 62 | pageController: _pageController, |
| 63 | initialList: videoDataList | 63 | initialList: videoDataList |
| 64 | .map( | 64 | .map( |
| 65 | (e) => VPVideoController( | 65 | (e) => VPVideoController( |
| 66 | - videoInfo: e, | 66 | + videoInfo: e, |
| 67 | - builder: () => VideoPlayerController.asset(e.url), | 67 | + builder: () => VideoPlayerController.asset(e.url), |
| 68 | - ), | 68 | + ), |
| 69 | - ) | 69 | + ) |
| 70 | .toList(), | 70 | .toList(), |
| 71 | videoProvider: (int index, List<VPVideoController> list) async { | 71 | videoProvider: (int index, List<VPVideoController> list) async { |
| 72 | return videoDataList | 72 | return videoDataList | ... | ... |
| ... | @@ -28,7 +28,7 @@ class LangSortBottomSheetState extends State<LangSortBottomSheet> | ... | @@ -28,7 +28,7 @@ class LangSortBottomSheetState extends State<LangSortBottomSheet> |
| 28 | @override | 28 | @override |
| 29 | void initState() { | 29 | void initState() { |
| 30 | super.initState(); | 30 | super.initState(); |
| 31 | - WidgetsBinding.instance!.addPostFrameCallback((_) { | 31 | + WidgetsBinding.instance.addPostFrameCallback((_) { |
| 32 | widget.provider.initData(); | 32 | widget.provider.initData(); |
| 33 | }); | 33 | }); |
| 34 | } | 34 | } | ... | ... |
| ... | @@ -54,7 +54,7 @@ class _AboutPageState extends State<AboutPage> { | ... | @@ -54,7 +54,7 @@ class _AboutPageState extends State<AboutPage> { |
| 54 | @override | 54 | @override |
| 55 | void initState() { | 55 | void initState() { |
| 56 | super.initState(); | 56 | super.initState(); |
| 57 | - WidgetsBinding.instance!.addPostFrameCallback((_) async { | 57 | + WidgetsBinding.instance.addPostFrameCallback((_) async { |
| 58 | // 2s定时器 | 58 | // 2s定时器 |
| 59 | _countdownTimer = Timer.periodic(const Duration(seconds: 2), (_) { | 59 | _countdownTimer = Timer.periodic(const Duration(seconds: 2), (_) { |
| 60 | // https://www.jianshu.com/p/e4106b829bff | 60 | // https://www.jianshu.com/p/e4106b829bff | ... | ... |
| 1 | import 'dart:math'; | 1 | import 'dart:math'; |
| 2 | +import 'package:Parlando/account/account_router.dart'; | ||
| 3 | +import 'package:Parlando/events/trans_event.dart'; | ||
| 4 | +import 'package:Parlando/home/provider/home_provider.dart'; | ||
| 5 | +import 'package:Parlando/poem/poem_router.dart'; | ||
| 6 | +import 'package:Parlando/routers/fluro_navigator.dart'; | ||
| 7 | +import 'package:animated_radial_menu/animated_radial_menu.dart'; | ||
| 2 | import 'package:flutter/material.dart'; | 8 | import 'package:flutter/material.dart'; |
| 3 | import 'package:flutter/rendering.dart'; | 9 | import 'package:flutter/rendering.dart'; |
| 4 | import 'package:Parlando/tiktok/style/style.dart'; | 10 | import 'package:Parlando/tiktok/style/style.dart'; |
| 11 | +import 'package:provider/provider.dart'; | ||
| 12 | +import 'package:flutter_gen/gen_l10n/Parlando_localizations.dart'; | ||
| 5 | 13 | ||
| 6 | const double scrollSpeed = 300; | 14 | const double scrollSpeed = 300; |
| 7 | 15 | ||
| ... | @@ -185,6 +193,82 @@ class _TikTokScaffoldState extends State<TikTokScaffold> | ... | @@ -185,6 +193,82 @@ class _TikTokScaffoldState extends State<TikTokScaffold> |
| 185 | body: body, | 193 | body: body, |
| 186 | backgroundColor: Colors.black, | 194 | backgroundColor: Colors.black, |
| 187 | resizeToAvoidBottomInset: false, | 195 | resizeToAvoidBottomInset: false, |
| 196 | + floatingActionButton: SizedBox( | ||
| 197 | + height: 60, | ||
| 198 | + child: RadialMenu( | ||
| 199 | + children: [ | ||
| 200 | + RadialButton( | ||
| 201 | + icon: const Icon(Icons.video_call_outlined), | ||
| 202 | + buttonColor: Colors.teal, | ||
| 203 | + onPress: () { | ||
| 204 | + eventBus.fire(TransEvent()); | ||
| 205 | + NavigatorUtils.push( | ||
| 206 | + context, | ||
| 207 | + '${PoemRouter.poemRecordVideoPage}?data=100', | ||
| 208 | + ); | ||
| 209 | + }), | ||
| 210 | + RadialButton( | ||
| 211 | + icon: const Icon(Icons.mic_none_outlined), | ||
| 212 | + buttonColor: Colors.green, | ||
| 213 | + onPress: () { | ||
| 214 | + eventBus.fire(TransEvent()); | ||
| 215 | + NavigatorUtils.push( | ||
| 216 | + context, | ||
| 217 | + '${PoemRouter.poemRecordAudioPage}?id=100', | ||
| 218 | + ); | ||
| 219 | + }), | ||
| 220 | + ], | ||
| 221 | + ), | ||
| 222 | + ), | ||
| 223 | + bottomNavigationBar: Consumer<HomeProvider>( | ||
| 224 | + builder: (_, provider, __) { | ||
| 225 | + return BottomAppBar( | ||
| 226 | + color: Colors.grey, | ||
| 227 | + child: Row( | ||
| 228 | + mainAxisSize: MainAxisSize.max, | ||
| 229 | + mainAxisAlignment: MainAxisAlignment.spaceAround, | ||
| 230 | + children: <Widget>[ | ||
| 231 | + InkWell( | ||
| 232 | + onTap: () {}, | ||
| 233 | + child: Container( | ||
| 234 | + alignment: Alignment.center, | ||
| 235 | + height: 36.0, | ||
| 236 | + child: Text( | ||
| 237 | + ParlandoLocalizations.of(context) | ||
| 238 | + .onePoemBottomNavigationBarItemTitle, | ||
| 239 | + style: const TextStyle( | ||
| 240 | + color: Colors.white54, | ||
| 241 | + fontSize: 15.0, | ||
| 242 | + ), | ||
| 243 | + ), | ||
| 244 | + ), | ||
| 245 | + ), | ||
| 246 | + InkWell( | ||
| 247 | + onTap: () { | ||
| 248 | + eventBus.fire(TransEvent()); | ||
| 249 | + NavigatorUtils.push( | ||
| 250 | + context, | ||
| 251 | + AccountRouter.accountPage, | ||
| 252 | + ); | ||
| 253 | + }, | ||
| 254 | + child: Container( | ||
| 255 | + alignment: Alignment.center, | ||
| 256 | + height: 36.0, | ||
| 257 | + child: Text( | ||
| 258 | + ParlandoLocalizations.of(context) | ||
| 259 | + .profileBottomNavigationBarItemTitle, | ||
| 260 | + style: const TextStyle( | ||
| 261 | + color: Colors.white54, | ||
| 262 | + fontSize: 15.0, | ||
| 263 | + ), | ||
| 264 | + ), | ||
| 265 | + ), | ||
| 266 | + ), | ||
| 267 | + ]), | ||
| 268 | + ); | ||
| 269 | + }, | ||
| 270 | + ), | ||
| 271 | + floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, | ||
| 188 | ), | 272 | ), |
| 189 | ); | 273 | ); |
| 190 | return body; | 274 | return body; |
| ... | @@ -344,6 +428,7 @@ class _MiddlePage extends StatelessWidget { | ... | @@ -344,6 +428,7 @@ class _MiddlePage extends StatelessWidget { |
| 344 | required this.tabBar, | 428 | required this.tabBar, |
| 345 | this.page, | 429 | this.page, |
| 346 | }) : super(key: key); | 430 | }) : super(key: key); |
| 431 | + | ||
| 347 | @override | 432 | @override |
| 348 | Widget build(BuildContext context) { | 433 | Widget build(BuildContext context) { |
| 349 | Widget mainVideoList = Container( | 434 | Widget mainVideoList = Container( |
| ... | @@ -440,6 +525,7 @@ class _LeftPageTransform extends StatelessWidget { | ... | @@ -440,6 +525,7 @@ class _LeftPageTransform extends StatelessWidget { |
| 440 | 525 | ||
| 441 | const _LeftPageTransform({Key? key, this.offsetX, this.content}) | 526 | const _LeftPageTransform({Key? key, this.offsetX, this.content}) |
| 442 | : super(key: key); | 527 | : super(key: key); |
| 528 | + | ||
| 443 | @override | 529 | @override |
| 444 | Widget build(BuildContext context) { | 530 | Widget build(BuildContext context) { |
| 445 | final screenWidth = MediaQuery.of(context).size.width; | 531 | final screenWidth = MediaQuery.of(context).size.width; | ... | ... |
| 1 | -import 'dart:math' as Math; | ||
| 2 | - | ||
| 3 | -import 'package:flutter/material.dart'; | ||
| 4 | - | ||
| 5 | -/// Draws an [ActionIcon] and [_ArcProgressPainter] that represent an active action. | ||
| 6 | -/// As the provided [Animation] progresses the ActionArc grows into a full | ||
| 7 | -/// circle and the ActionIcon moves along it. | ||
| 8 | -class ArcProgressIndicator extends StatelessWidget { | ||
| 9 | - // required | ||
| 10 | - final Animation<double> controller; | ||
| 11 | - final double radius; | ||
| 12 | - | ||
| 13 | - // optional | ||
| 14 | - final double startAngle; | ||
| 15 | - final double? width; | ||
| 16 | - | ||
| 17 | - /// The color to use when filling the arc. | ||
| 18 | - /// | ||
| 19 | - /// Defaults to the accent color of the current theme. | ||
| 20 | - final Color? color; | ||
| 21 | - final IconData icon; | ||
| 22 | - final Color? iconColor; | ||
| 23 | - final double? iconSize; | ||
| 24 | - | ||
| 25 | - // private | ||
| 26 | - final Animation<double> _progress; | ||
| 27 | - | ||
| 28 | - ArcProgressIndicator({ | ||
| 29 | - Key? key, | ||
| 30 | - required this.controller, | ||
| 31 | - required this.radius, | ||
| 32 | - this.startAngle = 0.0, | ||
| 33 | - this.width, | ||
| 34 | - this.color, | ||
| 35 | - required this.icon, | ||
| 36 | - this.iconColor, | ||
| 37 | - this.iconSize, | ||
| 38 | - }) : _progress = Tween(begin: 0.0, end: 1.0).animate(controller), | ||
| 39 | - super(key: key); | ||
| 40 | - | ||
| 41 | - @override | ||
| 42 | - Widget build(BuildContext context) { | ||
| 43 | - late TextPainter _iconPainter; | ||
| 44 | - final ThemeData theme = Theme.of(context); | ||
| 45 | - final Color? _iconColor = iconColor ?? theme.colorScheme.secondary; | ||
| 46 | - final double? _iconSize = iconSize ?? IconTheme.of(context).size; | ||
| 47 | - | ||
| 48 | - _iconPainter = TextPainter( | ||
| 49 | - textDirection: Directionality.of(context), | ||
| 50 | - text: TextSpan( | ||
| 51 | - text: String.fromCharCode(icon.codePoint), | ||
| 52 | - style: TextStyle( | ||
| 53 | - inherit: false, | ||
| 54 | - color: _iconColor, | ||
| 55 | - fontSize: _iconSize, | ||
| 56 | - fontFamily: icon.fontFamily, | ||
| 57 | - package: icon.fontPackage, | ||
| 58 | - ), | ||
| 59 | - ), | ||
| 60 | - )..layout(); | ||
| 61 | - | ||
| 62 | - return CustomPaint( | ||
| 63 | - painter: _ArcProgressPainter( | ||
| 64 | - controller: _progress, | ||
| 65 | - color: color ?? theme.colorScheme.secondary, | ||
| 66 | - radius: radius, | ||
| 67 | - width: width ?? _iconSize! * 2, | ||
| 68 | - startAngle: startAngle, | ||
| 69 | - icon: _iconPainter, | ||
| 70 | - ), | ||
| 71 | - ); | ||
| 72 | - } | ||
| 73 | -} | ||
| 74 | - | ||
| 75 | -class _ArcProgressPainter extends CustomPainter { | ||
| 76 | - // required | ||
| 77 | - final Animation<double> controller; | ||
| 78 | - final Color color; | ||
| 79 | - final double radius; | ||
| 80 | - final double width; | ||
| 81 | - | ||
| 82 | - // optional | ||
| 83 | - final double startAngle; | ||
| 84 | - final TextPainter icon; | ||
| 85 | - | ||
| 86 | - _ArcProgressPainter({ | ||
| 87 | - required this.controller, | ||
| 88 | - required this.color, | ||
| 89 | - required this.radius, | ||
| 90 | - required this.width, | ||
| 91 | - this.startAngle = 0.0, | ||
| 92 | - required this.icon, | ||
| 93 | - }) : super(repaint: controller); | ||
| 94 | - | ||
| 95 | - @override | ||
| 96 | - void paint(Canvas canvas, Size size) { | ||
| 97 | - Paint paint = Paint() | ||
| 98 | - ..color = color | ||
| 99 | - ..strokeWidth = width | ||
| 100 | - ..strokeCap = StrokeCap.round | ||
| 101 | - ..style = PaintingStyle.stroke; | ||
| 102 | - | ||
| 103 | - final double sweepAngle = controller.value * 2 * Math.pi; | ||
| 104 | - | ||
| 105 | - canvas.drawArc( | ||
| 106 | - Offset.zero & size, | ||
| 107 | - startAngle, | ||
| 108 | - sweepAngle, | ||
| 109 | - false, | ||
| 110 | - paint, | ||
| 111 | - ); | ||
| 112 | - | ||
| 113 | - double angle = startAngle + sweepAngle; | ||
| 114 | - Offset offset = Offset( | ||
| 115 | - (size.width / 2 - icon.size.width / 2) + radius * Math.cos(angle), | ||
| 116 | - (size.height / 2 - icon.size.height / 2) + radius * Math.sin(angle), | ||
| 117 | - ); | ||
| 118 | - | ||
| 119 | - icon.paint(canvas, offset); | ||
| 120 | - } | ||
| 121 | - | ||
| 122 | - @override | ||
| 123 | - bool shouldRepaint(_ArcProgressPainter other) { | ||
| 124 | - return controller.value != other.controller.value || | ||
| 125 | - color != other.color || | ||
| 126 | - radius != other.radius || | ||
| 127 | - width != other.width || | ||
| 128 | - startAngle != other.startAngle || | ||
| 129 | - icon != other.icon; | ||
| 130 | - } | ||
| 131 | -} |
| 1 | -import 'dart:async'; | ||
| 2 | -import 'dart:math' as math; | ||
| 3 | - | ||
| 4 | -import 'package:flutter/material.dart'; | ||
| 5 | -import 'package:Parlando/widgets/radial/src/radial_menu_button.dart'; | ||
| 6 | -import 'package:Parlando/widgets/radial/src/radial_menu_center_button.dart'; | ||
| 7 | -import 'package:Parlando/widgets/radial/src/radial_menu_item.dart'; | ||
| 8 | - | ||
| 9 | -const double _radiansPerDegree = math.pi / 180; | ||
| 10 | -const double _startAngle = -120.0 * _radiansPerDegree; | ||
| 11 | - | ||
| 12 | -typedef ItemAngleCalculator = double Function(int index); | ||
| 13 | - | ||
| 14 | -/// A radial menu for selecting from a list of items. | ||
| 15 | -/// | ||
| 16 | -/// A radial menu lets the user select from a number of items. It displays a | ||
| 17 | -/// button that opens the menu, showing its items arranged in an arc. Selecting | ||
| 18 | -/// an item triggers the animation of a progress bar drawn at the specified | ||
| 19 | -/// [radius] around the central menu button. | ||
| 20 | -/// | ||
| 21 | -/// The type `T` is the type of the values the radial menu represents. All the | ||
| 22 | -/// entries in a given menu must represent values with consistent types. | ||
| 23 | -/// Typically, an enum is used. Each [RadialMenuItem] in [items] must be | ||
| 24 | -/// specialized with that same type argument. | ||
| 25 | -/// | ||
| 26 | -/// Requires one of its ancestors to be a [Material] widget. | ||
| 27 | -/// | ||
| 28 | -/// See also: | ||
| 29 | -/// | ||
| 30 | -/// * [RadialMenuItem], the widget used to represent the [items]. | ||
| 31 | -/// * [RadialMenuCenterButton], the button used to open and close the menu. | ||
| 32 | -class RadialMenu<T> extends StatefulWidget { | ||
| 33 | - /// Creates a dropdown button. | ||
| 34 | - /// | ||
| 35 | - /// The [items] must have distinct values. | ||
| 36 | - /// | ||
| 37 | - /// The [radius], [menuAnimationDuration], and [progressAnimationDuration] | ||
| 38 | - /// arguments must not be null (they all have defaults, so do not need to be | ||
| 39 | - /// specified). | ||
| 40 | - const RadialMenu({ | ||
| 41 | - Key? key, | ||
| 42 | - required this.items, | ||
| 43 | - required this.onSelected, | ||
| 44 | - this.radius = 100.0, | ||
| 45 | - this.menuAnimationDuration = const Duration(milliseconds: 1000), | ||
| 46 | - this.progressAnimationDuration = const Duration(milliseconds: 1000), | ||
| 47 | - }) : super(key: key); | ||
| 48 | - | ||
| 49 | - /// The list of possible items to select among. | ||
| 50 | - final List<RadialMenuItem<T>> items; | ||
| 51 | - | ||
| 52 | - /// Called when the user selects an item. | ||
| 53 | - final Function onSelected; // TODO why Function? not ValueChanged? | ||
| 54 | - | ||
| 55 | - /// The radius of the arc used to lay out the items and draw the progress bar. | ||
| 56 | - /// | ||
| 57 | - /// Defaults to 100.0. | ||
| 58 | - final double radius; | ||
| 59 | - | ||
| 60 | - /// Duration of the menu opening/closing animation. | ||
| 61 | - /// | ||
| 62 | - /// Defaults to 1000 milliseconds. | ||
| 63 | - final Duration menuAnimationDuration; | ||
| 64 | - | ||
| 65 | - /// Duration of the action activation progress arc animation. | ||
| 66 | - /// | ||
| 67 | - /// Defaults to 1000 milliseconds. | ||
| 68 | - final Duration progressAnimationDuration; | ||
| 69 | - | ||
| 70 | - @override | ||
| 71 | - RadialMenuState createState() => RadialMenuState(); | ||
| 72 | -} | ||
| 73 | - | ||
| 74 | -class RadialMenuState extends State<RadialMenu> with TickerProviderStateMixin { | ||
| 75 | - late AnimationController _menuAnimationController; | ||
| 76 | - late AnimationController _progressAnimationController; | ||
| 77 | - bool _isOpen = false; | ||
| 78 | - int _activeItemIndex = -1; | ||
| 79 | - | ||
| 80 | - // todo: xqwzts: allow users to pass in their own calculator as a param. | ||
| 81 | - // and change this to the default: radialItemAngleCalculator. | ||
| 82 | - double calculateItemAngle(int index) { | ||
| 83 | - double _itemSpacing = 120.0 / widget.items.length; | ||
| 84 | - return _startAngle + index * _itemSpacing * _radiansPerDegree; | ||
| 85 | - } | ||
| 86 | - | ||
| 87 | - @override | ||
| 88 | - void initState() { | ||
| 89 | - super.initState(); | ||
| 90 | - _menuAnimationController = AnimationController( | ||
| 91 | - duration: widget.menuAnimationDuration, | ||
| 92 | - vsync: this, | ||
| 93 | - ); | ||
| 94 | - _progressAnimationController = AnimationController( | ||
| 95 | - duration: widget.progressAnimationDuration, | ||
| 96 | - vsync: this, | ||
| 97 | - ); | ||
| 98 | - } | ||
| 99 | - | ||
| 100 | - @override | ||
| 101 | - void dispose() { | ||
| 102 | - _menuAnimationController.dispose(); | ||
| 103 | - _progressAnimationController.dispose(); | ||
| 104 | - super.dispose(); | ||
| 105 | - } | ||
| 106 | - | ||
| 107 | - void _openMenu() { | ||
| 108 | - _menuAnimationController.forward(); | ||
| 109 | - setState(() => _isOpen = true); | ||
| 110 | - } | ||
| 111 | - | ||
| 112 | - void _closeMenu() { | ||
| 113 | - _menuAnimationController.reverse(); | ||
| 114 | - setState(() => _isOpen = false); | ||
| 115 | - } | ||
| 116 | - | ||
| 117 | - Future<void> _activate(int itemIndex) async { | ||
| 118 | - setState(() => _activeItemIndex = itemIndex); | ||
| 119 | - await _progressAnimationController.forward().orCancel; | ||
| 120 | - widget.onSelected(widget.items[itemIndex].value); | ||
| 121 | - _closeMenu(); | ||
| 122 | - } | ||
| 123 | - | ||
| 124 | - /// Resets the menu to its initial (closed) state. | ||
| 125 | - void reset() { | ||
| 126 | - _menuAnimationController.reset(); | ||
| 127 | - _progressAnimationController.reverse(); | ||
| 128 | - setState(() { | ||
| 129 | - _isOpen = false; | ||
| 130 | - _activeItemIndex = -1; | ||
| 131 | - }); | ||
| 132 | - } | ||
| 133 | - | ||
| 134 | - Widget _buildActionButton(int index) { | ||
| 135 | - final RadialMenuItem item = widget.items[index]; | ||
| 136 | - | ||
| 137 | - return LayoutId( | ||
| 138 | - id: '${_RadialMenuLayout.actionButton}$index', | ||
| 139 | - child: RadialMenuButton( | ||
| 140 | - child: item, | ||
| 141 | - backgroundColor: item.backgroundColor, | ||
| 142 | - onPressed: () => _activate(index), | ||
| 143 | - ), | ||
| 144 | - ); | ||
| 145 | - } | ||
| 146 | - | ||
| 147 | - Widget _buildCenterButton() { | ||
| 148 | - return LayoutId( | ||
| 149 | - id: _RadialMenuLayout.menuButton, | ||
| 150 | - child: RadialMenuCenterButton( | ||
| 151 | - openCloseAnimationController: _menuAnimationController.view, | ||
| 152 | - activateAnimationController: _progressAnimationController.view, | ||
| 153 | - isOpen: _isOpen, | ||
| 154 | - onPressed: _isOpen ? _closeMenu : _openMenu, | ||
| 155 | - ), | ||
| 156 | - ); | ||
| 157 | - } | ||
| 158 | - | ||
| 159 | - @override | ||
| 160 | - Widget build(BuildContext context) { | ||
| 161 | - final List<Widget> children = <Widget>[]; | ||
| 162 | - for (int i = 0; i < widget.items.length; i++) { | ||
| 163 | - if (_activeItemIndex != i) { | ||
| 164 | - children.add(_buildActionButton(i)); | ||
| 165 | - } | ||
| 166 | - } | ||
| 167 | - children.add(_buildCenterButton()); | ||
| 168 | - | ||
| 169 | - return AnimatedBuilder( | ||
| 170 | - animation: _menuAnimationController, | ||
| 171 | - builder: (BuildContext context, Widget? child) { | ||
| 172 | - return CustomMultiChildLayout( | ||
| 173 | - delegate: _RadialMenuLayout( | ||
| 174 | - itemCount: widget.items.length, | ||
| 175 | - radius: widget.radius, | ||
| 176 | - calculateItemAngle: calculateItemAngle, | ||
| 177 | - controller: _menuAnimationController.view, | ||
| 178 | - ), | ||
| 179 | - children: children, | ||
| 180 | - ); | ||
| 181 | - }, | ||
| 182 | - ); | ||
| 183 | - } | ||
| 184 | -} | ||
| 185 | - | ||
| 186 | -class _RadialMenuLayout extends MultiChildLayoutDelegate { | ||
| 187 | - static const String menuButton = 'menuButton'; | ||
| 188 | - static const String actionButton = 'actionButton'; | ||
| 189 | - static const String activeAction = 'activeAction'; | ||
| 190 | - | ||
| 191 | - final int itemCount; | ||
| 192 | - final double radius; | ||
| 193 | - final ItemAngleCalculator calculateItemAngle; | ||
| 194 | - | ||
| 195 | - final Animation<double> controller; | ||
| 196 | - | ||
| 197 | - final Animation<double> _progress; | ||
| 198 | - | ||
| 199 | - _RadialMenuLayout({ | ||
| 200 | - required this.itemCount, | ||
| 201 | - required this.radius, | ||
| 202 | - required this.calculateItemAngle, | ||
| 203 | - required this.controller, | ||
| 204 | - }) : _progress = Tween<double>(begin: 0.0, end: radius).animate( | ||
| 205 | - CurvedAnimation( | ||
| 206 | - curve: Curves.elasticOut, | ||
| 207 | - parent: controller, | ||
| 208 | - ), | ||
| 209 | - ); | ||
| 210 | - | ||
| 211 | - late Offset center; | ||
| 212 | - | ||
| 213 | - @override | ||
| 214 | - void performLayout(Size size) { | ||
| 215 | - center = Offset(size.width / 2, size.height / 2); | ||
| 216 | - | ||
| 217 | - if (hasChild(menuButton)) { | ||
| 218 | - Size menuButtonSize; | ||
| 219 | - menuButtonSize = layoutChild(menuButton, BoxConstraints.loose(size)); | ||
| 220 | - | ||
| 221 | - // place the menubutton in the center | ||
| 222 | - positionChild( | ||
| 223 | - menuButton, | ||
| 224 | - Offset( | ||
| 225 | - center.dx - menuButtonSize.width / 2, | ||
| 226 | - center.dy - menuButtonSize.height / 2, | ||
| 227 | - ), | ||
| 228 | - ); | ||
| 229 | - } | ||
| 230 | - | ||
| 231 | - for (int i = 0; i < itemCount; i++) { | ||
| 232 | - final String actionButtonId = '$actionButton$i'; | ||
| 233 | - final String actionArcId = '$activeAction$i'; | ||
| 234 | - if (hasChild(actionArcId)) { | ||
| 235 | - final Size arcSize = layoutChild( | ||
| 236 | - actionArcId, | ||
| 237 | - BoxConstraints.expand( | ||
| 238 | - width: _progress.value * 2, | ||
| 239 | - height: _progress.value * 2, | ||
| 240 | - ), | ||
| 241 | - ); | ||
| 242 | - | ||
| 243 | - positionChild( | ||
| 244 | - actionArcId, | ||
| 245 | - Offset( | ||
| 246 | - center.dx - arcSize.width / 2, | ||
| 247 | - center.dy - arcSize.height / 2, | ||
| 248 | - ), | ||
| 249 | - ); | ||
| 250 | - } | ||
| 251 | - | ||
| 252 | - if (hasChild(actionButtonId)) { | ||
| 253 | - final Size buttonSize = | ||
| 254 | - layoutChild(actionButtonId, BoxConstraints.loose(size)); | ||
| 255 | - | ||
| 256 | - final double itemAngle = calculateItemAngle(i); | ||
| 257 | - | ||
| 258 | - positionChild( | ||
| 259 | - actionButtonId, | ||
| 260 | - Offset( | ||
| 261 | - (center.dx - buttonSize.width / 2) + | ||
| 262 | - (_progress.value) * math.cos(itemAngle), | ||
| 263 | - (center.dy - buttonSize.height / 2) + | ||
| 264 | - (_progress.value) * math.sin(itemAngle), | ||
| 265 | - ), | ||
| 266 | - ); | ||
| 267 | - } | ||
| 268 | - } | ||
| 269 | - } | ||
| 270 | - | ||
| 271 | - @override | ||
| 272 | - bool shouldRelayout(_RadialMenuLayout oldDelegate) => | ||
| 273 | - itemCount != oldDelegate.itemCount || | ||
| 274 | - radius != oldDelegate.radius || | ||
| 275 | - calculateItemAngle != oldDelegate.calculateItemAngle || | ||
| 276 | - controller != oldDelegate.controller || | ||
| 277 | - _progress != oldDelegate._progress; | ||
| 278 | -} |
| 1 | -import 'package:flutter/foundation.dart'; | ||
| 2 | -import 'package:flutter/material.dart'; | ||
| 3 | - | ||
| 4 | -class RadialMenuButton extends StatelessWidget { | ||
| 5 | - const RadialMenuButton({ | ||
| 6 | - Key? key, | ||
| 7 | - required this.child, | ||
| 8 | - required this.backgroundColor, | ||
| 9 | - required this.onPressed, | ||
| 10 | - }) : super(key: key); | ||
| 11 | - | ||
| 12 | - final Widget child; | ||
| 13 | - final Color backgroundColor; | ||
| 14 | - final VoidCallback onPressed; | ||
| 15 | - | ||
| 16 | - @override | ||
| 17 | - Widget build(BuildContext context) { | ||
| 18 | - final Color color = backgroundColor; | ||
| 19 | - | ||
| 20 | - return Semantics( | ||
| 21 | - button: true, | ||
| 22 | - enabled: true, | ||
| 23 | - child: Material( | ||
| 24 | - type: MaterialType.circle, | ||
| 25 | - color: color, | ||
| 26 | - child: InkWell( | ||
| 27 | - onTap: onPressed, | ||
| 28 | - child: child, | ||
| 29 | - ), | ||
| 30 | - ), | ||
| 31 | - ); | ||
| 32 | - } | ||
| 33 | -} |
| 1 | -import 'package:flutter/foundation.dart'; | ||
| 2 | -import 'package:flutter/material.dart'; | ||
| 3 | -import 'package:Parlando/widgets/radial/src/radial_menu_button.dart'; | ||
| 4 | - | ||
| 5 | -const double _defaultButtonSize = 48.0; | ||
| 6 | - | ||
| 7 | -/// The button at the center of a [RadialMenu] which controls its open/closed | ||
| 8 | -/// state. | ||
| 9 | -class RadialMenuCenterButton extends StatelessWidget { | ||
| 10 | - /// Drives the opening/closing animation of the [RadialMenu]. | ||
| 11 | - final Animation<double> openCloseAnimationController; | ||
| 12 | - | ||
| 13 | - /// Drives the animation when an item in the [RadialMenu] is pressed. | ||
| 14 | - final Animation<double> activateAnimationController; | ||
| 15 | - | ||
| 16 | - /// Called when the user presses this button. | ||
| 17 | - final VoidCallback onPressed; | ||
| 18 | - | ||
| 19 | - /// The opened/closed state of the menu. | ||
| 20 | - /// | ||
| 21 | - /// Determines which of [closedColor] or [openedColor] should be used as the | ||
| 22 | - /// background color of the button. | ||
| 23 | - final bool isOpen; | ||
| 24 | - | ||
| 25 | - /// The color to use when painting the icon. | ||
| 26 | - /// | ||
| 27 | - /// Defaults to [Colors.black]. | ||
| 28 | - final Color iconColor; | ||
| 29 | - | ||
| 30 | - /// Background color when it is in its closed state. | ||
| 31 | - /// | ||
| 32 | - /// Defaults to [Colors.white]. | ||
| 33 | - final Color closedColor; | ||
| 34 | - | ||
| 35 | - /// Background color when it is in its opened state. | ||
| 36 | - /// | ||
| 37 | - /// Defaults to [Colors.grey]. | ||
| 38 | - final Color openedColor; | ||
| 39 | - | ||
| 40 | - /// The size of the button. | ||
| 41 | - /// | ||
| 42 | - /// Defaults to 48.0. | ||
| 43 | - final double size; | ||
| 44 | - | ||
| 45 | - /// The animation progress for the [AnimatedIcon] in the center of the button. | ||
| 46 | - final Animation<double> _progress; | ||
| 47 | - | ||
| 48 | - /// The scale factor applied to the button. | ||
| 49 | - /// | ||
| 50 | - /// Animates from 1.0 to 0.0 when an an item is pressed in the menu and | ||
| 51 | - /// [activateAnimationController] progresses. | ||
| 52 | - final Animation<double> _scale; | ||
| 53 | - | ||
| 54 | - RadialMenuCenterButton({ | ||
| 55 | - Key? key, | ||
| 56 | - required this.openCloseAnimationController, | ||
| 57 | - required this.activateAnimationController, | ||
| 58 | - required this.onPressed, | ||
| 59 | - required this.isOpen, | ||
| 60 | - this.iconColor = Colors.black, | ||
| 61 | - this.closedColor = Colors.white, | ||
| 62 | - this.openedColor = Colors.grey, | ||
| 63 | - this.size = _defaultButtonSize, | ||
| 64 | - }) : _progress = Tween(begin: 0.0, end: 1.0).animate( | ||
| 65 | - CurvedAnimation( | ||
| 66 | - parent: openCloseAnimationController, | ||
| 67 | - curve: const Interval( | ||
| 68 | - 0.0, | ||
| 69 | - 0.5, | ||
| 70 | - curve: Curves.ease, | ||
| 71 | - ), | ||
| 72 | - ), | ||
| 73 | - ), | ||
| 74 | - _scale = Tween(begin: 1.0, end: 0.0).animate( | ||
| 75 | - CurvedAnimation( | ||
| 76 | - parent: activateAnimationController, | ||
| 77 | - curve: Curves.elasticIn, | ||
| 78 | - ), | ||
| 79 | - ), | ||
| 80 | - super(key: key); | ||
| 81 | - | ||
| 82 | - @override | ||
| 83 | - Widget build(BuildContext context) { | ||
| 84 | - final AnimatedIcon animatedIcon = AnimatedIcon( | ||
| 85 | - color: iconColor, | ||
| 86 | - icon: AnimatedIcons.menu_close, | ||
| 87 | - progress: _progress, | ||
| 88 | - ); | ||
| 89 | - | ||
| 90 | - final Widget child = SizedBox( | ||
| 91 | - width: size, | ||
| 92 | - height: size, | ||
| 93 | - child: Center( | ||
| 94 | - child: animatedIcon, | ||
| 95 | - ), | ||
| 96 | - ); | ||
| 97 | - | ||
| 98 | - final Color color = isOpen ? openedColor : closedColor; | ||
| 99 | - | ||
| 100 | - return ScaleTransition( | ||
| 101 | - scale: _scale, | ||
| 102 | - child: RadialMenuButton( | ||
| 103 | - child: child, | ||
| 104 | - backgroundColor: color, | ||
| 105 | - onPressed: onPressed, | ||
| 106 | - ), | ||
| 107 | - ); | ||
| 108 | - } | ||
| 109 | -} |
| 1 | -import 'package:flutter/foundation.dart'; | ||
| 2 | -import 'package:flutter/material.dart'; | ||
| 3 | - | ||
| 4 | -const double _defaultButtonSize = 48.0; | ||
| 5 | - | ||
| 6 | -/// An item in a [RadialMenu]. | ||
| 7 | -/// | ||
| 8 | -/// The type `T` is the type of the value the entry represents. All the entries | ||
| 9 | -/// in a given menu must represent values with consistent types. | ||
| 10 | -class RadialMenuItem<T> extends StatelessWidget { | ||
| 11 | - /// Creates a circular action button for an item in a [RadialMenu]. | ||
| 12 | - /// | ||
| 13 | - /// The [child] argument is required. | ||
| 14 | - const RadialMenuItem({ | ||
| 15 | - Key? key, | ||
| 16 | - required this.child, | ||
| 17 | - required this.value, | ||
| 18 | - required this.tooltip, | ||
| 19 | - this.size = _defaultButtonSize, | ||
| 20 | - required this.backgroundColor, | ||
| 21 | - required this.iconColor, | ||
| 22 | - this.iconSize = 24.0, | ||
| 23 | - }) : super(key: key); | ||
| 24 | - | ||
| 25 | - /// The widget below this widget in the tree. | ||
| 26 | - /// | ||
| 27 | - /// Typically an [Icon] widget. | ||
| 28 | - final Widget child; | ||
| 29 | - | ||
| 30 | - /// The value to return if the user selects this menu item. | ||
| 31 | - /// | ||
| 32 | - /// Eventually returned in a call to [RadialMenu.onSelected]. | ||
| 33 | - final T value; | ||
| 34 | - | ||
| 35 | - /// Text that describes the action that will occur when the button is pressed. | ||
| 36 | - /// | ||
| 37 | - /// This text is displayed when the user long-presses on the button and is | ||
| 38 | - /// used for accessibility. | ||
| 39 | - final String tooltip; | ||
| 40 | - | ||
| 41 | - /// The color to use when filling the button. | ||
| 42 | - /// | ||
| 43 | - /// Defaults to the primary color of the current theme. | ||
| 44 | - final Color backgroundColor; | ||
| 45 | - | ||
| 46 | - /// The size of the button. | ||
| 47 | - /// | ||
| 48 | - /// Defaults to 48.0. | ||
| 49 | - final double size; | ||
| 50 | - | ||
| 51 | - /// The color to use when painting the child icon. | ||
| 52 | - /// | ||
| 53 | - /// Defaults to the primary icon theme color. | ||
| 54 | - final Color? iconColor; | ||
| 55 | - | ||
| 56 | - final double? iconSize; | ||
| 57 | - | ||
| 58 | - @override | ||
| 59 | - Widget build(BuildContext context) { | ||
| 60 | - final Color? _iconColor = | ||
| 61 | - iconColor ?? Theme.of(context).primaryIconTheme.color; | ||
| 62 | - | ||
| 63 | - late Widget result; | ||
| 64 | - | ||
| 65 | - result = Center( | ||
| 66 | - child: IconTheme.merge( | ||
| 67 | - data: IconThemeData( | ||
| 68 | - color: _iconColor, | ||
| 69 | - size: iconSize, | ||
| 70 | - ), | ||
| 71 | - child: child, | ||
| 72 | - ), | ||
| 73 | - ); | ||
| 74 | - | ||
| 75 | - result = Tooltip( | ||
| 76 | - message: tooltip, | ||
| 77 | - child: result, | ||
| 78 | - ); | ||
| 79 | - | ||
| 80 | - result = SizedBox( | ||
| 81 | - width: size, | ||
| 82 | - height: size, | ||
| 83 | - child: result, | ||
| 84 | - ); | ||
| 85 | - | ||
| 86 | - return result; | ||
| 87 | - } | ||
| 88 | -} |
| ... | @@ -107,7 +107,7 @@ class _SearchBarState extends State<SearchBar> { | ... | @@ -107,7 +107,7 @@ class _SearchBarState extends State<SearchBar> { |
| 107 | ), | 107 | ), |
| 108 | onTap: () { | 108 | onTap: () { |
| 109 | /// https://github.com/flutter/flutter/issues/35848 | 109 | /// https://github.com/flutter/flutter/issues/35848 |
| 110 | - SchedulerBinding.instance!.addPostFrameCallback((_) { | 110 | + SchedulerBinding.instance.addPostFrameCallback((_) { |
| 111 | _controller.text = ''; | 111 | _controller.text = ''; |
| 112 | }); | 112 | }); |
| 113 | }, | 113 | }, | ... | ... |
| ... | @@ -15,13 +15,20 @@ packages: | ... | @@ -15,13 +15,20 @@ packages: |
| 15 | url: "https://pub.flutter-io.cn" | 15 | url: "https://pub.flutter-io.cn" |
| 16 | source: hosted | 16 | source: hosted |
| 17 | version: "2.8.0" | 17 | version: "2.8.0" |
| 18 | + animated_radial_menu: | ||
| 19 | + dependency: "direct main" | ||
| 20 | + description: | ||
| 21 | + name: animated_radial_menu | ||
| 22 | + url: "https://pub.flutter-io.cn" | ||
| 23 | + source: hosted | ||
| 24 | + version: "0.0.1" | ||
| 18 | archive: | 25 | archive: |
| 19 | dependency: transitive | 26 | dependency: transitive |
| 20 | description: | 27 | description: |
| 21 | name: archive | 28 | name: archive |
| 22 | url: "https://pub.flutter-io.cn" | 29 | url: "https://pub.flutter-io.cn" |
| 23 | source: hosted | 30 | source: hosted |
| 24 | - version: "3.1.6" | 31 | + version: "3.1.11" |
| 25 | args: | 32 | args: |
| 26 | dependency: transitive | 33 | dependency: transitive |
| 27 | description: | 34 | description: |
| ... | @@ -189,7 +196,7 @@ packages: | ... | @@ -189,7 +196,7 @@ packages: |
| 189 | name: collection | 196 | name: collection |
| 190 | url: "https://pub.flutter-io.cn" | 197 | url: "https://pub.flutter-io.cn" |
| 191 | source: hosted | 198 | source: hosted |
| 192 | - version: "1.15.0" | 199 | + version: "1.16.0" |
| 193 | common_utils: | 200 | common_utils: |
| 194 | dependency: "direct main" | 201 | dependency: "direct main" |
| 195 | description: | 202 | description: |
| ... | @@ -210,7 +217,7 @@ packages: | ... | @@ -210,7 +217,7 @@ packages: |
| 210 | name: coverage | 217 | name: coverage |
| 211 | url: "https://pub.flutter-io.cn" | 218 | url: "https://pub.flutter-io.cn" |
| 212 | source: hosted | 219 | source: hosted |
| 213 | - version: "1.0.3" | 220 | + version: "1.2.0" |
| 214 | cross_file: | 221 | cross_file: |
| 215 | dependency: transitive | 222 | dependency: transitive |
| 216 | description: | 223 | description: |
| ... | @@ -322,7 +329,7 @@ packages: | ... | @@ -322,7 +329,7 @@ packages: |
| 322 | name: fake_async | 329 | name: fake_async |
| 323 | url: "https://pub.flutter-io.cn" | 330 | url: "https://pub.flutter-io.cn" |
| 324 | source: hosted | 331 | source: hosted |
| 325 | - version: "1.2.0" | 332 | + version: "1.3.0" |
| 326 | ffi: | 333 | ffi: |
| 327 | dependency: transitive | 334 | dependency: transitive |
| 328 | description: | 335 | description: |
| ... | @@ -411,7 +418,7 @@ packages: | ... | @@ -411,7 +418,7 @@ packages: |
| 411 | name: flutter_lints | 418 | name: flutter_lints |
| 412 | url: "https://pub.flutter-io.cn" | 419 | url: "https://pub.flutter-io.cn" |
| 413 | source: hosted | 420 | source: hosted |
| 414 | - version: "1.0.4" | 421 | + version: "2.0.1" |
| 415 | flutter_localizations: | 422 | flutter_localizations: |
| 416 | dependency: "direct main" | 423 | dependency: "direct main" |
| 417 | description: flutter | 424 | description: flutter |
| ... | @@ -483,6 +490,13 @@ packages: | ... | @@ -483,6 +490,13 @@ packages: |
| 483 | description: flutter | 490 | description: flutter |
| 484 | source: sdk | 491 | source: sdk |
| 485 | version: "0.0.0" | 492 | version: "0.0.0" |
| 493 | + font_awesome_flutter: | ||
| 494 | + dependency: transitive | ||
| 495 | + description: | ||
| 496 | + name: font_awesome_flutter | ||
| 497 | + url: "https://pub.flutter-io.cn" | ||
| 498 | + source: hosted | ||
| 499 | + version: "9.2.0" | ||
| 486 | frontend_server_client: | 500 | frontend_server_client: |
| 487 | dependency: transitive | 501 | dependency: transitive |
| 488 | description: | 502 | description: |
| ... | @@ -632,7 +646,7 @@ packages: | ... | @@ -632,7 +646,7 @@ packages: |
| 632 | name: js | 646 | name: js |
| 633 | url: "https://pub.flutter-io.cn" | 647 | url: "https://pub.flutter-io.cn" |
| 634 | source: hosted | 648 | source: hosted |
| 635 | - version: "0.6.3" | 649 | + version: "0.6.4" |
| 636 | json_annotation: | 650 | json_annotation: |
| 637 | dependency: "direct main" | 651 | dependency: "direct main" |
| 638 | description: | 652 | description: |
| ... | @@ -653,7 +667,7 @@ packages: | ... | @@ -653,7 +667,7 @@ packages: |
| 653 | name: keyboard_actions | 667 | name: keyboard_actions |
| 654 | url: "https://pub.flutter-io.cn" | 668 | url: "https://pub.flutter-io.cn" |
| 655 | source: hosted | 669 | source: hosted |
| 656 | - version: "3.4.7" | 670 | + version: "4.0.0" |
| 657 | lint: | 671 | lint: |
| 658 | dependency: transitive | 672 | dependency: transitive |
| 659 | description: | 673 | description: |
| ... | @@ -667,7 +681,7 @@ packages: | ... | @@ -667,7 +681,7 @@ packages: |
| 667 | name: lints | 681 | name: lints |
| 668 | url: "https://pub.flutter-io.cn" | 682 | url: "https://pub.flutter-io.cn" |
| 669 | source: hosted | 683 | source: hosted |
| 670 | - version: "1.0.1" | 684 | + version: "2.0.0" |
| 671 | logger: | 685 | logger: |
| 672 | dependency: transitive | 686 | dependency: transitive |
| 673 | description: | 687 | description: |
| ... | @@ -695,7 +709,7 @@ packages: | ... | @@ -695,7 +709,7 @@ packages: |
| 695 | name: material_color_utilities | 709 | name: material_color_utilities |
| 696 | url: "https://pub.flutter-io.cn" | 710 | url: "https://pub.flutter-io.cn" |
| 697 | source: hosted | 711 | source: hosted |
| 698 | - version: "0.1.3" | 712 | + version: "0.1.4" |
| 699 | meta: | 713 | meta: |
| 700 | dependency: transitive | 714 | dependency: transitive |
| 701 | description: | 715 | description: |
| ... | @@ -751,7 +765,7 @@ packages: | ... | @@ -751,7 +765,7 @@ packages: |
| 751 | name: path | 765 | name: path |
| 752 | url: "https://pub.flutter-io.cn" | 766 | url: "https://pub.flutter-io.cn" |
| 753 | source: hosted | 767 | source: hosted |
| 754 | - version: "1.8.0" | 768 | + version: "1.8.1" |
| 755 | path_provider: | 769 | path_provider: |
| 756 | dependency: "direct main" | 770 | dependency: "direct main" |
| 757 | description: | 771 | description: |
| ... | @@ -906,13 +920,6 @@ packages: | ... | @@ -906,13 +920,6 @@ packages: |
| 906 | url: "https://pub.flutter-io.cn" | 920 | url: "https://pub.flutter-io.cn" |
| 907 | source: hosted | 921 | source: hosted |
| 908 | version: "1.2.0" | 922 | version: "1.2.0" |
| 909 | - qr_code_scanner: | ||
| 910 | - dependency: "direct main" | ||
| 911 | - description: | ||
| 912 | - name: qr_code_scanner | ||
| 913 | - url: "https://pub.flutter-io.cn" | ||
| 914 | - source: hosted | ||
| 915 | - version: "0.7.0" | ||
| 916 | quick_actions: | 923 | quick_actions: |
| 917 | dependency: "direct main" | 924 | dependency: "direct main" |
| 918 | description: | 925 | description: |
| ... | @@ -1120,7 +1127,7 @@ packages: | ... | @@ -1120,7 +1127,7 @@ packages: |
| 1120 | name: source_span | 1127 | name: source_span |
| 1121 | url: "https://pub.flutter-io.cn" | 1128 | url: "https://pub.flutter-io.cn" |
| 1122 | source: hosted | 1129 | source: hosted |
| 1123 | - version: "1.8.1" | 1130 | + version: "1.8.2" |
| 1124 | sp_util: | 1131 | sp_util: |
| 1125 | dependency: transitive | 1132 | dependency: transitive |
| 1126 | description: | 1133 | description: |
| ... | @@ -1162,7 +1169,7 @@ packages: | ... | @@ -1162,7 +1169,7 @@ packages: |
| 1162 | name: sticky_headers | 1169 | name: sticky_headers |
| 1163 | url: "https://pub.flutter-io.cn" | 1170 | url: "https://pub.flutter-io.cn" |
| 1164 | source: hosted | 1171 | source: hosted |
| 1165 | - version: "0.2.0" | 1172 | + version: "0.3.0+2" |
| 1166 | stream_channel: | 1173 | stream_channel: |
| 1167 | dependency: transitive | 1174 | dependency: transitive |
| 1168 | description: | 1175 | description: |
| ... | @@ -1218,21 +1225,21 @@ packages: | ... | @@ -1218,21 +1225,21 @@ packages: |
| 1218 | name: test | 1225 | name: test |
| 1219 | url: "https://pub.flutter-io.cn" | 1226 | url: "https://pub.flutter-io.cn" |
| 1220 | source: hosted | 1227 | source: hosted |
| 1221 | - version: "1.19.5" | 1228 | + version: "1.20.2" |
| 1222 | test_api: | 1229 | test_api: |
| 1223 | dependency: transitive | 1230 | dependency: transitive |
| 1224 | description: | 1231 | description: |
| 1225 | name: test_api | 1232 | name: test_api |
| 1226 | url: "https://pub.flutter-io.cn" | 1233 | url: "https://pub.flutter-io.cn" |
| 1227 | source: hosted | 1234 | source: hosted |
| 1228 | - version: "0.4.8" | 1235 | + version: "0.4.9" |
| 1229 | test_core: | 1236 | test_core: |
| 1230 | dependency: transitive | 1237 | dependency: transitive |
| 1231 | description: | 1238 | description: |
| 1232 | name: test_core | 1239 | name: test_core |
| 1233 | url: "https://pub.flutter-io.cn" | 1240 | url: "https://pub.flutter-io.cn" |
| 1234 | source: hosted | 1241 | source: hosted |
| 1235 | - version: "0.4.9" | 1242 | + version: "0.4.11" |
| 1236 | timing: | 1243 | timing: |
| 1237 | dependency: transitive | 1244 | dependency: transitive |
| 1238 | description: | 1245 | description: |
| ... | @@ -1330,7 +1337,7 @@ packages: | ... | @@ -1330,7 +1337,7 @@ packages: |
| 1330 | name: vector_math | 1337 | name: vector_math |
| 1331 | url: "https://pub.flutter-io.cn" | 1338 | url: "https://pub.flutter-io.cn" |
| 1332 | source: hosted | 1339 | source: hosted |
| 1333 | - version: "2.1.1" | 1340 | + version: "2.1.2" |
| 1334 | vibration: | 1341 | vibration: |
| 1335 | dependency: "direct main" | 1342 | dependency: "direct main" |
| 1336 | description: | 1343 | description: |
| ... | @@ -1386,7 +1393,7 @@ packages: | ... | @@ -1386,7 +1393,7 @@ packages: |
| 1386 | name: vm_service | 1393 | name: vm_service |
| 1387 | url: "https://pub.flutter-io.cn" | 1394 | url: "https://pub.flutter-io.cn" |
| 1388 | source: hosted | 1395 | source: hosted |
| 1389 | - version: "7.5.0" | 1396 | + version: "8.2.2" |
| 1390 | watcher: | 1397 | watcher: |
| 1391 | dependency: transitive | 1398 | dependency: transitive |
| 1392 | description: | 1399 | description: |
| ... | @@ -1472,5 +1479,5 @@ packages: | ... | @@ -1472,5 +1479,5 @@ packages: |
| 1472 | source: hosted | 1479 | source: hosted |
| 1473 | version: "3.1.0" | 1480 | version: "3.1.0" |
| 1474 | sdks: | 1481 | sdks: |
| 1475 | - dart: ">=2.16.2 <3.0.0" | 1482 | + dart: ">=2.17.0 <3.0.0" |
| 1476 | - flutter: ">=2.10.0" | 1483 | + flutter: ">=3.0.0" | ... | ... |
| ... | @@ -59,9 +59,9 @@ dependencies: | ... | @@ -59,9 +59,9 @@ dependencies: |
| 59 | # WebView插件 https://github.com/flutter/plugins/tree/master/packages/webview_flutter | 59 | # WebView插件 https://github.com/flutter/plugins/tree/master/packages/webview_flutter |
| 60 | webview_flutter: ^3.0.1 | 60 | webview_flutter: ^3.0.1 |
| 61 | # 处理键盘事件 https://github.com/diegoveloper/flutter_keyboard_actions | 61 | # 处理键盘事件 https://github.com/diegoveloper/flutter_keyboard_actions |
| 62 | - keyboard_actions: ^3.4.4 | 62 | + keyboard_actions: ^4.0.0 |
| 63 | # 列表悬浮头 https://github.com/fluttercommunity/flutter_sticky_headers | 63 | # 列表悬浮头 https://github.com/fluttercommunity/flutter_sticky_headers |
| 64 | - sticky_headers: ^0.2.0 | 64 | + sticky_headers: ^0.3.0+2 |
| 65 | # 路由框架 https://github.com/theyakka/fluro | 65 | # 路由框架 https://github.com/theyakka/fluro |
| 66 | fluro: ^2.0.3 | 66 | fluro: ^2.0.3 |
| 67 | # 图片缓存 https://github.com/renefloor/flutter_cached_network_image | 67 | # 图片缓存 https://github.com/renefloor/flutter_cached_network_image |
| ... | @@ -70,8 +70,6 @@ dependencies: | ... | @@ -70,8 +70,6 @@ dependencies: |
| 70 | sprintf: ^6.0.0 | 70 | sprintf: ^6.0.0 |
| 71 | # 状态管理 https://github.com/rrousselGit/provider | 71 | # 状态管理 https://github.com/rrousselGit/provider |
| 72 | provider: ^6.0.2 | 72 | provider: ^6.0.2 |
| 73 | - # 扫码 https://github.com/juliuscanute/qr_code_scanner | ||
| 74 | - qr_code_scanner: ^0.7.0 | ||
| 75 | # App Shortcuts https://github.com/flutter/plugins/tree/master/packages/quick_actions | 73 | # App Shortcuts https://github.com/flutter/plugins/tree/master/packages/quick_actions |
| 76 | quick_actions: ^0.6.0+8 | 74 | quick_actions: ^0.6.0+8 |
| 77 | # 振动(支持Web) https://github.com/benjamindean/flutter_vibration | 75 | # 振动(支持Web) https://github.com/benjamindean/flutter_vibration |
| ... | @@ -113,6 +111,8 @@ dependencies: | ... | @@ -113,6 +111,8 @@ dependencies: |
| 113 | sign_in_with_apple: ^3.3.0 | 111 | sign_in_with_apple: ^3.3.0 |
| 114 | event_bus: ^2.0.0 | 112 | event_bus: ^2.0.0 |
| 115 | 113 | ||
| 114 | + animated_radial_menu: ^0.0.1 | ||
| 115 | + | ||
| 116 | dependency_overrides: | 116 | dependency_overrides: |
| 117 | decimal: 1.5.0 | 117 | decimal: 1.5.0 |
| 118 | 118 | ||
| ... | @@ -135,7 +135,7 @@ dev_dependencies: | ... | @@ -135,7 +135,7 @@ dev_dependencies: |
| 135 | # activated in the `analysis_options.yaml` file located at the root of your | 135 | # activated in the `analysis_options.yaml` file located at the root of your |
| 136 | # package. See that file for information about deactivating specific lint | 136 | # package. See that file for information about deactivating specific lint |
| 137 | # rules and activating additional ones. | 137 | # rules and activating additional ones. |
| 138 | - flutter_lints: ^1.0.0 | 138 | + flutter_lints: ^2.0.1 |
| 139 | 139 | ||
| 140 | json_serializable: ^6.1.3 | 140 | json_serializable: ^6.1.3 |
| 141 | build_runner: ^2.1.7 | 141 | build_runner: ^2.1.7 | ... | ... |
-
Please register or login to post a comment