import 'package:cached_network_image/cached_network_image.dart'; import 'package:dating_touchme_app/extension/ex_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:dating_touchme_app/generated/assets.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:dating_touchme_app/controller/mine/user_info_controller.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; class UserInfoPage extends StatefulWidget { const UserInfoPage({super.key}); @override _UserInfoState createState() => _UserInfoState(); } class _UserInfoState extends State { // 显示头像选择选项 void _showAvatarPopup(UserInfoController controller){ Navigator.of(Get.context!).push( TDSlidePopupRoute( slideTransitionFrom: SlideTransitionFrom.bottom, builder: (context) { return Container( // color: TDTheme.of(context).bgColorContainer, height: 490, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(12.0), topRight: Radius.circular(12.0), ), ), child: Column( children: [ const SizedBox(height: 4), CachedNetworkImage(imageUrl: 'https://dating-agency-prod.oss-cn-shenzhen.aliyuncs.com/1A437A945667.jpg', width: 375, height: 314), const TDDivider(), TDCell( arrow: false, titleWidget: Center( child: Text('拍照', style: TextStyle(fontSize: 16.w, color: const Color.fromRGBO(51, 51, 51, 1))), ), onClick: (cell) async{ Navigator.pop(context); await controller.handleCameraCapture(); }, ), const TDDivider(), TDCell( arrow: false, titleWidget: Center( child: Text('从相册选择'), ), onClick: (cell) async{ Navigator.pop(context); await controller.handleGallerySelection(); }, ), Expanded( child: Container( color: Color(0xFFF3F3F3), ), ), TDCell( arrow: false, titleWidget: Center( child: Text('取消'), ), onClick: (cell){ Navigator.pop(context); }, ), ], ), ); }), ); } // 显示学历选择弹框 Future _showEducationPicker(UserInfoController controller) async { final List educationOptions = ['高中及以下', "中专", '大专', '本科', '硕士', "博士"]; await showModalBottomSheet( context: Get.context!, isScrollControlled: true, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(8), topRight: Radius.circular(8), ), ), builder: (BuildContext context) { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, // 明确设置背景色 borderRadius: const BorderRadius.only( topLeft: Radius.circular(8), topRight: Radius.circular(8), ), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ // 标题和关闭按钮 Stack( alignment: Alignment.center, children: [ // 关闭按钮 - 左对齐 Align( alignment: Alignment.centerLeft, child: IconButton( icon: const Icon(Icons.close), onPressed: () { Navigator.pop(context); }, ), ), // 标题 - 居中 Text( '学历', style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), ], ), const SizedBox(height: 16), // 学历选项列表 for (String education in educationOptions) Container( margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), // 左右10,上下6 child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: controller.education.value == education ? const Color.fromRGBO(123, 104, 238, 1) // 紫色 : const Color.fromRGBO(247, 247, 247, 1), padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 25), // 增加水平内边距 minimumSize: const Size(double.infinity, 48), // 宽度充满,最小高度48 shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(32), ), elevation: 0, ), onPressed: () { Navigator.pop(context); controller.selectEducation(education); }, child: Text( education, style: TextStyle( color: controller.education.value == education ? Colors.white : Colors.black, fontSize: 16, ), ), ), ), // 底部间距 const SizedBox(height: 20), ], ), ); }, ); } // 显示日期选择器 Future _showDatePicker(UserInfoController controller) async { // 计算最小和最大日期 final now = DateTime.now(); final maxDate = DateTime(now.year - 18); // 最小18岁 final minDate = DateTime(now.year - 80); // 最大80岁 // 初始选择日期(默认为25岁) DateTime initialDate = DateTime(now.year - 25); if (controller.birthday.value.isNotEmpty) { try { final List dateParts = controller.birthday.value.split('-'); if (dateParts.length == 3) { initialDate = DateTime( int.parse(dateParts[0]), int.parse(dateParts[1]), int.parse(dateParts[2]), ); // 确保初始日期在有效范围内 if (initialDate.isBefore(minDate)) initialDate = minDate; if (initialDate.isAfter(maxDate)) initialDate = maxDate; } } catch (e) { print('解析日期失败: $e'); } } // 临时存储选择的日期 DateTime? selectedDate = initialDate; await showCupertinoModalPopup( context: Get.context!, builder: (BuildContext context) { return Container( height: 300, color: CupertinoColors.white, child: Column( children: [ // 头部按钮区域 Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ CupertinoButton( child: const Text('取消'), onPressed: () { Navigator.pop(context); }, ), CupertinoButton( child: const Text('确定'), onPressed: () { Navigator.pop(context); if (selectedDate != null) { // 格式化为YYYY-MM-DD final formattedDate = '${selectedDate!.year}-' '${selectedDate!.month.toString().padLeft(2, '0')}-' '${selectedDate!.day.toString().padLeft(2, '0')}'; controller.selectBirthday(formattedDate); } }, ), ], ), ), // 日期选择器 Expanded( child: CupertinoDatePicker( mode: CupertinoDatePickerMode.date, initialDateTime: initialDate, minimumDate: minDate, maximumDate: maxDate, onDateTimeChanged: (DateTime dateTime) { selectedDate = dateTime; }, use24hFormat: true, backgroundColor: CupertinoColors.white, ), ), ], ), ); }, ); } final FocusNode _blankFocusNode = FocusNode(); final TextEditingController _controller = TextEditingController(); final FocusNode _blankFocusNode2 = FocusNode(); final TextEditingController _controller2 = TextEditingController(); @override Widget build(BuildContext context) { return GetX( init: UserInfoController(), builder: (controller) { return Scaffold( extendBodyBehindAppBar: true, appBar: AppBar( title: const Text( '完善信息', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Color.fromRGBO(51, 51, 51, 1), ), ), backgroundColor: Colors.transparent, shadowColor: Colors.transparent, elevation: 0, centerTitle: true, automaticallyImplyLeading: false, ), body: Stack( children: [ // 背景图 - 覆盖全页面包括AppBar Image.asset( Assets.imagesBgInformation, fit: BoxFit.cover, width: double.infinity, height: double.infinity, ), // 内容区域,顶部留出AppBar高度空间 SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 20.0), child: Column( children: [ const SizedBox(height: 25), // 头像 GestureDetector( onTap: () => _showAvatarPopup(controller), child: Stack( children: [ Container( width: 85, height: 85, decoration: const BoxDecoration( shape: BoxShape.circle, color: Colors.grey, ), child: ClipOval( child: (controller.avatarUrl.value.startsWith('http') ? Image.network( controller.avatarUrl.value, fit: BoxFit.cover, ) : Image.asset( Assets.imagesUserAvatar, fit: BoxFit.cover, )), ), ), Positioned( bottom: 0, right: 0, child: Container( width: 20, height: 20, child: Stack( children: [ Center( child: Image.asset( Assets.imagesBgEditAvatars, ), ), Center( child: Image.asset( Assets.imagesEditAvatarsIcon, width: 12, height: 12, ), ), ], ), ), ), ], ), ), const SizedBox(height: 25), // 性别选择 const Align( alignment: Alignment.centerLeft, child: Text( '性别 (注册后不可修改)', style: TextStyle( fontSize: 15, color: Color.fromRGBO(144, 144, 144, 1), fontWeight: FontWeight.w500, ), ), ), const SizedBox(height: 10), Row( children: [ GestureDetector( onTap: () => controller.selectGender('male'), child: Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), color: controller.gender.value == 'male' ? Colors.black : Colors.grey[200], ), child: Row( children: [ Image.asset( Assets.imagesManIcon, width: 20, height: 20, color: controller.gender.value == 'male' ? Colors.white : Colors.black, ), const SizedBox(width: 5), ], ), ), ), const SizedBox(width: 20), GestureDetector( onTap: () => controller.selectGender('female'), child: Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), color: controller.gender.value == 'female' ? Colors.pink : Colors.grey[200], ), child: Row( children: [ Image.asset( Assets.imagesWomenIcon, width: 20, height: 20, color: controller.gender.value == 'female' ? Colors.white : Colors.black, ), const SizedBox(width: 5), ], ), ), ), ], ), const SizedBox(height: 20), // 昵称 const Align( alignment: Alignment.centerLeft, child: Text( '昵称', style: TextStyle( fontSize: 15, color: Color.fromRGBO(144, 144, 144, 1), fontWeight: FontWeight.w500, ), ), ), const SizedBox(height: 10), Container( padding: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(32), color: Color.fromRGBO(247, 247, 247, 1), ), child: Row( children: [ Expanded( child: TextField( focusNode: _blankFocusNode, controller: _controller, onChanged: (value) { controller.nickname.value = value; }, onTapOutside: (e){ _blankFocusNode.unfocus(); }, onTap: (){ // 确保光标在文本末尾 WidgetsBinding.instance.addPostFrameCallback((_) { _controller.selection = TextSelection.fromPosition( TextPosition(offset: _controller.text.length), ); }); }, decoration: const InputDecoration( border: InputBorder.none, hintText: '请输入昵称', hintStyle: TextStyle(color: Colors.grey), ), ), ), ], ), ), const SizedBox(height: 20), // 出生日期 const Align( alignment: Alignment.centerLeft, child: Text( '出生日期', style: TextStyle( fontSize: 15, color: Color.fromRGBO(144, 144, 144, 1), fontWeight: FontWeight.w500, ), ), ), const SizedBox(height: 10), GestureDetector( onTap: () async { // FocusScope.of(context).requestFocus(_blankFocusNode); // 显示Cupertino日期选择器 // _blankFocusNode.unfocus(); await _showDatePicker(controller); }, child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), decoration: BoxDecoration( borderRadius: BorderRadius.circular(32), color: Color.fromRGBO(247, 247, 247, 1), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( controller.birthday.value.isEmpty ? '请选择你的出生日期' : controller.birthday.value, style: TextStyle( color: controller.birthday.value.isEmpty ? Colors.grey : Colors.black, ), ), Image.asset( Assets.imagesArrowForwardRight, width: 5, height: 10, ), ], ), ), ), const SizedBox(height: 20), // 学历 const Align( alignment: Alignment.centerLeft, child: Text( '学历', style: TextStyle( fontSize: 15, color: Color.fromRGBO(144, 144, 144, 1), fontWeight: FontWeight.w500, ), ), ), const SizedBox(height: 10), GestureDetector( onTap: () async { // FocusScope.of(context).requestFocus(_blankFocusNode); // _blankFocusNode.unfocus(); // 显示学历选择弹框 await _showEducationPicker(controller); }, child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), decoration: BoxDecoration( borderRadius: BorderRadius.circular(32), color: Color.fromRGBO(247, 247, 247, 1), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( controller.education.value.isEmpty ? '请选择你的学历' : controller.education.value, style: TextStyle( color: controller.education.value.isEmpty ? Colors.grey : Colors.black, ), ), Image.asset( Assets.imagesArrowForwardRight, width: 5, height: 10, ), ], ), ), ), const SizedBox(height: 20), // 邀请码 const Align( alignment: Alignment.centerLeft, child: Text( '邀请码 (非必填)', style: TextStyle( fontSize: 15, color: Color.fromRGBO(144, 144, 144, 1), fontWeight: FontWeight.w500, ), ), ), const SizedBox(height: 10), Container( padding: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(32), color: Color.fromRGBO(247, 247, 247, 1), ), child: TextField( focusNode: _blankFocusNode2, controller: _controller2, onChanged: (value) { controller.invitationCode.value = value; }, onTapOutside: (e){ _blankFocusNode2.unfocus(); }, onTap: (){ // 确保光标在文本末尾 WidgetsBinding.instance.addPostFrameCallback((_) { _controller2.selection = TextSelection.fromPosition( TextPosition(offset: _controller2.text.length), ); }); }, decoration: const InputDecoration( hintText: '请输入邀请码', hintStyle: TextStyle(color: Colors.grey), border: InputBorder.none, ), ), ), const SizedBox(height: 24), // 开始交友按钮 SizedBox( width: double.infinity, height: 50, child: ElevatedButton( onPressed: controller.isSubmitting.value ? null : controller.submitUserInfo, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(25), ), ), child: controller.isSubmitting.value ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2, ), ) : const Text( '开始交友', style: TextStyle( fontSize: 18, color: Colors.white, ), ), ), ), const SizedBox(height: 20), ], ), ), ), ], ), ); }, ); } @override void dispose() { // TODO: implement dispose super.dispose(); _blankFocusNode.dispose(); _controller.dispose(); _blankFocusNode2.dispose(); _controller2.dispose(); } }