Showing
14 changed files
with
743 additions
and
46 deletions
| ... | @@ -180,7 +180,7 @@ class HomeState extends State<Home> with WidgetsBindingObserver { | ... | @@ -180,7 +180,7 @@ class HomeState extends State<Home> with WidgetsBindingObserver { |
| 180 | ), | 180 | ), |
| 181 | ), | 181 | ), |
| 182 | Positioned( | 182 | Positioned( |
| 183 | - top: 18.0, | 183 | + top: 30.0, |
| 184 | left: 10.0, | 184 | left: 10.0, |
| 185 | right: 10.0, | 185 | right: 10.0, |
| 186 | child: Center( | 186 | child: Center( | ... | ... |
| 1 | +import 'dart:io'; | ||
| 2 | + | ||
| 1 | import 'package:Parlando/account/view_models/account_view_model.dart'; | 3 | import 'package:Parlando/account/view_models/account_view_model.dart'; |
| 2 | import 'package:Parlando/membership/view_models/membership_view_model.dart'; | 4 | import 'package:Parlando/membership/view_models/membership_view_model.dart'; |
| 3 | import 'package:dio/dio.dart'; | 5 | import 'package:dio/dio.dart'; |
| ... | @@ -23,6 +25,7 @@ import 'util/device_utils.dart'; | ... | @@ -23,6 +25,7 @@ import 'util/device_utils.dart'; |
| 23 | import 'util/handle_error_utils.dart'; | 25 | import 'util/handle_error_utils.dart'; |
| 24 | import 'util/log_utils.dart'; | 26 | import 'util/log_utils.dart'; |
| 25 | import 'util/theme_utils.dart'; | 27 | import 'util/theme_utils.dart'; |
| 28 | + | ||
| 26 | /// | 29 | /// |
| 27 | /// 配置本地化的方法 | 30 | /// 配置本地化的方法 |
| 28 | /// 1. 安裝Flutter intl插件 | 31 | /// 1. 安裝Flutter intl插件 |
| ... | @@ -69,6 +72,16 @@ Future<void> main() async { | ... | @@ -69,6 +72,16 @@ Future<void> main() async { |
| 69 | overlays: [SystemUiOverlay.bottom]); | 72 | overlays: [SystemUiOverlay.bottom]); |
| 70 | // TODO(weilu): 启动体验不佳。状态栏、导航栏在冷启动开始的一瞬间为黑色,且无法通过隐藏、修改颜色等方式进行处理。。。 | 73 | // TODO(weilu): 启动体验不佳。状态栏、导航栏在冷启动开始的一瞬间为黑色,且无法通过隐藏、修改颜色等方式进行处理。。。 |
| 71 | // 相关问题跟踪:https://github.com/flutter/flutter/issues/73351 | 74 | // 相关问题跟踪:https://github.com/flutter/flutter/issues/73351 |
| 75 | + if (Platform.isAndroid) { | ||
| 76 | + //设置Android头部的导航栏透明 | ||
| 77 | + SystemUiOverlayStyle systemUiOverlayStyle = const SystemUiOverlayStyle( | ||
| 78 | + statusBarColor: Colors.transparent, //全局设置透明 | ||
| 79 | + statusBarIconBrightness: Brightness.light | ||
| 80 | + //light:黑色图标 dark:白色图标 | ||
| 81 | + //在此处设置statusBarIconBrightness为全局设置 | ||
| 82 | + ); | ||
| 83 | + SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle); | ||
| 84 | + } | ||
| 72 | } | 85 | } |
| 73 | 86 | ||
| 74 | class MyApp extends StatelessWidget { | 87 | class MyApp extends StatelessWidget { |
| ... | @@ -143,13 +156,14 @@ class MyApp extends StatelessWidget { | ... | @@ -143,13 +156,14 @@ class MyApp extends StatelessWidget { |
| 143 | return OKToast( | 156 | return OKToast( |
| 144 | backgroundColor: Colors.black54, | 157 | backgroundColor: Colors.black54, |
| 145 | textPadding: | 158 | textPadding: |
| 146 | - const EdgeInsets.symmetric(horizontal: 16.0, vertical: 10.0), | 159 | + const EdgeInsets.symmetric(horizontal: 16.0, vertical: 10.0), |
| 147 | radius: 20.0, | 160 | radius: 20.0, |
| 148 | position: ToastPosition.bottom, | 161 | position: ToastPosition.bottom, |
| 149 | child: app); | 162 | child: app); |
| 150 | } | 163 | } |
| 151 | 164 | ||
| 152 | - Widget _buildMaterialApp(ThemeProvider provider, LocaleProvider localeProvider) { | 165 | + Widget _buildMaterialApp( |
| 166 | + ThemeProvider provider, LocaleProvider localeProvider) { | ||
| 153 | return MaterialApp( | 167 | return MaterialApp( |
| 154 | title: '一言', | 168 | title: '一言', |
| 155 | // showPerformanceOverlay: true, //显示性能标签 | 169 | // showPerformanceOverlay: true, //显示性能标签 | ... | ... |
| 1 | import 'package:Parlando/account/page/account_page.dart'; | 1 | import 'package:Parlando/account/page/account_page.dart'; |
| 2 | import 'package:Parlando/home/home_page.dart'; | 2 | import 'package:Parlando/home/home_page.dart'; |
| 3 | -import 'package:Parlando/poem/theme/tik_theme.dart'; | ||
| 4 | -import 'package:animated_radial_menu/animated_radial_menu.dart'; | ||
| 5 | import 'package:flutter/material.dart'; | 3 | import 'package:flutter/material.dart'; |
| 6 | import 'package:flutter_gen/gen_l10n/Parlando_localizations.dart'; | 4 | import 'package:flutter_gen/gen_l10n/Parlando_localizations.dart'; |
| 7 | import 'package:provider/provider.dart'; | 5 | import 'package:provider/provider.dart'; |
| ... | @@ -38,11 +36,12 @@ class NavBarPageState extends State<NavBarPage> { | ... | @@ -38,11 +36,12 @@ class NavBarPageState extends State<NavBarPage> { |
| 38 | 'UserProfile': const AccountPage(), | 36 | 'UserProfile': const AccountPage(), |
| 39 | }; | 37 | }; |
| 40 | return Scaffold( | 38 | return Scaffold( |
| 39 | + extendBody: true, // 底部nav bar透明 | ||
| 41 | body: tabs[_currentPage], | 40 | body: tabs[_currentPage], |
| 42 | bottomNavigationBar: Consumer( | 41 | bottomNavigationBar: Consumer( |
| 43 | builder: (_, provider, __) { | 42 | builder: (_, provider, __) { |
| 44 | return BottomAppBar( | 43 | return BottomAppBar( |
| 45 | - color: Colors.grey, | 44 | + color: Colors.transparent, |
| 46 | child: Row( | 45 | child: Row( |
| 47 | mainAxisSize: MainAxisSize.max, | 46 | mainAxisSize: MainAxisSize.max, |
| 48 | mainAxisAlignment: MainAxisAlignment.spaceAround, | 47 | mainAxisAlignment: MainAxisAlignment.spaceAround, |
| ... | @@ -60,7 +59,7 @@ class NavBarPageState extends State<NavBarPage> { | ... | @@ -60,7 +59,7 @@ class NavBarPageState extends State<NavBarPage> { |
| 60 | .onePoemBottomNavigationBarItemTitle, | 59 | .onePoemBottomNavigationBarItemTitle, |
| 61 | style: const TextStyle( | 60 | style: const TextStyle( |
| 62 | color: Colors.white54, | 61 | color: Colors.white54, |
| 63 | - fontSize: 20.0, | 62 | + fontSize: 16.0, |
| 64 | ), | 63 | ), |
| 65 | ), | 64 | ), |
| 66 | ), | 65 | ), |
| ... | @@ -81,7 +80,7 @@ class NavBarPageState extends State<NavBarPage> { | ... | @@ -81,7 +80,7 @@ class NavBarPageState extends State<NavBarPage> { |
| 81 | .profileBottomNavigationBarItemTitle, | 80 | .profileBottomNavigationBarItemTitle, |
| 82 | style: const TextStyle( | 81 | style: const TextStyle( |
| 83 | color: Colors.white54, | 82 | color: Colors.white54, |
| 84 | - fontSize: 20.0, | 83 | + fontSize: 16.0, |
| 85 | ), | 84 | ), |
| 86 | ), | 85 | ), |
| 87 | ), | 86 | ), |
| ... | @@ -90,26 +89,6 @@ class NavBarPageState extends State<NavBarPage> { | ... | @@ -90,26 +89,6 @@ class NavBarPageState extends State<NavBarPage> { |
| 90 | ); | 89 | ); |
| 91 | }, | 90 | }, |
| 92 | ), | 91 | ), |
| 93 | - floatingActionButton: SizedBox( | ||
| 94 | - height: 60, | ||
| 95 | - child: RadialMenu( | ||
| 96 | - children: [ | ||
| 97 | - RadialButton( | ||
| 98 | - icon: const Icon(Icons.video_call_outlined), | ||
| 99 | - buttonColor: Colors.teal, | ||
| 100 | - onPress: () { | ||
| 101 | - eventBus.fire(TransEvent()); | ||
| 102 | - }), | ||
| 103 | - RadialButton( | ||
| 104 | - icon: const Icon(Icons.mic_none_outlined), | ||
| 105 | - buttonColor: Colors.green, | ||
| 106 | - onPress: () { | ||
| 107 | - eventBus.fire(TransEvent()); | ||
| 108 | - }), | ||
| 109 | - ], | ||
| 110 | - ), | ||
| 111 | - ), | ||
| 112 | - floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, | ||
| 113 | ); | 92 | ); |
| 114 | } | 93 | } |
| 115 | } | 94 | } | ... | ... |
| 1 | +import 'package:Parlando/poem/poem_router.dart'; | ||
| 2 | +import 'package:Parlando/routers/fluro_navigator.dart'; | ||
| 3 | +import 'package:animated_radial_menu/animated_radial_menu.dart'; | ||
| 1 | import 'package:dio/dio.dart'; | 4 | import 'package:dio/dio.dart'; |
| 2 | import 'package:flutter/material.dart'; | 5 | import 'package:flutter/material.dart'; |
| 3 | import 'package:getwidget/getwidget.dart'; | 6 | import 'package:getwidget/getwidget.dart'; |
| ... | @@ -38,11 +41,25 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -38,11 +41,25 @@ class VideoSlidesState extends State<VideoSlides> { |
| 38 | super.initState(); | 41 | super.initState(); |
| 39 | isPraise = widget.isPraise; | 42 | isPraise = widget.isPraise; |
| 40 | isCollect = widget.isCollect; | 43 | isCollect = widget.isCollect; |
| 44 | + recodeVideoPlayStatus(); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + Future<void> recodeVideoPlayStatus() async { | ||
| 48 | + String url = '${HttpApi.addView}/${widget.videoId}'; | ||
| 49 | + // 统计观看数 | ||
| 50 | + DioUtils.instance.asyncRequestNetwork( | ||
| 51 | + Method.get, | ||
| 52 | + url, | ||
| 53 | + params: [], | ||
| 54 | + onSuccess: (data) {}, | ||
| 55 | + onError: (code, msg) {}, | ||
| 56 | + ); | ||
| 41 | } | 57 | } |
| 42 | 58 | ||
| 43 | @override | 59 | @override |
| 44 | Widget build(BuildContext context) { | 60 | Widget build(BuildContext context) { |
| 45 | return Stack( | 61 | return Stack( |
| 62 | + alignment: AlignmentDirectional.center, | ||
| 46 | children: [ | 63 | children: [ |
| 47 | Container( | 64 | Container( |
| 48 | width: double.infinity, | 65 | width: double.infinity, |
| ... | @@ -93,7 +110,7 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -93,7 +110,7 @@ class VideoSlidesState extends State<VideoSlides> { |
| 93 | children: [ | 110 | children: [ |
| 94 | Padding( | 111 | Padding( |
| 95 | padding: | 112 | padding: |
| 96 | - const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0), | 113 | + const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0), |
| 97 | child: Row( | 114 | child: Row( |
| 98 | mainAxisSize: MainAxisSize.max, | 115 | mainAxisSize: MainAxisSize.max, |
| 99 | mainAxisAlignment: MainAxisAlignment.center, | 116 | mainAxisAlignment: MainAxisAlignment.center, |
| ... | @@ -108,7 +125,7 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -108,7 +125,7 @@ class VideoSlidesState extends State<VideoSlides> { |
| 108 | child: InkWell( | 125 | child: InkWell( |
| 109 | onTap: () { | 126 | onTap: () { |
| 110 | isPraise = | 127 | isPraise = |
| 111 | - isPraise == false ? true : false; | 128 | + isPraise == false ? true : false; |
| 112 | setState(() {}); | 129 | setState(() {}); |
| 113 | String url = | 130 | String url = |
| 114 | '${HttpApi.praise}/${widget.videoId}'; | 131 | '${HttpApi.praise}/${widget.videoId}'; |
| ... | @@ -144,7 +161,7 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -144,7 +161,7 @@ class VideoSlidesState extends State<VideoSlides> { |
| 144 | ), | 161 | ), |
| 145 | Padding( | 162 | Padding( |
| 146 | padding: | 163 | padding: |
| 147 | - const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0), | 164 | + const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0), |
| 148 | child: Row( | 165 | child: Row( |
| 149 | mainAxisSize: MainAxisSize.max, | 166 | mainAxisSize: MainAxisSize.max, |
| 150 | mainAxisAlignment: MainAxisAlignment.center, | 167 | mainAxisAlignment: MainAxisAlignment.center, |
| ... | @@ -159,7 +176,7 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -159,7 +176,7 @@ class VideoSlidesState extends State<VideoSlides> { |
| 159 | child: InkWell( | 176 | child: InkWell( |
| 160 | onTap: () async { | 177 | onTap: () async { |
| 161 | isCollect = | 178 | isCollect = |
| 162 | - isCollect == false ? true : false; | 179 | + isCollect == false ? true : false; |
| 163 | setState(() {}); | 180 | setState(() {}); |
| 164 | String url = | 181 | String url = |
| 165 | '${HttpApi.collect}/${widget.videoId}'; | 182 | '${HttpApi.collect}/${widget.videoId}'; |
| ... | @@ -195,7 +212,7 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -195,7 +212,7 @@ class VideoSlidesState extends State<VideoSlides> { |
| 195 | ), | 212 | ), |
| 196 | Padding( | 213 | Padding( |
| 197 | padding: | 214 | padding: |
| 198 | - const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0), | 215 | + const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0), |
| 199 | child: Row( | 216 | child: Row( |
| 200 | mainAxisSize: MainAxisSize.max, | 217 | mainAxisSize: MainAxisSize.max, |
| 201 | mainAxisAlignment: MainAxisAlignment.center, | 218 | mainAxisAlignment: MainAxisAlignment.center, |
| ... | @@ -225,14 +242,14 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -225,14 +242,14 @@ class VideoSlidesState extends State<VideoSlides> { |
| 225 | ), | 242 | ), |
| 226 | child: isSharing | 243 | child: isSharing |
| 227 | ? GFProgressBar( | 244 | ? GFProgressBar( |
| 228 | - percentage: currentProgress, | 245 | + percentage: currentProgress, |
| 229 | - backgroundColor: Colors.black26, | 246 | + backgroundColor: Colors.black26, |
| 230 | - progressBarColor: GFColors.DANGER) | 247 | + progressBarColor: GFColors.DANGER) |
| 231 | : const Icon( | 248 | : const Icon( |
| 232 | - Icons.share_rounded, | 249 | + Icons.share_rounded, |
| 233 | - color: Colors.white, | 250 | + color: Colors.white, |
| 234 | - size: 20, | 251 | + size: 20, |
| 235 | - ), | 252 | + ), |
| 236 | ), | 253 | ), |
| 237 | ), | 254 | ), |
| 238 | ), | 255 | ), |
| ... | @@ -248,6 +265,39 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -248,6 +265,39 @@ class VideoSlidesState extends State<VideoSlides> { |
| 248 | ), | 265 | ), |
| 249 | ], | 266 | ], |
| 250 | ), | 267 | ), |
| 268 | + Positioned( | ||
| 269 | + bottom: -48, | ||
| 270 | + child: Container( | ||
| 271 | + alignment: Alignment.bottomCenter, | ||
| 272 | + width: 160, | ||
| 273 | + height: 180, | ||
| 274 | + child: RadialMenu( | ||
| 275 | + centerButtonAlignment: Alignment.bottomLeft, | ||
| 276 | + children: [ | ||
| 277 | + RadialButton( | ||
| 278 | + icon: const Icon(Icons.video_call_outlined), | ||
| 279 | + buttonColor: Colors.teal, | ||
| 280 | + onPress: () { | ||
| 281 | + String url = | ||
| 282 | + '${PoemRouter.poemRecordVideoPage}?id=${widget.videoId}&type=${widget.poemType}'; | ||
| 283 | + NavigatorUtils.push( | ||
| 284 | + context, | ||
| 285 | + url, | ||
| 286 | + ); | ||
| 287 | + }), | ||
| 288 | + RadialButton( | ||
| 289 | + icon: const Icon(Icons.mic_none_outlined), | ||
| 290 | + buttonColor: Colors.green, | ||
| 291 | + onPress: () { | ||
| 292 | + NavigatorUtils.push( | ||
| 293 | + context, | ||
| 294 | + '${PoemRouter.poemRecordAudioPage}?id=${widget.videoId}&type=${widget.poemType}', | ||
| 295 | + ); | ||
| 296 | + }), | ||
| 297 | + ], | ||
| 298 | + ), | ||
| 299 | + ), | ||
| 300 | + ), | ||
| 251 | ], | 301 | ], |
| 252 | ); | 302 | ); |
| 253 | } | 303 | } |
| ... | @@ -269,10 +319,10 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -269,10 +319,10 @@ class VideoSlidesState extends State<VideoSlides> { |
| 269 | tempVideoPath = "$savePath$appName"; | 319 | tempVideoPath = "$savePath$appName"; |
| 270 | Response response = await dio.download(url, tempVideoPath, | 320 | Response response = await dio.download(url, tempVideoPath, |
| 271 | onReceiveProgress: (received, total) { | 321 | onReceiveProgress: (received, total) { |
| 272 | - if (total != -1) { | 322 | + if (total != -1) { |
| 273 | - currentProgress = received / total; | 323 | + currentProgress = received / total; |
| 274 | - setState(() {}); | 324 | + setState(() {}); |
| 275 | - } | 325 | + } |
| 276 | - }); | 326 | + }); |
| 277 | } | 327 | } |
| 278 | } | 328 | } | ... | ... |
plugins/animated_radial/.gitignore
0 → 100644
| 1 | +# Miscellaneous | ||
| 2 | +*.class | ||
| 3 | +*.log | ||
| 4 | +*.pyc | ||
| 5 | +*.swp | ||
| 6 | +.DS_Store | ||
| 7 | +.atom/ | ||
| 8 | +.buildlog/ | ||
| 9 | +.history | ||
| 10 | +.svn/ | ||
| 11 | + | ||
| 12 | +# IntelliJ related | ||
| 13 | +*.iml | ||
| 14 | +*.ipr | ||
| 15 | +*.iws | ||
| 16 | +.idea/ | ||
| 17 | + | ||
| 18 | +# The .vscode folder contains launch configuration and tasks you configure in | ||
| 19 | +# VS Code which you may wish to be included in version control, so this line | ||
| 20 | +# is commented out by default. | ||
| 21 | +#.vscode/ | ||
| 22 | + | ||
| 23 | +# Flutter/Dart/Pub related | ||
| 24 | +**/doc/api/ | ||
| 25 | +.dart_tool/ | ||
| 26 | +.flutter-plugins | ||
| 27 | +.flutter-plugins-dependencies | ||
| 28 | +.packages | ||
| 29 | +.pub-cache/ | ||
| 30 | +.pub/ | ||
| 31 | +build/ | ||
| 32 | + | ||
| 33 | +# Android related | ||
| 34 | +**/android/**/gradle-wrapper.jar | ||
| 35 | +**/android/.gradle | ||
| 36 | +**/android/captures/ | ||
| 37 | +**/android/gradlew | ||
| 38 | +**/android/gradlew.bat | ||
| 39 | +**/android/local.properties | ||
| 40 | +**/android/**/GeneratedPluginRegistrant.java | ||
| 41 | + | ||
| 42 | +# iOS/XCode related | ||
| 43 | +**/ios/**/*.mode1v3 | ||
| 44 | +**/ios/**/*.mode2v3 | ||
| 45 | +**/ios/**/*.moved-aside | ||
| 46 | +**/ios/**/*.pbxuser | ||
| 47 | +**/ios/**/*.perspectivev3 | ||
| 48 | +**/ios/**/*sync/ | ||
| 49 | +**/ios/**/.sconsign.dblite | ||
| 50 | +**/ios/**/.tags* | ||
| 51 | +**/ios/**/.vagrant/ | ||
| 52 | +**/ios/**/DerivedData/ | ||
| 53 | +**/ios/**/Icon? | ||
| 54 | +**/ios/**/Pods/ | ||
| 55 | +**/ios/**/.symlinks/ | ||
| 56 | +**/ios/**/profile | ||
| 57 | +**/ios/**/xcuserdata | ||
| 58 | +**/ios/.generated/ | ||
| 59 | +**/ios/Flutter/App.framework | ||
| 60 | +**/ios/Flutter/Flutter.framework | ||
| 61 | +**/ios/Flutter/Flutter.podspec | ||
| 62 | +**/ios/Flutter/Generated.xcconfig | ||
| 63 | +**/ios/Flutter/ephemeral | ||
| 64 | +**/ios/Flutter/app.flx | ||
| 65 | +**/ios/Flutter/app.zip | ||
| 66 | +**/ios/Flutter/flutter_assets/ | ||
| 67 | +**/ios/Flutter/flutter_export_environment.sh | ||
| 68 | +**/ios/ServiceDefinitions.json | ||
| 69 | +**/ios/Runner/GeneratedPluginRegistrant.* | ||
| 70 | + | ||
| 71 | +# Exceptions to above rules. | ||
| 72 | +!**/ios/**/default.mode1v3 | ||
| 73 | +!**/ios/**/default.mode2v3 | ||
| 74 | +!**/ios/**/default.pbxuser | ||
| 75 | +!**/ios/**/default.perspectivev3 |
plugins/animated_radial/.metadata
0 → 100644
| 1 | +# This file tracks properties of this Flutter project. | ||
| 2 | +# Used by Flutter tool to assess capabilities and perform upgrades etc. | ||
| 3 | +# | ||
| 4 | +# This file should be version controlled and should not be manually edited. | ||
| 5 | + | ||
| 6 | +version: | ||
| 7 | + revision: d79295af24c3ed621c33713ecda14ad196fd9c31 | ||
| 8 | + channel: stable | ||
| 9 | + | ||
| 10 | +project_type: package |
plugins/animated_radial/CHANGELOG.md
0 → 100644
plugins/animated_radial/LICENSE
0 → 100644
| 1 | +MIT License | ||
| 2 | + | ||
| 3 | +Copyright (c) 2021 Sony Kurian | ||
| 4 | + | ||
| 5 | +Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 6 | +of this software and associated documentation files (the "Software"), to deal | ||
| 7 | +in the Software without restriction, including without limitation the rights | ||
| 8 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 9 | +copies of the Software, and to permit persons to whom the Software is | ||
| 10 | +furnished to do so, subject to the following conditions: | ||
| 11 | + | ||
| 12 | +The above copyright notice and this permission notice shall be included in all | ||
| 13 | +copies or substantial portions of the Software. | ||
| 14 | + | ||
| 15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 18 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 19 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 20 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 21 | +SOFTWARE. |
plugins/animated_radial/README.md
0 → 100644
| 1 | +# animated_radial_menu | ||
| 2 | + | ||
| 3 | +The package provides an easy way to work with radial menu along with animations. | ||
| 4 | + | ||
| 5 | + | ||
| 6 | + | ||
| 7 | +You can check out the | ||
| 8 | +example [here](https://github.com/sonykurian96/animated-radial-menu/blob/master/example/lib/main.dart) | ||
| 9 | + | ||
| 10 | +## Installation | ||
| 11 | + | ||
| 12 | +To use this package : add the dependency to your pubspec.yaml file | ||
| 13 | + | ||
| 14 | +```yaml | ||
| 15 | + dependencies: | ||
| 16 | + flutter: | ||
| 17 | + sdk: flutter | ||
| 18 | + animated_radial_menu: | ||
| 19 | +``` | ||
| 20 | + | ||
| 21 | +## Basic Usage | ||
| 22 | + | ||
| 23 | +Import it to your project file | ||
| 24 | + | ||
| 25 | +```dart | ||
| 26 | + import 'package:animated_radial_menu/animated_radial_menu.dart'; | ||
| 27 | +``` | ||
| 28 | + | ||
| 29 | +Similar to column or row widget, simply pass in buttons as children and you are done | ||
| 30 | + | ||
| 31 | +```dart | ||
| 32 | + RadialMenu | ||
| 33 | +( | ||
| 34 | +children: [ | ||
| 35 | +RadialButton | ||
| 36 | +( | ||
| 37 | +icon: Icon | ||
| 38 | +( | ||
| 39 | +Icons.ac_unit), | ||
| 40 | +onPress: ( | ||
| 41 | +) | ||
| 42 | +=> | ||
| 43 | |||
| 44 | +("ac unit | ||
| 45 | +" | ||
| 46 | +) | ||
| 47 | +, | ||
| 48 | +) | ||
| 49 | +] | ||
| 50 | +) | ||
| 51 | +, | ||
| 52 | +``` | ||
| 53 | + | ||
| 54 | +Eventhough you can use this widget anywhere, it's recommended to use RadialMenu with Stack Widget if | ||
| 55 | +your page contains tons of UI elements | ||
| 56 | + | ||
| 57 | +```dart | ||
| 58 | + body: Stack | ||
| 59 | +( | ||
| 60 | +children: [ | ||
| 61 | +RadialMenu | ||
| 62 | +( | ||
| 63 | +children: [ | ||
| 64 | +RadialButton | ||
| 65 | +( | ||
| 66 | +icon: Icon | ||
| 67 | +( | ||
| 68 | +Icons.ac_unit), | ||
| 69 | +buttonColor: Colors.teal,onPress: ( | ||
| 70 | +) | ||
| 71 | +=> | ||
| 72 | +Get.to(TargetScreen | ||
| 73 | +( | ||
| 74 | +))) | ||
| 75 | +, | ||
| 76 | +RadialButton | ||
| 77 | +( | ||
| 78 | +icon: Icon | ||
| 79 | +( | ||
| 80 | +Icons.camera_alt), | ||
| 81 | +buttonColor: Colors.green,onPress: ( | ||
| 82 | +) | ||
| 83 | +=> | ||
| 84 | +Get.to(TargetScreen | ||
| 85 | +( | ||
| 86 | +))) | ||
| 87 | +, | ||
| 88 | +RadialButton | ||
| 89 | +( | ||
| 90 | +icon: Icon | ||
| 91 | +( | ||
| 92 | +Icons.map), | ||
| 93 | +buttonColor: Colors.orange,onPress: ( | ||
| 94 | +) | ||
| 95 | +=> | ||
| 96 | +Get.to(TargetScreen | ||
| 97 | +( | ||
| 98 | +))), | ||
| 99 | + | ||
| 100 | +/* you can add any number of buttons, although it's | ||
| 101 | + not recommended to insert beyond 8-9 buttons. */ | ||
| 102 | +], | ||
| 103 | +), | ||
| 104 | + | ||
| 105 | +// rest of the widgets.... | ||
| 106 | + | ||
| 107 | +], | ||
| 108 | +), | ||
| 109 | +``` | ||
| 110 | + | ||
| 111 | +You can manually position the widget wherever you wish | ||
| 112 | + | ||
| 113 | +```dart | ||
| 114 | + RadialMenu | ||
| 115 | +( | ||
| 116 | +centerButtonAlignment: Alignment | ||
| 117 | +(0.3, | ||
| 118 | +0.5 | ||
| 119 | +) // by default alignment is set to Alignment.center | ||
| 120 | +) | ||
| 121 | +``` | ||
| 122 | + | ||
| 123 | +You can also customize the main centered button(more customizations will be made available soon) | ||
| 124 | + | ||
| 125 | +```dart | ||
| 126 | + RadialMenu | ||
| 127 | +( | ||
| 128 | +centerButtonSize: 0.5 | ||
| 129 | +, // size ranging from 0.0 to 1.0 | ||
| 130 | +) | ||
| 131 | +``` |
| 1 | +library animated_radial_menu; | ||
| 2 | + | ||
| 3 | +import 'package:flutter/material.dart'; | ||
| 4 | +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; | ||
| 5 | +import 'dart:math'; | ||
| 6 | +import 'package:vector_math/vector_math.dart' show radians; | ||
| 7 | + | ||
| 8 | +class RadialMenu extends StatefulWidget { | ||
| 9 | + // will take in list of buttons | ||
| 10 | + final List<RadialButton> children; | ||
| 11 | + | ||
| 12 | + // used for positioning the widget | ||
| 13 | + final AlignmentGeometry centerButtonAlignment; | ||
| 14 | + | ||
| 15 | + // set main button size | ||
| 16 | + final double centerButtonSize; | ||
| 17 | + | ||
| 18 | + // constructor for main button | ||
| 19 | + const RadialMenu( | ||
| 20 | + {Key? key, | ||
| 21 | + required this.children, | ||
| 22 | + this.centerButtonSize = 0.5, | ||
| 23 | + this.centerButtonAlignment = Alignment.center}) | ||
| 24 | + : super(key: key); | ||
| 25 | + | ||
| 26 | + @override | ||
| 27 | + createState() => _RadialMenuState(); | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +class _RadialMenuState extends State<RadialMenu> | ||
| 31 | + with SingleTickerProviderStateMixin { | ||
| 32 | + // used to control animations | ||
| 33 | + AnimationController? controller; | ||
| 34 | + | ||
| 35 | + // controller gets initialized here | ||
| 36 | + @override | ||
| 37 | + void initState() { | ||
| 38 | + super.initState(); | ||
| 39 | + controller = AnimationController( | ||
| 40 | + duration: const Duration(milliseconds: 900), vsync: this); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + @override | ||
| 44 | + Widget build(BuildContext context) { | ||
| 45 | + return Align( | ||
| 46 | + alignment: widget.centerButtonAlignment, | ||
| 47 | + child: SizedBox( | ||
| 48 | + width: 160, | ||
| 49 | + height: 180, | ||
| 50 | + child: RadialAnimation( | ||
| 51 | + controller: controller!, | ||
| 52 | + radialButtons: widget.children, | ||
| 53 | + centerSizeOfButton: widget.centerButtonSize, | ||
| 54 | + ), | ||
| 55 | + ), | ||
| 56 | + ); | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + // controller gets disposed here | ||
| 60 | + @override | ||
| 61 | + void dispose() { | ||
| 62 | + controller!.dispose(); | ||
| 63 | + super.dispose(); | ||
| 64 | + } | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +// Here all the animation will take place | ||
| 68 | +class RadialAnimation extends StatelessWidget { | ||
| 69 | + RadialAnimation( | ||
| 70 | + {Key? key, | ||
| 71 | + required this.controller, | ||
| 72 | + required this.radialButtons, | ||
| 73 | + this.centerSizeOfButton = 0.5}) | ||
| 74 | + : | ||
| 75 | + // translation animation | ||
| 76 | + translation = Tween<double>( | ||
| 77 | + begin: 0.0, | ||
| 78 | + end: 70.0, | ||
| 79 | + ).animate( | ||
| 80 | + CurvedAnimation(parent: controller, curve: Curves.elasticOut), | ||
| 81 | + ), | ||
| 82 | + | ||
| 83 | + // scaling animation | ||
| 84 | + scale = Tween<double>( | ||
| 85 | + begin: centerSizeOfButton * 2, | ||
| 86 | + end: 0.0, | ||
| 87 | + ).animate( | ||
| 88 | + CurvedAnimation(parent: controller, curve: Curves.fastOutSlowIn), | ||
| 89 | + ), | ||
| 90 | + | ||
| 91 | + // rotation animation | ||
| 92 | + rotation = Tween<double>( | ||
| 93 | + begin: 0.0, | ||
| 94 | + end: 315.0, | ||
| 95 | + ).animate( | ||
| 96 | + CurvedAnimation( | ||
| 97 | + parent: controller, | ||
| 98 | + curve: const Interval( | ||
| 99 | + 0.0, | ||
| 100 | + 0.3, | ||
| 101 | + curve: Curves.decelerate, | ||
| 102 | + ), | ||
| 103 | + ), | ||
| 104 | + ), | ||
| 105 | + super(key: key); | ||
| 106 | + | ||
| 107 | + final AnimationController controller; | ||
| 108 | + final Animation<double> rotation; | ||
| 109 | + final Animation<double> translation; | ||
| 110 | + final Animation<double> scale; | ||
| 111 | + final List<RadialButton> radialButtons; | ||
| 112 | + final double centerSizeOfButton; | ||
| 113 | + | ||
| 114 | + @override | ||
| 115 | + Widget build(BuildContext context) { | ||
| 116 | + // will provide angle for further calculation | ||
| 117 | + double generatedAngle = 270; | ||
| 118 | + double iconAngle; | ||
| 119 | + | ||
| 120 | + return AnimatedBuilder( | ||
| 121 | + animation: controller, | ||
| 122 | + builder: (context, widget) { | ||
| 123 | + return Transform.rotate( | ||
| 124 | + angle: radians(rotation.value), | ||
| 125 | + child: Stack(alignment: Alignment.center, children: [ | ||
| 126 | + // generates list of buttons | ||
| 127 | + ...radialButtons.map((index) { | ||
| 128 | + iconAngle = radialButtons.indexOf(index) * generatedAngle; | ||
| 129 | + return _buildButton(iconAngle, | ||
| 130 | + color: index.buttonColor, | ||
| 131 | + icon: index.icon, | ||
| 132 | + onPress: index.onPress); | ||
| 133 | + }), | ||
| 134 | + // secondary button animation | ||
| 135 | + Transform.scale( | ||
| 136 | + scale: scale.value - (centerSizeOfButton * 2 - 0.25), | ||
| 137 | + child: FloatingActionButton( | ||
| 138 | + onPressed: close, | ||
| 139 | + backgroundColor: Colors.red, | ||
| 140 | + child: const Icon(FontAwesomeIcons.plus)), | ||
| 141 | + ), | ||
| 142 | + // primary button animation | ||
| 143 | + Transform.scale( | ||
| 144 | + scale: scale.value, | ||
| 145 | + child: FloatingActionButton( | ||
| 146 | + onPressed: open, | ||
| 147 | + backgroundColor: Colors.white, | ||
| 148 | + child: const Icon( | ||
| 149 | + FontAwesomeIcons.plus, | ||
| 150 | + color: Colors.black54, | ||
| 151 | + ), | ||
| 152 | + ), | ||
| 153 | + ) | ||
| 154 | + ])); | ||
| 155 | + }); | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + // will show child buttons | ||
| 159 | + void open() { | ||
| 160 | + controller.forward(); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + // will hide child buttons | ||
| 164 | + void close() { | ||
| 165 | + controller.reverse(); | ||
| 166 | + } | ||
| 167 | + | ||
| 168 | + // build custom child buttons | ||
| 169 | + Widget _buildButton(double angle, | ||
| 170 | + {Function? onPress, Color? color, Icon? icon}) { | ||
| 171 | + final double rad = radians(angle); | ||
| 172 | + return Transform( | ||
| 173 | + transform: Matrix4.identity() | ||
| 174 | + ..translate( | ||
| 175 | + (translation.value) * cos(rad), (translation.value) * sin(rad)), | ||
| 176 | + child: FloatingActionButton( | ||
| 177 | + backgroundColor: color, | ||
| 178 | + onPressed: () { | ||
| 179 | + onPress!(); | ||
| 180 | + close(); | ||
| 181 | + }, | ||
| 182 | + elevation: 0, | ||
| 183 | + child: icon)); | ||
| 184 | + } | ||
| 185 | +} | ||
| 186 | + | ||
| 187 | +class RadialButton { | ||
| 188 | + // background colour of the button surrounding the icon | ||
| 189 | + final Color buttonColor; | ||
| 190 | + | ||
| 191 | + // sets icon of the child buttons | ||
| 192 | + final Icon icon; | ||
| 193 | + | ||
| 194 | + // onPress function of the child buttons | ||
| 195 | + final Function onPress; | ||
| 196 | + | ||
| 197 | + // constructor for child buttons | ||
| 198 | + RadialButton( | ||
| 199 | + {this.buttonColor = Colors.orange, | ||
| 200 | + required this.icon, | ||
| 201 | + required this.onPress}); | ||
| 202 | +} |
plugins/animated_radial/pubspec.lock
0 → 100644
| 1 | +# Generated by pub | ||
| 2 | +# See https://dart.dev/tools/pub/glossary#lockfile | ||
| 3 | +packages: | ||
| 4 | + async: | ||
| 5 | + dependency: transitive | ||
| 6 | + description: | ||
| 7 | + name: async | ||
| 8 | + url: "https://pub.dartlang.org" | ||
| 9 | + source: hosted | ||
| 10 | + version: "2.6.1" | ||
| 11 | + boolean_selector: | ||
| 12 | + dependency: transitive | ||
| 13 | + description: | ||
| 14 | + name: boolean_selector | ||
| 15 | + url: "https://pub.dartlang.org" | ||
| 16 | + source: hosted | ||
| 17 | + version: "2.1.0" | ||
| 18 | + characters: | ||
| 19 | + dependency: transitive | ||
| 20 | + description: | ||
| 21 | + name: characters | ||
| 22 | + url: "https://pub.dartlang.org" | ||
| 23 | + source: hosted | ||
| 24 | + version: "1.1.0" | ||
| 25 | + charcode: | ||
| 26 | + dependency: transitive | ||
| 27 | + description: | ||
| 28 | + name: charcode | ||
| 29 | + url: "https://pub.dartlang.org" | ||
| 30 | + source: hosted | ||
| 31 | + version: "1.2.0" | ||
| 32 | + clock: | ||
| 33 | + dependency: transitive | ||
| 34 | + description: | ||
| 35 | + name: clock | ||
| 36 | + url: "https://pub.dartlang.org" | ||
| 37 | + source: hosted | ||
| 38 | + version: "1.1.0" | ||
| 39 | + collection: | ||
| 40 | + dependency: transitive | ||
| 41 | + description: | ||
| 42 | + name: collection | ||
| 43 | + url: "https://pub.dartlang.org" | ||
| 44 | + source: hosted | ||
| 45 | + version: "1.15.0" | ||
| 46 | + fake_async: | ||
| 47 | + dependency: transitive | ||
| 48 | + description: | ||
| 49 | + name: fake_async | ||
| 50 | + url: "https://pub.dartlang.org" | ||
| 51 | + source: hosted | ||
| 52 | + version: "1.2.0" | ||
| 53 | + flutter: | ||
| 54 | + dependency: "direct main" | ||
| 55 | + description: flutter | ||
| 56 | + source: sdk | ||
| 57 | + version: "0.0.0" | ||
| 58 | + flutter_test: | ||
| 59 | + dependency: "direct dev" | ||
| 60 | + description: flutter | ||
| 61 | + source: sdk | ||
| 62 | + version: "0.0.0" | ||
| 63 | + font_awesome_flutter: | ||
| 64 | + dependency: "direct main" | ||
| 65 | + description: | ||
| 66 | + name: font_awesome_flutter | ||
| 67 | + url: "https://pub.dartlang.org" | ||
| 68 | + source: hosted | ||
| 69 | + version: "9.1.0" | ||
| 70 | + matcher: | ||
| 71 | + dependency: transitive | ||
| 72 | + description: | ||
| 73 | + name: matcher | ||
| 74 | + url: "https://pub.dartlang.org" | ||
| 75 | + source: hosted | ||
| 76 | + version: "0.12.10" | ||
| 77 | + meta: | ||
| 78 | + dependency: transitive | ||
| 79 | + description: | ||
| 80 | + name: meta | ||
| 81 | + url: "https://pub.dartlang.org" | ||
| 82 | + source: hosted | ||
| 83 | + version: "1.3.0" | ||
| 84 | + path: | ||
| 85 | + dependency: transitive | ||
| 86 | + description: | ||
| 87 | + name: path | ||
| 88 | + url: "https://pub.dartlang.org" | ||
| 89 | + source: hosted | ||
| 90 | + version: "1.8.0" | ||
| 91 | + sky_engine: | ||
| 92 | + dependency: transitive | ||
| 93 | + description: flutter | ||
| 94 | + source: sdk | ||
| 95 | + version: "0.0.99" | ||
| 96 | + source_span: | ||
| 97 | + dependency: transitive | ||
| 98 | + description: | ||
| 99 | + name: source_span | ||
| 100 | + url: "https://pub.dartlang.org" | ||
| 101 | + source: hosted | ||
| 102 | + version: "1.8.1" | ||
| 103 | + stack_trace: | ||
| 104 | + dependency: transitive | ||
| 105 | + description: | ||
| 106 | + name: stack_trace | ||
| 107 | + url: "https://pub.dartlang.org" | ||
| 108 | + source: hosted | ||
| 109 | + version: "1.10.0" | ||
| 110 | + stream_channel: | ||
| 111 | + dependency: transitive | ||
| 112 | + description: | ||
| 113 | + name: stream_channel | ||
| 114 | + url: "https://pub.dartlang.org" | ||
| 115 | + source: hosted | ||
| 116 | + version: "2.1.0" | ||
| 117 | + string_scanner: | ||
| 118 | + dependency: transitive | ||
| 119 | + description: | ||
| 120 | + name: string_scanner | ||
| 121 | + url: "https://pub.dartlang.org" | ||
| 122 | + source: hosted | ||
| 123 | + version: "1.1.0" | ||
| 124 | + term_glyph: | ||
| 125 | + dependency: transitive | ||
| 126 | + description: | ||
| 127 | + name: term_glyph | ||
| 128 | + url: "https://pub.dartlang.org" | ||
| 129 | + source: hosted | ||
| 130 | + version: "1.2.0" | ||
| 131 | + test_api: | ||
| 132 | + dependency: transitive | ||
| 133 | + description: | ||
| 134 | + name: test_api | ||
| 135 | + url: "https://pub.dartlang.org" | ||
| 136 | + source: hosted | ||
| 137 | + version: "0.3.0" | ||
| 138 | + typed_data: | ||
| 139 | + dependency: transitive | ||
| 140 | + description: | ||
| 141 | + name: typed_data | ||
| 142 | + url: "https://pub.dartlang.org" | ||
| 143 | + source: hosted | ||
| 144 | + version: "1.3.0" | ||
| 145 | + vector_math: | ||
| 146 | + dependency: "direct main" | ||
| 147 | + description: | ||
| 148 | + name: vector_math | ||
| 149 | + url: "https://pub.dartlang.org" | ||
| 150 | + source: hosted | ||
| 151 | + version: "2.1.0" | ||
| 152 | +sdks: | ||
| 153 | + dart: ">=2.12.0 <3.0.0" | ||
| 154 | + flutter: ">=1.17.0" |
plugins/animated_radial/pubspec.yaml
0 → 100644
| 1 | +name: animated_radial_menu | ||
| 2 | +description: highly customizable complex radial animation without any boilerplate code. | ||
| 3 | +version: 0.0.1 | ||
| 4 | +homepage: https://github.com/sonykurian96/animated-radial-menu | ||
| 5 | + | ||
| 6 | +environment: | ||
| 7 | + sdk: ">=2.12.0 <3.0.0" | ||
| 8 | + flutter: ">=1.17.0" | ||
| 9 | + | ||
| 10 | +dependencies: | ||
| 11 | + flutter: | ||
| 12 | + sdk: flutter | ||
| 13 | + | ||
| 14 | + font_awesome_flutter: ^9.1.0 | ||
| 15 | + vector_math: ^2.1.0 | ||
| 16 | + | ||
| 17 | +dev_dependencies: | ||
| 18 | + flutter_test: | ||
| 19 | + sdk: flutter | ||
| 20 | + | ||
| 21 | +# For information on the generic Dart part of this file, see the | ||
| 22 | +# following page: https://dart.dev/tools/pub/pubspec | ||
| 23 | + | ||
| 24 | +# The following section is specific to Flutter. | ||
| 25 | +flutter: | ||
| 26 | + | ||
| 27 | +# To add assets to your package, add an assets section, like this: | ||
| 28 | +# assets: | ||
| 29 | +# - images/a_dot_burr.jpeg | ||
| 30 | +# - images/a_dot_ham.jpeg | ||
| 31 | +# | ||
| 32 | +# For details regarding assets in packages, see | ||
| 33 | +# https://flutter.dev/assets-and-images/#from-packages | ||
| 34 | +# | ||
| 35 | +# An image asset can refer to one or more resolution-specific "variants", see | ||
| 36 | +# https://flutter.dev/assets-and-images/#resolution-aware. | ||
| 37 | + | ||
| 38 | +# To add custom fonts to your package, add a fonts section here, | ||
| 39 | +# in this "flutter" section. Each entry in this list should have a | ||
| 40 | +# "family" key with the font family name, and a "fonts" key with a | ||
| 41 | +# list giving the asset and other descriptors for the font. For | ||
| 42 | +# example: | ||
| 43 | +# fonts: | ||
| 44 | +# - family: Schyler | ||
| 45 | +# fonts: | ||
| 46 | +# - asset: fonts/Schyler-Regular.ttf | ||
| 47 | +# - asset: fonts/Schyler-Italic.ttf | ||
| 48 | +# style: italic | ||
| 49 | +# - family: Trajan Pro | ||
| 50 | +# fonts: | ||
| 51 | +# - asset: fonts/TrajanPro.ttf | ||
| 52 | +# - asset: fonts/TrajanPro_Bold.ttf | ||
| 53 | +# weight: 700 | ||
| 54 | +# | ||
| 55 | +# For details regarding fonts in packages, see | ||
| 56 | +# https://flutter.dev/custom-fonts/#from-packages |
This diff is collapsed. Click to expand it.
| ... | @@ -116,7 +116,9 @@ dependencies: | ... | @@ -116,7 +116,9 @@ dependencies: |
| 116 | 116 | ||
| 117 | event_bus: ^2.0.0 | 117 | event_bus: ^2.0.0 |
| 118 | 118 | ||
| 119 | - animated_radial_menu: ^0.0.1 | 119 | + animated_radial_menu: |
| 120 | + path: plugins/animated_radial | ||
| 121 | + | ||
| 120 | flutter_inapp_purchase: ^5.3.0 | 122 | flutter_inapp_purchase: ^5.3.0 |
| 121 | 123 | ||
| 122 | jpush_flutter: ^2.2.9 | 124 | jpush_flutter: ^2.2.9 | ... | ... |
-
Please register or login to post a comment