import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:trackoffical_app/logger.dart'; import 'package:trackoffical_app/screen.dart'; import '../../../styles/theme.dart'; import 'dialog_base.dart'; class DialogCheckText extends StatefulWidget { const DialogCheckText({ super.key, required this.text, required this.color, this.autoPlayAfter, this.closeAfterPlay=true, this.beanCount, this.onStop, }); final String text; final Color color; final Duration? autoPlayAfter; final bool closeAfterPlay; final int? beanCount; final VoidCallback? onStop; @override State createState() { return DialogCheckTextState(); } } class DialogCheckTextState extends State with SingleTickerProviderStateMixin{ AnimationController? _animationController; Animation? _animation; static const milliseconds = 400; var willClose =false; var isActive=true; @override void initState() { super.initState(); if(widget.autoPlayAfter!= null){ widget.autoPlayAfter!.delay(onClick); } } @override Widget build(BuildContext context) { final maxFontSize = 28.5.wp; var alpha = 255; var fontSize = 11.2.wp; final v = _animation?.value; var beanAlpha = 1.0; var beanSize = 9.92.wp; final maxBeanSize = 18.0.wp; if(v!= null){ alpha -= (v *255).round(); var d = (maxFontSize - fontSize); fontSize += d * v; beanAlpha -= v; d = (maxBeanSize - beanSize); beanSize += d * v; } final children = []; if(widget.text.isNotEmpty){ children.add( Container( height: 41.22.wp, alignment: Alignment.center, child: Text( widget.text, style: context.textTheme.titleLarge?.copyWith( color: widget.color.withAlpha( alpha), fontSize: fontSize, fontWeight: FontWeight.w700), maxLines: 1, ) ) ); } final beanCount = widget.beanCount; if(beanCount!= null){ if(widget.text.isNotEmpty){ children.add(SizedBox(height: 7.64.wp,)); } children.add(Container( height: 45.0.wp, alignment: Alignment.center, child: Opacity( opacity: beanAlpha, child: bean(beanCount, beanSize), ) , ) ); } return GestureDetector( onTap: onClick, child: Container( width: context.width, height: context.height, color: const Color(0xB8000000), alignment: Alignment.center, child: DefaultTextStyle( style: context.textTheme.titleLarge??const TextStyle(), child: Column( mainAxisSize: MainAxisSize.min, children: children, ) ) ), ) ; } void onClick(){ if(willClose){ return; } willClose=true; doClick(); } Future doClick()async{ if(!isActive){ return; } _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: milliseconds), reverseDuration: const Duration(milliseconds: milliseconds), )..repeat(reverse: false); _animation =Tween(begin: 0, end: 1) .animate(_animationController!) ..addListener(() { setState(() { // The state that has changed here is the animation object’s value. }); }); await Future.delayed(milliseconds.milliseconds); _animationController?.dispose(); _animationController=null; widget.onStop?.call(); if(mounted&&Get.isOverlaysOpen&&widget.closeAfterPlay){ debug('${widget.runtimeType} back'); Get.back(); } } @override void dispose() { super.dispose(); isActive=false; _animationController?.dispose(); _animationController=null; } } class _Empty extends StatelessWidget { @override Widget build(BuildContext context) { SizeFit.screenInit(context); return const Scaffold( floatingActionButton: FloatingActionButton(onPressed: _showDialog), ); } } Future _showDialog() async { if (Get.isOverlaysOpen) { Get.back(); } Get.dialog(DialogCheckText( text: '打点错误', color: Colors.red, beanCount: 1, )); } void main() async { runApp(GetMaterialApp(theme: appThemeData(), home: _Empty())); }