status_bar.dart 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:vitalapp/architecture/network_connectivity.dart';
  4. import 'package:vitalapp/global.dart';
  5. import 'package:vitalapp/pages/help/help_dialog.dart';
  6. import 'package:fis_common/logger/logger.dart';
  7. class HeaderStatusBar extends StatelessWidget {
  8. const HeaderStatusBar({super.key});
  9. @override
  10. Widget build(BuildContext context) {
  11. return Row(
  12. mainAxisSize: MainAxisSize.min,
  13. crossAxisAlignment: CrossAxisAlignment.center,
  14. mainAxisAlignment: MainAxisAlignment.center,
  15. children: [
  16. _NetStatusWidget(),
  17. const SizedBox(width: 2),
  18. IconButton(
  19. onPressed: () {
  20. HelpDialog.show();
  21. },
  22. padding: EdgeInsets.all(0),
  23. icon: const Icon(Icons.help, size: 36, color: Colors.white),
  24. ),
  25. ],
  26. );
  27. }
  28. }
  29. class _NetStatusWidget extends StatefulWidget {
  30. @override
  31. State<StatefulWidget> createState() => _NetStatusWidgetState();
  32. }
  33. class _NetStatusWidgetState extends State<_NetStatusWidget> {
  34. Timer? _waitTimer;
  35. bool _isOnline = false;
  36. @override
  37. void initState() {
  38. super.initState();
  39. _isOnline = kIsOnline;
  40. WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
  41. netChecker.onlineChangedEvent.addListener(_onlineChanged);
  42. });
  43. }
  44. @override
  45. void dispose() {
  46. netChecker.onlineChangedEvent.removeListener(_onlineChanged);
  47. super.dispose();
  48. }
  49. void _onlineChanged(_, e) {
  50. if (_isOnline == e) {
  51. return;
  52. }
  53. setState(() {
  54. _isOnline = e;
  55. if (e) {
  56. _stopWaitNetRecover();
  57. } else {
  58. _waitNetRecover();
  59. }
  60. });
  61. }
  62. void _waitNetRecover() {
  63. if (_waitTimer != null) {
  64. return;
  65. }
  66. logger.i("HeaderStatusBar - Wait network start.");
  67. print("HeaderStatusBar - Wait network start.");
  68. _waitTimer = Timer(const Duration(milliseconds: 5 * 1000), () {
  69. setState(() {
  70. _waitTimer = null;
  71. });
  72. logger.i("HeaderStatusBar - Wait network done.");
  73. print("HeaderStatusBar - Wait network done.");
  74. });
  75. }
  76. void _stopWaitNetRecover() {
  77. if (_waitTimer != null) {
  78. _waitTimer?.cancel();
  79. _waitTimer = null;
  80. logger.i("HeaderStatusBar - Wait network abort.");
  81. print("HeaderStatusBar - Wait network abort.");
  82. }
  83. }
  84. @override
  85. Widget build(BuildContext context) {
  86. if (_isOnline) {
  87. return const Tooltip(
  88. triggerMode: TooltipTriggerMode.tap,
  89. message: "网络已连接",
  90. child: Icon(Icons.wifi, size: 36, color: Colors.green),
  91. );
  92. } else {
  93. if (_waitTimer == null) {
  94. return const Tooltip(
  95. triggerMode: TooltipTriggerMode.tap,
  96. message: "网络已断开",
  97. child: Icon(Icons.wifi_off_outlined, size: 36, color: Colors.red),
  98. );
  99. } else {
  100. return Tooltip(
  101. triggerMode: TooltipTriggerMode.tap,
  102. message: "网络等待中",
  103. child: SizedBox(
  104. width: 36,
  105. height: 36,
  106. child: _NetWaitingWidget(),
  107. ),
  108. );
  109. }
  110. }
  111. }
  112. }
  113. class _NetWaitingWidget extends StatefulWidget {
  114. @override
  115. State<_NetWaitingWidget> createState() => _NetWaitingWidgetState();
  116. }
  117. class _NetWaitingWidgetState extends State<_NetWaitingWidget> {
  118. static final _color = Colors.orange.shade200;
  119. bool _isShow = false;
  120. Timer? _timer;
  121. @override
  122. void initState() {
  123. super.initState();
  124. WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
  125. _timer = Timer.periodic(const Duration(milliseconds: 1000), (timer) {
  126. setState(() {
  127. _isShow = !_isShow;
  128. });
  129. });
  130. });
  131. }
  132. @override
  133. void dispose() {
  134. _timer?.cancel();
  135. _timer = null;
  136. super.dispose();
  137. }
  138. @override
  139. Widget build(BuildContext context) {
  140. return Stack(
  141. children: [
  142. Icon(
  143. Icons.wifi,
  144. size: 36,
  145. color: _isShow ? _color : _color.withOpacity(.4),
  146. ),
  147. const Center(
  148. child: Padding(
  149. padding: EdgeInsets.all(8),
  150. child: CircularProgressIndicator(
  151. strokeWidth: 4,
  152. color: Colors.white,
  153. ),
  154. ),
  155. ),
  156. ],
  157. );
  158. }
  159. }