animated_splash_screen.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. // ignore_for_file: depend_on_referenced_packages
  2. library animated_splash_screen;
  3. import 'package:flutter/material.dart';
  4. import 'package:get/get.dart';
  5. import 'package:page_transition/page_transition.dart';
  6. enum SplashType { simpleSplash, backgroundScreenReturn }
  7. enum SplashTransition {
  8. slideTransition,
  9. scaleTransition,
  10. rotationTransition,
  11. sizeTransition,
  12. fadeTransition,
  13. decoratedBoxTransition
  14. }
  15. class AnimatedSplashScreen extends StatefulWidget {
  16. /// Type of page transition
  17. final PageTransitionType transitionType;
  18. /// Type of splash transition
  19. final SplashTransition splashTransition;
  20. /// Only required while using [AnimatedSplashScreen.withScreenFunction]
  21. /// here you pass your function that needs to be called before jumping
  22. /// on to the next screen
  23. final Future Function()? function;
  24. /// Custom animation to icon of splash
  25. final Animatable? customAnimation;
  26. /// Background color
  27. final Color backgroundColor;
  28. /// Compulsory in default constructor.
  29. /// Here you pass your widget that will be browsed
  30. final Widget? nextScreen;
  31. /// Type of AnimatedSplashScreen
  32. final SplashType type;
  33. /// to make the icon in [Center] of splash
  34. final bool centered;
  35. /// If you want to implement the navigation to the next page yourself.
  36. /// By default this is [false], the widget will call Navigator.of(_context).pushReplacement()
  37. /// using PageTransition with [transitionType] after [duration] to [nextScreen]
  38. final bool disableNavigation;
  39. /// It can be string for [Image.asserts], normal [Widget] or you can user tags
  40. /// to choose which one you image type, for example:
  41. /// * '[n]www.my-site.com/my-image.png' to [Image.network]
  42. final dynamic splash;
  43. /// Time in milliseconds after splash animation to jump to next screen
  44. /// Default is [milliseconds: 2500], minimum is [milliseconds: 100]
  45. final int duration;
  46. /// Curve of splash animation
  47. final Curve curve;
  48. /// Splash animation duration, default is [milliseconds: 800]
  49. final Duration? animationDuration;
  50. /// Size of an icon in splash screen
  51. final double? splashIconSize;
  52. /// Here you pass your route that will be browsed
  53. final String? nextRoute;
  54. factory AnimatedSplashScreen(
  55. {Curve curve = Curves.easeInCirc,
  56. Future Function()? function,
  57. int duration = 2500,
  58. required dynamic splash,
  59. required Widget nextScreen,
  60. Color backgroundColor = Colors.white,
  61. Animatable? customTween,
  62. bool centered = true,
  63. bool disableNavigation = false,
  64. SplashTransition? splashTransition,
  65. PageTransitionType? pageTransitionType,
  66. Duration? animationDuration,
  67. double? splashIconSize,
  68. String? nextRoute}) {
  69. return AnimatedSplashScreen._internal(
  70. backgroundColor: backgroundColor,
  71. animationDuration: animationDuration,
  72. transitionType: pageTransitionType ?? PageTransitionType.bottomToTop,
  73. splashTransition: splashTransition ?? SplashTransition.fadeTransition,
  74. splashIconSize: splashIconSize,
  75. customAnimation: customTween,
  76. function: function,
  77. nextRoute: nextRoute,
  78. duration: duration,
  79. centered: centered,
  80. disableNavigation: disableNavigation,
  81. splash: splash,
  82. type: SplashType.simpleSplash,
  83. nextScreen: nextScreen,
  84. curve: curve,
  85. );
  86. }
  87. factory AnimatedSplashScreen.withScreenFunction({
  88. Curve curve = Curves.easeInCirc,
  89. bool centered = true,
  90. bool disableNavigation = false,
  91. int duration = 2500,
  92. required dynamic splash,
  93. required Future<Widget> Function() screenFunction,
  94. Animatable? customTween,
  95. Color backgroundColor = Colors.white,
  96. SplashTransition? splashTransition,
  97. PageTransitionType? pageTransitionType,
  98. Duration? animationDuration,
  99. double? splashIconSize,
  100. }) {
  101. return AnimatedSplashScreen._internal(
  102. type: SplashType.backgroundScreenReturn,
  103. animationDuration: animationDuration,
  104. transitionType: pageTransitionType ?? PageTransitionType.bottomToTop,
  105. splashTransition: splashTransition ?? SplashTransition.fadeTransition,
  106. backgroundColor: backgroundColor,
  107. splashIconSize: splashIconSize,
  108. customAnimation: customTween,
  109. function: screenFunction,
  110. duration: duration,
  111. centered: centered,
  112. disableNavigation: disableNavigation,
  113. nextRoute: null,
  114. nextScreen: null,
  115. splash: splash,
  116. curve: curve,
  117. );
  118. }
  119. factory AnimatedSplashScreen.withScreenRouteFunction({
  120. Curve curve = Curves.easeInCirc,
  121. bool centered = true,
  122. bool disableNavigation = false,
  123. int duration = 2500,
  124. required dynamic splash,
  125. required Future<String> Function() screenRouteFunction,
  126. Animatable? customTween,
  127. Color backgroundColor = Colors.white,
  128. SplashTransition? splashTransition,
  129. PageTransitionType? pageTransitionType,
  130. Duration? animationDuration,
  131. double? splashIconSize,
  132. }) {
  133. return AnimatedSplashScreen._internal(
  134. type: SplashType.backgroundScreenReturn,
  135. animationDuration: animationDuration,
  136. transitionType: pageTransitionType ?? PageTransitionType.bottomToTop,
  137. splashTransition: splashTransition ?? SplashTransition.fadeTransition,
  138. backgroundColor: backgroundColor,
  139. splashIconSize: splashIconSize,
  140. customAnimation: customTween,
  141. function: screenRouteFunction,
  142. duration: duration,
  143. centered: centered,
  144. disableNavigation: disableNavigation,
  145. nextRoute: null,
  146. nextScreen: null,
  147. splash: splash,
  148. curve: curve,
  149. );
  150. }
  151. AnimatedSplashScreen._internal(
  152. {required this.animationDuration,
  153. required this.splashTransition,
  154. required this.customAnimation,
  155. required this.backgroundColor,
  156. required this.transitionType,
  157. required this.splashIconSize,
  158. required this.nextScreen,
  159. required this.function,
  160. required this.duration,
  161. required this.centered,
  162. required this.disableNavigation,
  163. required this.splash,
  164. required this.curve,
  165. required this.type,
  166. required this.nextRoute});
  167. @override
  168. _AnimatedSplashScreenState createState() => _AnimatedSplashScreenState();
  169. }
  170. class _AnimatedSplashScreenState extends State<AnimatedSplashScreen>
  171. with SingleTickerProviderStateMixin {
  172. late AnimationController _animationController;
  173. static late BuildContext _context;
  174. late Animation _animation;
  175. AnimatedSplashScreen get w => widget;
  176. @override
  177. void initState() {
  178. super.initState();
  179. _animationController = new AnimationController(
  180. duration: w.animationDuration ?? Duration(milliseconds: 800),
  181. vsync: this);
  182. Animatable animation = w.customAnimation ??
  183. () {
  184. switch (w.splashTransition) {
  185. case SplashTransition.slideTransition:
  186. return Tween<Offset>(
  187. end: Offset.zero,
  188. begin: Offset(1, 0),
  189. );
  190. case SplashTransition.decoratedBoxTransition:
  191. return DecorationTween(
  192. end: BoxDecoration(color: Colors.black87),
  193. begin: BoxDecoration(color: Colors.redAccent));
  194. default:
  195. return Tween(begin: 0.0, end: 1.0);
  196. }
  197. }() as Animatable<dynamic>;
  198. _animation = animation
  199. .animate(CurvedAnimation(parent: _animationController, curve: w.curve));
  200. _animationController.forward().then((value) => doTransition());
  201. }
  202. /// call function case needed and then jump to next screen
  203. doTransition() async {
  204. if (w.type == SplashType.backgroundScreenReturn)
  205. navigator(await w.function!());
  206. else if (!w.disableNavigation) navigator(w.nextRoute ?? w.nextScreen);
  207. }
  208. @override
  209. void dispose() {
  210. _animationController.reset();
  211. _animationController.dispose();
  212. super.dispose();
  213. }
  214. navigator(screen) {
  215. Future.delayed(Duration(milliseconds: w.duration < 100 ? 100 : w.duration))
  216. .then((_) {
  217. try {
  218. if (screen is String) {
  219. // Navigator.of(_context).pushReplacementNamed(screen);
  220. Get.offAllNamed(screen);
  221. } else {
  222. Get.offAll(screen);
  223. // Navigator.of(context).push(
  224. // MaterialPageRoute(
  225. // builder: (BuildContext context) {
  226. // return screen;
  227. // },
  228. // ),
  229. // );
  230. // Navigator.of(_context).pushReplacement(
  231. // PageTransition(type: w.transitionType, child: screen));
  232. }
  233. } catch (msg) {
  234. print('AnimatedSplashScreen -> '
  235. 'error in jump to next screen, probably '
  236. 'this run is in hot reload: $msg');
  237. }
  238. });
  239. }
  240. /// Return icon of splash screen
  241. Widget getSplash() {
  242. final size =
  243. w.splashIconSize ?? MediaQuery.of(context).size.shortestSide * 0.2;
  244. Widget main({required Widget child}) =>
  245. w.centered ? Center(child: child) : child;
  246. return getTransition(
  247. child: main(
  248. child: SizedBox(
  249. height: size,
  250. child: w.splash is String
  251. ? <Widget>() {
  252. if (w.splash.toString().contains('[n]'))
  253. return Image.network(
  254. w.splash.toString().replaceAll('[n]', ''));
  255. else
  256. return Image.asset(w.splash);
  257. }()
  258. : (w.splash is IconData
  259. ? Icon(w.splash, size: size)
  260. : w.splash))));
  261. }
  262. /// return transtion
  263. Widget getTransition({required Widget child}) {
  264. switch (w.splashTransition) {
  265. case SplashTransition.slideTransition:
  266. return SlideTransition(
  267. position: (_animation as Animation<Offset>), child: child);
  268. case SplashTransition.scaleTransition:
  269. return ScaleTransition(
  270. scale: (_animation as Animation<double>), child: child);
  271. case SplashTransition.rotationTransition:
  272. return RotationTransition(
  273. turns: (_animation as Animation<double>), child: child);
  274. case SplashTransition.sizeTransition:
  275. return SizeTransition(
  276. sizeFactor: (_animation as Animation<double>), child: child);
  277. case SplashTransition.fadeTransition:
  278. return FadeTransition(
  279. opacity: (_animation as Animation<double>), child: child);
  280. case SplashTransition.decoratedBoxTransition:
  281. return DecoratedBoxTransition(
  282. decoration: (_animation as Animation<Decoration>), child: child);
  283. default:
  284. return FadeTransition(
  285. opacity: (_animation as Animation<double>), child: child);
  286. }
  287. }
  288. @override
  289. Widget build(BuildContext context) {
  290. _context = context;
  291. return Scaffold(backgroundColor: w.backgroundColor, body: getSplash());
  292. }
  293. }