import 'package:animated_text_kit/animated_text_kit.dart'; import 'package:dreampad/app/modules/select/views/animated_horizon_column_widget.dart'; import 'package:dreampad/app/routes/app_pages.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/select_controller.dart'; class SelectView extends GetView { const SelectView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: Container( decoration: const BoxDecoration( image: DecorationImage( image: Images.selectBg, fit: BoxFit.fill, ), ), child: Obx( () => Scaffold( backgroundColor: Colors.transparent, body: AnimatedSwitcher( duration: const Duration(milliseconds: 300), child: KeyedSubtree( key: ValueKey(controller.confirm.value), child: controller.confirm.value ? buildConfirm(context) : buildSelect(context), ), ), ), ), ), ); } Widget buildSelect(BuildContext context) { return Stack( children: [ Positioned( top: 2.h, left: 412.w, child: _ShowUp( child: Container( width: 360.w, height: 164.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.selectTitle1, fit: BoxFit.fill, ), ), padding: REdgeInsets.only(left: 113.0, top: 70.0), child: Text( '梦想职业', style: TextStyles.boldWhiteShadow34_200, ), ), ), ), buildSelectOccupation(context), ], ); } Widget buildSelectOccupation(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Obx( () => AnimatedSwitcher( duration: const Duration(milliseconds: 300), child: OccupationListWidget( key: ValueKey( controller.selectOccupations.first.value.name ?? ''), keyBuilder: (index) => controller.selectOccupations[index].value.name ?? '', children: controller.selectOccupations.map((t) { return GestureDetector( key: ValueKey(t.value.id), onTap: () async { if (t.value.enable!) { await controller.selectedOccupation(t.value); } else { SmartDialog.showToast('开发中,敬请期待…'); } }, child: Container( width: 218.w, height: 366.h, decoration: BoxDecoration( color: const Color(0xFF4A3FAE).withOpacity(0.6), ), padding: REdgeInsets.all(6.0), child: Stack( children: [ LoadAssetImage( 'select/${t.value.vImage}', height: 354.h, width: 206.w, fit: BoxFit.fill, ), LoadAssetImage( 'select/${t.value.id == controller.selectOccupation.value?.id! || t.value.selected! ? 'label_state_pre' : 'label_state_default'}', height: 354.h, width: 206.w, fit: BoxFit.fill, ), t.value.id == controller.selectOccupation.value?.id! ? LoadAssetImage( 'select/btn_icon_selected', height: 65.h, width: 65.w, ) : Container(), Positioned( bottom: 43.h, left: 13.w, child: Text( t.value.enName!.toUpperCase(), style: TextStyles.pmzdWhiteShadow22_022, ), ), Positioned( bottom: 8.h, left: 14.w, child: Text( t.value.name!, style: TextStyles.pmzdWhiteShadow26_022, ), ), ], ), ), ); }).toList(), ), ), ), buildSelectChange(context), ], ), const RSizedBox(height: 14.0), buildSelectBtn(context), const RSizedBox(height: 50.0), ], ); } Widget buildSelectBtn(BuildContext context) { return Obx( () => Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _ShowUp( child: ImageTxtButton( text: '还没想好', imgName: 'select/btn_bg', textStyle: TextStyles.mediumWhiteShadow28_022, width: 264.0, height: 80.0, onPressed: () async { var data = await Get.toNamed(Routes.QUESTION); if (data != null) { await controller.recommendOccupation(int.parse(data['id'])); } }, ), ), const RSizedBox(width: 34.0), _ShowUp( child: ImageTxtButton( text: '输入我的想法', imgName: 'select/btn_bg', textStyle: TextStyles.mediumWhiteShadow28_022, width: 264.0, height: 80.0, onPressed: () { SmartDialog.showToast('开发中,敬请期待…'); }, ), ), const RSizedBox(width: 34.0), AnimatedVisibilityWidget( isVisible: controller.selectOccupation.value != null, child: ImageTxtButton( text: '决定了', imgName: 'select/btn_icon_confirm', textStyle: TextStyles.mediumWhiteShadow28_022, width: 264.0, height: 80.0, onPressed: () async { controller.confimSelected(); }, ), ), ], ), ); } Widget buildSelectChange(BuildContext context) { return _ShowUp( child: GestureDetector( onTap: () async { await controller.change(); }, child: Padding( padding: REdgeInsets.only(left: 6), child: Container( width: 72.w, height: 364.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.selectChange, fit: BoxFit.fill, ), ), child: Center( child: Text( '换一批', style: TextStyles.mediumColorShadow16_032, ), ), ), ), ), ); } Widget buildConfirm(BuildContext context) { return _ShowUp( child: Obx( () => Stack( children: [ Positioned( left: 90.w, top: 62.h, child: Container( width: 999.w, height: 558.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.selectBgBorder, fit: BoxFit.fill, ), ), padding: REdgeInsets.only( top: 13.0, left: 13.0, bottom: 10.0, right: 16.0), child: LoadAssetImage( 'select/${controller.selectOccupation.value!.hImage!}', height: 534.h, width: 971.w, fit: BoxFit.fill, ), ), ), Positioned( top: 64.h, left: 363.w, child: Container( width: 450.w, height: 61.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.selectTitle2, fit: BoxFit.fill, ), ), child: Center( child: Text( controller.confirmTitle.value, style: TextStyles.boldWhiteShadow34_200, ), ), ), ), controller.recommend.value ? buildRecommendConfirmBtn( context, controller.selectOccupation.value!.name!) : buildConfirmBtn( context, controller.selectOccupation.value!.name!), controller.showOccupationName.value ? Container() : Positioned( left: 90.w, top: 62.h, child: Container( width: 999.w, height: 558.h, color: const Color(0x8C02184B), ), ), 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( top: 207.h, left: 378.w, child: AnimatedVisibilityWidget( animationWidgetBuilder: AnimatedVisibilityWidget.fadeAnimationWidgetBuilder, isVisible: !controller.allAnswer.value && !controller.showOccupationName.value, child: buildDialog(context)), ), ], ), ), ); } Widget buildRecommendConfirmBtn(BuildContext context, String name) { return Positioned( bottom: 12.h, left: 243.w, child: Container( width: 713.w, height: 222.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.selectBgShadow, fit: BoxFit.fill, ), ), child: Stack( children: [ Positioned( left: 88.w, top: 90.h, child: GestureDetector( onTap: () { controller.confirm.value = false; }, child: Container( width: 285.w, height: 45.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.selectBgReflect, fit: BoxFit.fill, ), ), padding: REdgeInsets.only(left: 40.0, top: 5.0), child: Text( '我再想想', style: TextStyles.mediumWhite22_012_2, ), ), ), ), Positioned( right: 87.w, top: 90.h, child: GestureDetector( onTap: () async { await controller.openDream(); }, child: Container( width: 258.w, height: 45.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.selectBgGenerate, fit: BoxFit.fill, ), ), padding: REdgeInsets.only(left: 92.0, top: 5.0), child: Text( '生成梦之建木', style: TextStyles.mediumWhite22_012_2, ), ), ), ), Positioned( left: 221.w, top: 60.h, child: Container( width: 242.w, height: 98.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.selectBgCareer, fit: BoxFit.fill, ), ), child: Center( child: Text( name, style: TextStyles.boldWhiteShadow28_110, ), ), ), ), ], ), ), ); } Widget buildConfirmBtn(BuildContext context, String name) { return Positioned( bottom: 18.h, left: 243.w, child: Container( width: 713.w, height: 214.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.selectBgShadow, fit: BoxFit.fill, ), ), child: Obx( () => Stack( children: [ controller.showBtn.value ? Positioned( left: 88.w, top: 77.h, child: ImageTxtButton( text: '我再想想', imgName: 'select/btn_bg_reflect_1', textStyle: TextStyles.mediumWhiteShadow28_013, width: 264.0, height: 80.0, onPressed: () async { await controller.reflect(); }, ), ) : Container(), controller.showBtn.value ? Positioned( right: 66.w, top: 77.h, child: ImageTxtButton( text: '生成梦之建木', imgName: 'select/btn_bg_generate_1', textStyle: TextStyles.mediumWhiteShadow28_013, width: 264.0, height: 80.0, onPressed: () async { await controller.openDream(); }, ), ) : Container(), controller.showOccupationName.value ? Positioned( left: 208.w, top: 19.h, child: ImageTxtButton( text: name, imgName: 'select/label_bg_career_1', textStyle: TextStyles.mediumWhiteShadow28_113, width: 324.0, height: 45.0, ), ) : Container(), ], ), ), ), ); } Widget buildAnswer(BuildContext context, int index, String answer) { return Container( width: 369.w, height: 160.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.selectAnswer, 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: 444.w, height: 248.h, decoration: const BoxDecoration( image: DecorationImage( image: Images.selectDialog, fit: BoxFit.fill, ), ), padding: REdgeInsets.only(top: 28.0, left: 27.0, right: 63.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(() async { await Future.delayed(const Duration(milliseconds: 300)); controller.forward(); }); return FadeTransition( opacity: CurvedAnimation(curve: Curves.easeIn, parent: controller), child: child, ); } }