使用: LoadingView.showSerially(context); LoadingView.showDiscrete(context); 源码: LoadingView.showSerially(context);
import 'dart:async'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'dart:math' as math; class LoadingView { static LoadingView _instance; static LoadingView instance() { if(_instance == null) { _instance = LoadingView(); } return _instance; } SeriallyLoadingView _seriallyLoadingView; DiscreteLoadingView _discreteLoadingView; OverlayEntry _discreteOverlayEntry; OverlayEntry _seriallyOverlayEntry; int _rotationType = 0; OverlayEntry discreteOverlayEntry() { if(_discreteOverlayEntry == null) { _discreteOverlayEntry = _createDiscreteOverlayEntry(); } return _discreteOverlayEntry; } OverlayEntry seriallyOverlayEntry() { if(_seriallyOverlayEntry == null) { _seriallyOverlayEntry = _createSeriallyOverlayEntry(); } return _seriallyOverlayEntry; } OverlayEntry _createSeriallyOverlayEntry() { return OverlayEntry( builder: (BuildContext context) { return Scaffold( backgroundColor: Colors.transparent, body: _seriallyLoadingView, ); } ); } OverlayEntry _createDiscreteOverlayEntry() { return OverlayEntry( builder: (BuildContext context) { return Scaffold( backgroundColor: Colors.transparent, body: _discreteLoadingView, ); } ); } static show(BuildContext context) { instance()._seriallyLoadingView = SeriallyLoadingView(); Overlay.of(context).insert(instance().seriallyOverlayEntry()); } /// 不连续的,间断地,默认旋转角22.5 static showDiscrete(BuildContext context) { instance()._rotationType = 1; instance()._discreteLoadingView = DiscreteLoadingView(); Overlay.of(context).insert(instance().discreteOverlayEntry()); } static showSerially(BuildContext context) { instance()._rotationType = 0; instance()._seriallyLoadingView = SeriallyLoadingView(); Overlay.of(context).insert(instance().seriallyOverlayEntry()); } static hide() { if(instance()._rotationType == 1) { instance().discreteOverlayEntry().remove(); instance()._discreteLoadingView.stopAnimation(); } else { instance().seriallyOverlayEntry().remove(); instance()._seriallyLoadingView.stopAnimation(); } } } class SeriallyLoadingView extends StatefulWidget { void stopAnimation() { _loadingState.stopAnimation(); } final _loadingState = _SeriallyLoadingViewState(); @override State<StatefulWidget> createState() { return _loadingState; } } class _SeriallyLoadingViewState extends State<StatefulWidget> with SingleTickerProviderStateMixin { AnimationController _animationController; @override void initState() { super.initState(); _animationController = AnimationController( vsync: this, duration: Duration(milliseconds: 600), ); _animationController.forward(); _animationController.repeat(); } void stopAnimation() { _animationController.stop(); } @override Widget build(BuildContext context) { return Center( child: RotationTransition( turns: _animationController, alignment: Alignment.center, child: Container( width: 40, height: 40, child: Image.asset("resource/images/other/loading3.png"), ), ), ); } } class DiscreteLoadingView extends StatefulWidget { void stopAnimation() { _state.stopAnimation(); } final _state = _DiscreteLoadingViewState(); @override State<StatefulWidget> createState() { return _state; } } class _DiscreteLoadingViewState extends State<DiscreteLoadingView> { double _angle = 0; Timer _timer; int rotateIndex = 0; @override void initState() { super.initState(); _timer = Timer.periodic(Duration(milliseconds: 50), timerCallBack); } void timerCallBack(Timer timer) { rotateIndex ++; rotateIndex %= 15; setState(() { _angle = rotateIndex * math.pi / 8; }); } void stopAnimation() { _timer.cancel(); } @override Widget build(BuildContext context) { return Center( child: Transform.rotate( angle: _angle, child: Container( width: 40, height: 40, child: Image.asset("resource/images/other/loading.png"), ), ), ); } }