Merge remote-tracking branch 'origin/yuanjunyao_dev' into yuanjunyao_dev
This commit is contained in:
commit
d6ea57859c
BIN
assets/images/select/btn_bg_generate_1.png
Normal file
BIN
assets/images/select/btn_bg_generate_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
assets/images/select/btn_bg_reflect_1.png
Normal file
BIN
assets/images/select/btn_bg_reflect_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
assets/images/select/btn_icon_begin.png
Normal file
BIN
assets/images/select/btn_icon_begin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
assets/images/select/label_bg_answer.png
Normal file
BIN
assets/images/select/label_bg_answer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
BIN
assets/images/select/label_bg_career_1.png
Normal file
BIN
assets/images/select/label_bg_career_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
assets/images/select/pic_dialogue_type.png
Normal file
BIN
assets/images/select/pic_dialogue_type.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
@ -4,3 +4,4 @@ export 'base_response_model.dart';
|
||||
export 'token_model.dart';
|
||||
export 'page_result_model.dart';
|
||||
export 'goal_model.dart';
|
||||
export 'question_answer_model.dart';
|
@ -1,11 +1,10 @@
|
||||
// ignore_for_file: unnecessary_overrides
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:dreampad/app/models/models.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../models/question_answer_model.dart';
|
||||
|
||||
class QuestionController extends GetxController {
|
||||
final step = 0.obs;
|
||||
final ipLeft = 149.obs;
|
||||
|
@ -1,8 +1,10 @@
|
||||
// ignore_for_file: unnecessary_overrides
|
||||
|
||||
import 'package:dreampad/app/models/models.dart';
|
||||
import 'package:dreampad/app/routes/app_pages.dart';
|
||||
import 'package:dreampad/app/shared/shared.dart';
|
||||
import 'package:flustars_flutter3/flustars_flutter3.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../models/occupation_model.dart';
|
||||
@ -11,11 +13,22 @@ class SelectController extends GetxController {
|
||||
late int gender = 2;
|
||||
late int count = 4;
|
||||
late int page = 0;
|
||||
final step = 0.obs;
|
||||
final question = ''.obs;
|
||||
final guide = ''.obs;
|
||||
final btnTxt = '我要回答'.obs;
|
||||
final allAnswer = false.obs;
|
||||
final showQuestionDialog = false.obs;
|
||||
late List<Occupation> occupations = [];
|
||||
final confirm = false.obs;
|
||||
final confirmTitle = '为你推荐的梦想职业是'.obs;
|
||||
final recommend = false.obs;
|
||||
final showBtn = false.obs;
|
||||
final showOccupationName = false.obs;
|
||||
final selectOccupation = Rx<Occupation?>(null);
|
||||
final selectOccupations = RxList<Rx<Occupation>>([]);
|
||||
final questionAnswers = RxList<Rx<QuestionAnswer>>([]);
|
||||
final TextEditingController textController = TextEditingController();
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
@ -26,6 +39,24 @@ class SelectController extends GetxController {
|
||||
initMaleOccupation();
|
||||
}
|
||||
changeOccupation();
|
||||
questionAnswers.add(QuestionAnswer(
|
||||
index: 1,
|
||||
left: 110.0,
|
||||
top: 147.0,
|
||||
question: '很酷的选择!能告诉我为什么选择这个梦想的职业吗?',
|
||||
display: false,
|
||||
answer: '',
|
||||
guide: '我想成为下一个“爱因斯坦”,他被称为最聪明的人',
|
||||
).obs);
|
||||
questionAnswers.add(QuestionAnswer(
|
||||
index: 2,
|
||||
left: 720.0,
|
||||
top: 425.0,
|
||||
question: '还有很多选择也非常精彩哦!你还有其他想选择的职业吗?',
|
||||
display: false,
|
||||
answer: '',
|
||||
guide: '我只想做科学家',
|
||||
).obs);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -208,8 +239,18 @@ class SelectController extends GetxController {
|
||||
}
|
||||
}
|
||||
|
||||
Future confimSelected() async {
|
||||
confirm.value = true;
|
||||
recommend.value = false;
|
||||
confirmTitle.value = '你的梦想职业是';
|
||||
showOccupationName.value = true;
|
||||
await Future.delayed(const Duration(milliseconds: 1000));
|
||||
showOccupationName.value = false;
|
||||
}
|
||||
|
||||
Future selectedOccupation(Occupation occupation) async {
|
||||
selectOccupation.value = occupation;
|
||||
await setStep();
|
||||
for (var occupation in selectOccupations) {
|
||||
occupation.update((val) {
|
||||
val!.selected = false;
|
||||
@ -221,6 +262,7 @@ class SelectController extends GetxController {
|
||||
var occupation = selectOccupations.firstWhere((t) => t.value.id == id);
|
||||
selectOccupation.value = occupation.value;
|
||||
confirm.value = true;
|
||||
recommend.value = true;
|
||||
for (var occupation in selectOccupations) {
|
||||
occupation.update((val) {
|
||||
val!.selected = false;
|
||||
@ -228,6 +270,63 @@ class SelectController extends GetxController {
|
||||
}
|
||||
}
|
||||
|
||||
Future setStep() async {
|
||||
btnTxt.value = '我要回答';
|
||||
bool hasQuestion = false;
|
||||
for (var questionAnswer in questionAnswers) {
|
||||
if (!questionAnswer.value.display!) {
|
||||
if (questionAnswer.value.index != step.value) {
|
||||
showQuestionDialog.value = false;
|
||||
} else {
|
||||
showQuestionDialog.value = true;
|
||||
}
|
||||
step.value = questionAnswer.value.index!;
|
||||
question.value = questionAnswer.value.question!;
|
||||
guide.value = questionAnswer.value.guide;
|
||||
hasQuestion = true;
|
||||
allAnswer.value = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasQuestion) {
|
||||
showQuestionDialog.value = false;
|
||||
allAnswer.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
Future updateAnswer(String answer) async {
|
||||
var questionAnswer =
|
||||
questionAnswers.firstWhere((t) => t.value.index == step.value);
|
||||
questionAnswer.update((val) {
|
||||
val!.answer = answer;
|
||||
val.display = true;
|
||||
});
|
||||
await setStep();
|
||||
textController.text = '';
|
||||
if (allAnswer.value) {
|
||||
await Future.delayed(const Duration(milliseconds: 1000));
|
||||
for (var questionAnswer in questionAnswers) {
|
||||
questionAnswer.update((val) {
|
||||
val!.display = false;
|
||||
});
|
||||
}
|
||||
showBtn.value = true;
|
||||
showOccupationName.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
Future reflect() async {
|
||||
confirm.value = false;
|
||||
for (var questionAnswer in questionAnswers) {
|
||||
questionAnswer.update((val) {
|
||||
val!.display = false;
|
||||
});
|
||||
}
|
||||
showBtn.value = false;
|
||||
allAnswer.value = false;
|
||||
showOccupationName.value = false;
|
||||
}
|
||||
|
||||
Future openDream() async {
|
||||
SpUtil.putString(Constant.occupationName, selectOccupation.value!.name!);
|
||||
SpUtil.putInt(Constant.occupationId, selectOccupation.value!.id!);
|
||||
|
@ -1,3 +1,4 @@
|
||||
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';
|
||||
@ -82,8 +83,10 @@ class SelectView extends GetView<SelectController> {
|
||||
() => AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: OccupationListWidget(
|
||||
key: ValueKey(controller.selectOccupations.first.value.name ?? ''),
|
||||
keyBuilder: (index) => controller.selectOccupations[index].value.name ?? '',
|
||||
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),
|
||||
@ -198,9 +201,8 @@ class SelectView extends GetView<SelectController> {
|
||||
textStyle: TextStyles.mediumWhiteShadow28_022,
|
||||
width: 264.0,
|
||||
height: 80.0,
|
||||
onPressed: () {
|
||||
controller.confirm.value = true;
|
||||
controller.confirmTitle.value = '你的梦想职业是';
|
||||
onPressed: () async {
|
||||
controller.confimSelected();
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -285,14 +287,60 @@ class SelectView extends GetView<SelectController> {
|
||||
),
|
||||
),
|
||||
),
|
||||
buildConfirmBtn(context, controller.selectOccupation.value!.name!),
|
||||
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 buildConfirmBtn(BuildContext context, String name) {
|
||||
Widget buildRecommendConfirmBtn(BuildContext context, String name) {
|
||||
return Positioned(
|
||||
bottom: 12.h,
|
||||
left: 243.w,
|
||||
@ -380,10 +428,246 @@ class SelectView extends GetView<SelectController> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
});
|
||||
|
||||
@ -398,10 +682,7 @@ class _ShowUp extends HookWidget {
|
||||
controller.forward();
|
||||
});
|
||||
return FadeTransition(
|
||||
opacity: CurvedAnimation(
|
||||
curve: Curves.easeIn,
|
||||
parent: controller
|
||||
),
|
||||
opacity: CurvedAnimation(curve: Curves.easeIn, parent: controller),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ part 'app_routes.dart';
|
||||
class AppPages {
|
||||
AppPages._();
|
||||
|
||||
static const INITIAL = Routes.HOME;
|
||||
static const INITIAL = Routes.SELECT;
|
||||
|
||||
static final routes = [
|
||||
GetPage(
|
||||
|
@ -369,6 +369,10 @@ class Images {
|
||||
AssetImage("assets/images/select/btn_bg_generate.png");
|
||||
static const AssetImage selectBgCareer =
|
||||
AssetImage("assets/images/select/label_bg_career.png");
|
||||
static const AssetImage selectDialog =
|
||||
AssetImage("assets/images/select/pic_dialogue_type.png");
|
||||
static const AssetImage selectAnswer =
|
||||
AssetImage("assets/images/select/label_bg_answer.png");
|
||||
|
||||
static const AssetImage questionBg =
|
||||
AssetImage("assets/images/question/bg_pic_answer_page.png");
|
||||
|
@ -95,6 +95,16 @@ class Shadows {
|
||||
offset: Offset(1.w, 0.h),
|
||||
blurRadius: 4.r,
|
||||
);
|
||||
static Shadow txtShadow113 = Shadow(
|
||||
color: const Color(0xFF513892),
|
||||
offset: Offset(1.w, 1.h),
|
||||
blurRadius: 3.r,
|
||||
);
|
||||
static Shadow txtShadow013 = Shadow(
|
||||
color: const Color(0xA30D0C0A),
|
||||
offset: Offset(0.w, 1.h),
|
||||
blurRadius: 3.r,
|
||||
);
|
||||
}
|
||||
|
||||
class TextStyles {
|
||||
@ -121,6 +131,13 @@ class TextStyles {
|
||||
shadows: [Shadows.txtShadow022],
|
||||
);
|
||||
|
||||
static TextStyle mediumWhiteShadow28_013 = TextStyle(
|
||||
fontSize: Dimens.font_sp28.sp,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
shadows: [Shadows.txtShadow013],
|
||||
);
|
||||
|
||||
static TextStyle mediumWhiteShadow26_034 = TextStyle(
|
||||
fontSize: Dimens.font_sp26.sp,
|
||||
color: Colors.white,
|
||||
@ -218,6 +235,14 @@ class TextStyles {
|
||||
shadows: [Shadows.txtShadow100],
|
||||
);
|
||||
|
||||
static TextStyle mediumWhiteShadow28_113 = TextStyle(
|
||||
fontSize: Dimens.font_sp28.sp,
|
||||
fontFamily: 'alph-b',
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
shadows: [Shadows.txtShadow113],
|
||||
);
|
||||
|
||||
static TextStyle boldWhiteShadow28_110 = TextStyle(
|
||||
fontSize: Dimens.font_sp28.sp,
|
||||
fontFamily: 'alph-b',
|
||||
|
Loading…
Reference in New Issue
Block a user