import 'package:animated_text_kit/animated_text_kit.dart'; import 'package:dreampad/app/shared/shared.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import '../controllers/question_controller.dart'; class QuestionView extends GetView { const QuestionView({super.key}); @override @override Widget build(BuildContext context) { return MaterialApp( home: Container( decoration: const BoxDecoration( image: DecorationImage( image: Images.questionBg, fit: BoxFit.fill, ), ), child: Scaffold( backgroundColor: Colors.transparent, body: buildBody(context), ), ), ); } Widget buildBody(BuildContext context) { return HookBuilder(builder: (context) { final isReady = useState(false); final isIpShown = useState(false); useMemoized(() async { await Future.delayed(const Duration(milliseconds: 500)); isReady.value = true; }); return Obx( () => Stack( children: [ Positioned( top: 38.h, left: 30.w, child: MyBackButton( onPressed: () { Get.back(); }, ), ), AnimatedPositioned( duration: const Duration(milliseconds: 500), curve: Curves.easeIn, top: controller.ipTop.value.h, left: controller.ipLeft.value.w, child: AnimatedVisibilityWidget( isVisible: isReady.value, animationWidgetBuilder: AnimatedVisibilityWidget.fadeAnimationWidgetBuilder, onDone: (_) async { await Future.delayed(const Duration(milliseconds: 300)); isIpShown.value = true; }, child: Images.ip, ), ), Positioned( top: 78.h, left: 451.w, child: AnimatedVisibilityWidget( animationWidgetBuilder: AnimatedVisibilityWidget.fadeAnimationWidgetBuilder, isVisible: isIpShown.value && !controller.allAnswer.value, child: buildDialog(context)), ), RSizedBox( child: Stack( children: controller.questionAnswers.map((element) { if (element.value.display!) { return Positioned( top: element.value.top!.h, left: element.value.left!.w, child: _ShowUp( key: ValueKey(element.value.answer), child: buildAnswer( context, element.value.index!, element.value.answer!, ), ), ); } else { return Container(); } }).toList()), ), Positioned( bottom: 3.h, left: 416.w, child: AnimatedVisibilityWidget( isVisible: controller.allAnswer.value, duration: const Duration(milliseconds: 500), child: Images.questionRecommended, ), ), ], ), ); }); } Widget buildAnswer(BuildContext context, int index, String answer) { return Container( width: 369.w, height: 160.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.questionAnswer, fit: BoxFit.fill, ), ), child: Stack( children: [ Positioned( top: 23.h, left: 68.w, child: Text( index.toString(), style: TextStyles.boldColor24, ), ), Positioned( top: 25.h, left: 105.w, child: Text( '问题回答', style: TextStyles.boldColor20, ), ), Positioned( top: 65.h, left: 85.w, child: RSizedBox( height: 64.h, width: 230.w, child: Text( answer, style: TextStyles.mediumWhite18, ), ), ), ], ), ); } Widget buildDialog(BuildContext context) { return Obx( () => AnimatedSwitcher( duration: const Duration(milliseconds: 500), child: KeyedSubtree( key: ValueKey(controller.question.value), child: HookBuilder(builder: (context) { final isReady = useState(false); final isDialogShown = useState(false); final isTextShown = useState(false); useMemoized(() async { await Future.delayed(const Duration(milliseconds: 500)); isReady.value = true; }); return AnimatedVisibilityWidget( isVisible: isReady.value, isInitAnimated: true, animationWidgetBuilder: AnimatedVisibilityWidget.fadeAnimationWidgetBuilder, duration: const Duration(milliseconds: 500), onDone: (_) async { await Future.delayed(const Duration(milliseconds: 500)); isDialogShown.value = true; }, child: Container( width: 464.w, height: 270.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.questionDialog, fit: BoxFit.fill, ), ), padding: REdgeInsets.only(top: 45.0, left: 45.0, right: 45.0), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: SizedBox( width: double.infinity, child: Visibility( visible: isDialogShown.value, child: AnimatedTextKit( totalRepeatCount: 1, pause: Duration.zero, onFinished: () { isTextShown.value = true; }, animatedTexts: [ TypewriterAnimatedText( controller.question.value, textStyle: TextStyles.mediumWhiteShadow18_034, cursor: '', speed: const Duration(milliseconds: 150), textAlign: TextAlign.start, ) ], ), ), ), ), SizedBox(height: 16.h), AnimatedVisibilityWidget( isVisible: isTextShown.value, animationWidgetBuilder: AnimatedVisibilityWidget.fadeAnimationWidgetBuilder, child: ImageTxtButton( text: controller.btnTxt.value, imgName: 'question/btn_icon_begin', textStyle: TextStyles.boldWhite20_014, width: 186.0, height: 54.0, onPressed: () async { await controller.setStep(); if (controller.showQuestionDialog.value) { SmartDialog.show( alignment: Alignment.topCenter, onDismiss: () async { FocusScope.of(context).requestFocus(); if (controller.textController.text.isNotEmpty) { await controller.updateAnswer( controller.textController.text); } }, maskColor: const Color(0xFF080F3D).withOpacity(0.8), builder: (_) { return HookBuilder(builder: (context) { useMemoized(() async { final guide = controller.guide.value; for (int i = 0; i < guide.length + 1; i++) { controller.textController.text = guide.substring(0, i); await Future.delayed( const Duration(milliseconds: 80)); } }); return QuestionDialog( question: controller.question.value, controller: controller.textController, ); }); }, ); } }, ), ), const RSizedBox( height: 64, ), ], ), ), ); }), ), ), ); } } class _ShowUp extends HookWidget { const _ShowUp({ super.key, required this.child, }); final Widget child; @override Widget build(BuildContext context) { final controller = useAnimationController(duration: const Duration(milliseconds: 300)); useMemoized(() { controller.forward(); }); return FadeTransition( opacity: CurvedAnimation(curve: Curves.easeIn, parent: controller), child: child, ); } }