dialog_check_text.dart 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:trackoffical_app/logger.dart';
  4. import 'package:trackoffical_app/screen.dart';
  5. import '../../../styles/theme.dart';
  6. import 'dialog_base.dart';
  7. class DialogCheckText extends StatefulWidget {
  8. const DialogCheckText({
  9. super.key,
  10. required
  11. this.text,
  12. required this.color,
  13. this.autoPlayAfter,
  14. this.closeAfterPlay=true,
  15. this.beanCount,
  16. this.onStop,
  17. });
  18. final String text;
  19. final Color color;
  20. final Duration? autoPlayAfter;
  21. final bool closeAfterPlay;
  22. final int? beanCount;
  23. final VoidCallback? onStop;
  24. @override
  25. State<StatefulWidget> createState() {
  26. return DialogCheckTextState();
  27. }
  28. }
  29. class DialogCheckTextState extends State<DialogCheckText>
  30. with SingleTickerProviderStateMixin{
  31. AnimationController? _animationController;
  32. Animation<double?>? _animation;
  33. static const milliseconds = 400;
  34. var willClose =false;
  35. var isActive=true;
  36. @override
  37. void initState() {
  38. super.initState();
  39. if(widget.autoPlayAfter!= null){
  40. widget.autoPlayAfter!.delay(onClick);
  41. }
  42. }
  43. @override
  44. Widget build(BuildContext context) {
  45. final maxFontSize = 28.5.wp;
  46. var alpha = 255;
  47. var fontSize = 11.2.wp;
  48. final v = _animation?.value;
  49. var beanAlpha = 1.0;
  50. var beanSize = 9.92.wp;
  51. final maxBeanSize = 18.0.wp;
  52. if(v!= null){
  53. alpha -= (v *255).round();
  54. var d = (maxFontSize - fontSize);
  55. fontSize += d * v;
  56. beanAlpha -= v;
  57. d = (maxBeanSize - beanSize);
  58. beanSize += d * v;
  59. }
  60. final children = <Widget>[];
  61. if(widget.text.isNotEmpty){
  62. children.add(
  63. Container(
  64. height: 41.22.wp,
  65. alignment: Alignment.center,
  66. child: Text(
  67. widget.text,
  68. style: context.textTheme.titleLarge?.copyWith(
  69. color: widget.color.withAlpha( alpha),
  70. fontSize: fontSize,
  71. fontWeight: FontWeight.w700),
  72. maxLines: 1,
  73. )
  74. )
  75. );
  76. }
  77. final beanCount = widget.beanCount;
  78. if(beanCount!= null){
  79. if(widget.text.isNotEmpty){
  80. children.add(SizedBox(height: 7.64.wp,));
  81. }
  82. children.add(Container(
  83. height: 45.0.wp,
  84. alignment: Alignment.center,
  85. child: Opacity(
  86. opacity: beanAlpha,
  87. child: bean(beanCount, beanSize),
  88. ) ,
  89. ) );
  90. }
  91. return GestureDetector(
  92. onTap: onClick,
  93. child: Container(
  94. width: context.width,
  95. height: context.height,
  96. color: const Color(0xB8000000),
  97. alignment: Alignment.center,
  98. child: DefaultTextStyle(
  99. style: context.textTheme.titleLarge??const TextStyle(),
  100. child: Column(
  101. mainAxisSize: MainAxisSize.min,
  102. children: children,
  103. )
  104. )
  105. ),
  106. ) ;
  107. }
  108. void onClick(){
  109. if(willClose){
  110. return;
  111. }
  112. willClose=true;
  113. doClick();
  114. }
  115. Future<void> doClick()async{
  116. if(!isActive){
  117. return;
  118. }
  119. _animationController = AnimationController(
  120. vsync: this,
  121. duration: const Duration(milliseconds: milliseconds),
  122. reverseDuration: const Duration(milliseconds: milliseconds),
  123. )..repeat(reverse: false);
  124. _animation =Tween<double>(begin: 0, end: 1)
  125. .animate(_animationController!)
  126. ..addListener(() {
  127. setState(() {
  128. // The state that has changed here is the animation object’s value.
  129. });
  130. });
  131. await Future.delayed(milliseconds.milliseconds);
  132. _animationController?.dispose();
  133. _animationController=null;
  134. widget.onStop?.call();
  135. if(mounted&&Get.isOverlaysOpen&&widget.closeAfterPlay){
  136. debug('${widget.runtimeType} back');
  137. Get.back();
  138. }
  139. }
  140. @override
  141. void dispose() {
  142. super.dispose();
  143. isActive=false;
  144. _animationController?.dispose();
  145. _animationController=null;
  146. }
  147. }
  148. class _Empty extends StatelessWidget {
  149. @override
  150. Widget build(BuildContext context) {
  151. SizeFit.screenInit(context);
  152. return const Scaffold(
  153. floatingActionButton: FloatingActionButton(onPressed: _showDialog),
  154. );
  155. }
  156. }
  157. Future<void> _showDialog() async {
  158. if (Get.isOverlaysOpen) {
  159. Get.back();
  160. }
  161. Get.dialog(DialogCheckText(
  162. text: '打点错误',
  163. color: Colors.red,
  164. beanCount: 1,
  165. ));
  166. }
  167. void main() async {
  168. runApp(GetMaterialApp(theme: appThemeData(), home: _Empty()));
  169. }