step_partner_view.dart 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/src/widgets/framework.dart';
  3. import 'package:flutter_screenutil/flutter_screenutil.dart';
  4. import 'package:keyboard/base/base_view.dart';
  5. import 'package:keyboard/module/new_user/new_user_controller.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:keyboard/resource/string.gen.dart';
  8. import 'package:get/get.dart';
  9. import '../../../../resource/assets.gen.dart';
  10. import '../../../../resource/colors.gen.dart';
  11. import '../../../../utils/age_zodiac_sign_util.dart';
  12. import '../../../../utils/styles.dart';
  13. import '../../../../widget/avatar/avatar_image_widget.dart';
  14. class StepPartnerView extends BaseView<NewUserController> {
  15. const StepPartnerView({super.key});
  16. @override
  17. Color backgroundColor() {
  18. return Colors.transparent;
  19. }
  20. @override
  21. Widget buildBody(BuildContext context) {
  22. return Container(
  23. child: Column(
  24. crossAxisAlignment: CrossAxisAlignment.start,
  25. children: [
  26. _buildStepTitle(),
  27. SizedBox(height: 24.w),
  28. Center(child: _buildAvatar()),
  29. SizedBox(height: 12.w),
  30. Expanded(child: SingleChildScrollView(child: _buildContent())),
  31. ],
  32. ),
  33. );
  34. }
  35. Widget _buildStepTitle() {
  36. return Container(
  37. margin: EdgeInsets.only(left: 30.w, right: 30.w),
  38. child: Column(
  39. crossAxisAlignment: CrossAxisAlignment.start,
  40. children: [
  41. Text(
  42. StringName.newUserPartnerTitle,
  43. style: TextStyle(
  44. color: Colors.black.withAlpha(204),
  45. fontSize: 22.sp,
  46. fontWeight: FontWeight.w500,
  47. ),
  48. ),
  49. SizedBox(height: 7.h),
  50. Text(
  51. StringName.newUserPartnerDesc,
  52. style: TextStyle(
  53. color: Colors.black.withAlpha(153),
  54. fontSize: 14.sp,
  55. fontWeight: FontWeight.w400,
  56. ),
  57. ),
  58. ],
  59. ),
  60. );
  61. }
  62. Widget _buildAvatar() {
  63. return GestureDetector(
  64. onTap: controller.nextAvatar,
  65. child: Obx(() {
  66. return Container(
  67. height: 90.w,
  68. child: Stack(
  69. children: [
  70. Container(
  71. width: 84.w,
  72. height: 84.w,
  73. child:
  74. controller.partnerAvatarUrl.isNotEmpty
  75. ? CircleAvatarWidget(
  76. image:
  77. Assets.images.iconKeyboardDefaultAvatar
  78. .provider(),
  79. imageUrl: controller.partnerAvatarUrl,
  80. size: 84.w,
  81. borderColor: Colors.white,
  82. borderWidth: 2.r,
  83. placeholder: (_, __) {
  84. return const CupertinoActivityIndicator();
  85. },
  86. )
  87. : SizedBox(),
  88. ),
  89. Positioned(
  90. left: 0,
  91. right: 0,
  92. bottom: 0,
  93. child: _buildAvatarSwitch(),
  94. ),
  95. ],
  96. ),
  97. );
  98. }),
  99. );
  100. }
  101. Widget _buildAvatarSwitch() {
  102. return GestureDetector(
  103. onTap: controller.nextAvatar,
  104. child: SizedBox(
  105. width: 22.r,
  106. height: 22.r,
  107. child: Assets.images.iconCharacterCustomDetailSwitch.image(
  108. width: 22.r,
  109. height: 22.r,
  110. ),
  111. ),
  112. );
  113. }
  114. Widget _buildContent() {
  115. return Container(
  116. margin: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 200.w),
  117. padding: EdgeInsets.only(top: 21.w),
  118. decoration: BoxDecoration(
  119. borderRadius: BorderRadius.circular(18),
  120. color: Colors.white,
  121. ),
  122. child: Column(
  123. crossAxisAlignment: CrossAxisAlignment.start,
  124. children: [
  125. Padding(
  126. padding: EdgeInsets.only(left: 20.w),
  127. child: Text(
  128. StringName.newUserPartnerIs,
  129. style: Styles.getTextStyleBlack204W500(14.sp),
  130. ),
  131. ),
  132. SizedBox(height: 12.w),
  133. buildPartnerNameFiled(),
  134. SizedBox(height: 30.w),
  135. Padding(
  136. padding: EdgeInsets.only(left: 20.w),
  137. child: Text(
  138. StringName.gender,
  139. style: Styles.getTextStyleBlack204W500(14.sp),
  140. ),
  141. ),
  142. SizedBox(height: 9.w),
  143. Obx(
  144. () => Container(
  145. margin: EdgeInsets.symmetric(horizontal: 16.w),
  146. child: Row(
  147. mainAxisAlignment: MainAxisAlignment.spaceAround,
  148. children: [
  149. // 女生按钮
  150. Expanded(
  151. child: buildGenderSwitchButton(
  152. isSelected: controller.partnerGender == 2,
  153. text: StringName.newUserPartnerIsFemale,
  154. genderIcon: Assets.images.iconFamateBlack,
  155. onTap: () => controller.onPartnerGenderChanged(2),
  156. ),
  157. ),
  158. SizedBox(width: 16.w),
  159. // 男生按钮
  160. Expanded(
  161. child: buildGenderSwitchButton(
  162. genderIcon: Assets.images.iconMaleWhite,
  163. isSelected: controller.partnerGender == 1,
  164. text: StringName.newUserPartnerIsMale,
  165. onTap: () => controller.onPartnerGenderChanged(1),
  166. ),
  167. ),
  168. ],
  169. ),
  170. ),
  171. ),
  172. SizedBox(height: 30.w),
  173. Padding(
  174. padding: EdgeInsets.only(left: 20.w),
  175. child: Text(
  176. StringName.newUserBirthdayTitle,
  177. style: Styles.getTextStyleBlack204W500(14.sp),
  178. ),
  179. ),
  180. SizedBox(height: 12.w),
  181. _buildPartnerBirthday(),
  182. SizedBox(height: 32.w),
  183. ],
  184. ),
  185. );
  186. }
  187. Widget buildPartnerNameFiled() {
  188. return Container(
  189. height: 42.w,
  190. margin: EdgeInsets.symmetric(horizontal: 16.w),
  191. padding: EdgeInsets.symmetric(horizontal: 12.w),
  192. decoration: BoxDecoration(
  193. color: Color(0XFFF6F5FA),
  194. borderRadius: BorderRadius.circular(28.w),
  195. ),
  196. child: Row(
  197. children: [
  198. Expanded(
  199. child: TextField(
  200. cursorHeight: 20.w,
  201. style: TextStyle(
  202. fontSize: 14.sp,
  203. color: Colors.black.withAlpha(204),
  204. fontWeight: FontWeight.w500,
  205. ),
  206. controller: controller.partnerNameController,
  207. maxLines: 1,
  208. textAlignVertical: TextAlignVertical.center,
  209. decoration: InputDecoration(
  210. isDense: true,
  211. hintText: StringName.newUserNicknameTitle,
  212. counterText: "",
  213. hintStyle: TextStyle(
  214. fontSize: 14.sp,
  215. color: Colors.black.withAlpha(77),
  216. fontWeight: FontWeight.w500,
  217. ),
  218. labelStyle: TextStyle(
  219. fontSize: 14.sp,
  220. color: ColorName.primaryTextColor,
  221. ),
  222. contentPadding: const EdgeInsets.all(0),
  223. border: const OutlineInputBorder(borderSide: BorderSide.none),
  224. enabled: true,
  225. ),
  226. onChanged: controller.onNicknameChange,
  227. ),
  228. ),
  229. ],
  230. ),
  231. );
  232. }
  233. Widget buildSwitchPartnerGender() {
  234. return Container(
  235. width: 296,
  236. height: 42,
  237. decoration: ShapeDecoration(
  238. color: const Color(0xFFF5F4F9),
  239. shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)),
  240. ),
  241. );
  242. }
  243. Widget buildGenderSwitchButton({
  244. required String text,
  245. required bool isSelected,
  246. required VoidCallback onTap,
  247. required AssetGenImage genderIcon,
  248. }) {
  249. return GestureDetector(
  250. onTap: onTap,
  251. child: Container(
  252. height: 42.w,
  253. alignment: Alignment.center,
  254. decoration: BoxDecoration(
  255. borderRadius: BorderRadius.circular(28.r),
  256. color: isSelected ? null : const Color(0xFFF5F4F9),
  257. gradient:
  258. isSelected
  259. ? LinearGradient(
  260. begin: Alignment.centerLeft,
  261. end: Alignment.centerRight,
  262. transform: GradientRotation(0.5),
  263. colors: [const Color(0xFF7D46FC), const Color(0xFFBC87FF)],
  264. )
  265. : null,
  266. ),
  267. child: Row(
  268. mainAxisAlignment: MainAxisAlignment.center,
  269. children: [
  270. genderIcon.image(width: 24.w,height: 24.w,color: isSelected ? Colors.white : Colors.black),
  271. Text(
  272. text,
  273. style:
  274. isSelected
  275. ? Styles.getTextStyleWhiteW500(14.sp)
  276. : Styles.getTextStyleBlack204W500(14.sp),
  277. ),
  278. ],
  279. ),
  280. ),
  281. );
  282. }
  283. _buildPartnerBirthday() {
  284. return GestureDetector(
  285. onTap: controller.changePartnerBirthday,
  286. child: Obx(() {
  287. return Container(
  288. height: 42.w,
  289. margin: EdgeInsets.symmetric(horizontal: 16.w),
  290. padding: EdgeInsets.symmetric(horizontal: 12.w),
  291. decoration: BoxDecoration(
  292. color: Color(0XFFF6F5FA),
  293. borderRadius: BorderRadius.circular(28.w),
  294. ),
  295. child: Row(
  296. children: [
  297. controller.currentPartnerBirthday == null
  298. ? Expanded(
  299. child: Row(
  300. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  301. children: [
  302. Text(
  303. StringName.newUserPartnerBirthday,
  304. style: TextStyle(
  305. color: Colors.black.withAlpha(77),
  306. fontSize: 14.sp,
  307. fontWeight: FontWeight.w500,
  308. ),
  309. ),
  310. Assets.images.iconArrowRight.image(
  311. width: 24.w,
  312. height: 24.w,
  313. fit: BoxFit.contain,
  314. ),
  315. ],
  316. ),
  317. )
  318. : Expanded(
  319. child: Row(
  320. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  321. children: [
  322. _buildBirthdayNotEmptyText(),
  323. Assets.images.iconArrowRight.image(
  324. width: 24.w,
  325. height: 24.w,
  326. fit: BoxFit.contain,
  327. ),
  328. ],
  329. ),
  330. ),
  331. ],
  332. ),
  333. );
  334. }),
  335. );
  336. }
  337. _buildBirthdayNotEmptyText() {
  338. return Row(
  339. children: [
  340. Text(
  341. controller.dateComponents.yearPart,
  342. style: Styles.getTextStyleBlack204W500(14.sp),
  343. ),
  344. SizedBox(width: 4.w),
  345. Text(
  346. StringName.year,
  347. style: TextStyle(
  348. color: Colors.black.withAlpha(102),
  349. fontSize: 12.sp,
  350. fontWeight: FontWeight.w500,
  351. ),
  352. ),
  353. SizedBox(width: 4.w),
  354. Text(
  355. controller.dateComponents.monthPart,
  356. style: Styles.getTextStyleBlack204W500(14.sp),
  357. ),
  358. SizedBox(width: 4.w),
  359. Text(
  360. StringName.month,
  361. style: TextStyle(
  362. color: Colors.black.withAlpha(102),
  363. fontSize: 12.sp,
  364. fontWeight: FontWeight.w500,
  365. ),
  366. ),
  367. SizedBox(width: 4.w),
  368. Text(
  369. controller.dateComponents.dayPart,
  370. style: Styles.getTextStyleBlack204W500(14.sp),
  371. ),
  372. Text(
  373. StringName.day,
  374. style: TextStyle(
  375. color: Colors.black.withAlpha(102),
  376. fontSize: 12.sp,
  377. fontWeight: FontWeight.w500,
  378. ),
  379. ),
  380. SizedBox(width: 16.w),
  381. Text(
  382. AgeZodiacSignUtil.getZodiacSign(
  383. controller.currentPartnerBirthday!,
  384. ).name,
  385. style: Styles.getTextStyleBlack204W500(14.sp),
  386. ),
  387. ],
  388. );
  389. }
  390. }