import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:dating_touchme_app/generated/assets.dart'; import 'package:dating_touchme_app/model/home/marriage_data.dart'; class UserInformationPage extends StatefulWidget { final MarriageData userData; const UserInformationPage({super.key, required this.userData}); @override State createState() => _UserInformationPageState(); } class _UserInformationPageState extends State { bool _showMoreMenu = false; @override Widget build(BuildContext context) { final screenHeight = MediaQuery.of(context).size.height; final screenWidth = MediaQuery.of(context).size.width; // 按照 750:769 的比例计算高度 final topSectionHeight = screenWidth * 769 / 750; return Scaffold( backgroundColor: Colors.white, body: Stack( children: [ // Top section with profile image _buildTopSection(topSectionHeight, screenWidth), // Scrollable content section _buildScrollableContent(topSectionHeight, screenHeight), // Bottom action bar _buildBottomActionBar(), ], ), ); } Widget _buildTopSection(double height, double width) { return GestureDetector( onTap: () { // Close dropdown menu when tapping on background if (_showMoreMenu) { setState(() { _showMoreMenu = false; }); } }, child: Stack( children: [ // Main profile image widget.userData.avatar.isNotEmpty ? Image.network( widget.userData.avatar, width: width, height: height, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Image.asset( Assets.imagesAvatarsExample, width: width, height: height, fit: BoxFit.cover, ); }, ) : Image.asset( Assets.imagesAvatarsExample, width: width, height: height, fit: BoxFit.cover, ), // Add imagesInformationBg overlay with same size Image.asset( Assets.imagesInformationBg, width: width, height: height, fit: BoxFit.cover, ), // Back button Positioned( top: MediaQuery.of(context).padding.top + 8, left: 16, child: GestureDetector( onTap: () => Get.back(), child: Container( width: 40, height: 40, decoration: BoxDecoration( color: Colors.black.withOpacity(0.3), shape: BoxShape.circle, ), child: Center( child: Image.asset( Assets.imagesBackIcon, width: 24, height: 24, color: Colors.white, ), ), ), ), ), // More button with dropdown menu Positioned( top: MediaQuery.of(context).padding.top + 8, right: 16, child: GestureDetector( onTap: () { setState(() { _showMoreMenu = !_showMoreMenu; }); }, behavior: HitTestBehavior.opaque, child: Stack( clipBehavior: Clip.none, children: [ Container( width: 40, height: 40, decoration: BoxDecoration( color: Colors.black.withOpacity(0.3), shape: BoxShape.circle, ), child: Center( child: Image.asset( Assets.imagesMoreIcon, width: 24, height: 24, color: Colors.white, ), ), ), // Dropdown menu if (_showMoreMenu) Positioned( top: 50, right: 0, child: GestureDetector( onTap: () {}, // Prevent event bubbling behavior: HitTestBehavior.opaque, child: Material( color: Colors.transparent, child: Container( width: 100, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Column( mainAxisSize: MainAxisSize.min, children: [ _buildMenuItem('举报', () { setState(() => _showMoreMenu = false); // Handle report action }), Divider(height: 1, color: Colors.grey[200]), _buildMenuItem('拉黑', () { setState(() => _showMoreMenu = false); // Handle blacklist action }), ], ), ), ), ), ), ], ), ), ), // Three small profile pictures at bottom-left Positioned( bottom: -30, left: 16, child: Row( children: widget.userData.photoList.isNotEmpty ? widget.userData.photoList.take(3).map((photo) { return Container( margin: const EdgeInsets.only(right: 8), width: 60, height: 60, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all(color: Colors.white, width: 2), ), child: ClipOval( child: photo.photoUrl.isNotEmpty ? Image.network( photo.photoUrl, width: 60, height: 60, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Image.asset( Assets.imagesAvatarsExample, width: 60, height: 60, fit: BoxFit.cover, ); }, ) : Image.asset( Assets.imagesAvatarsExample, width: 60, height: 60, fit: BoxFit.cover, ), ), ); }).toList() : List.generate( 3, (index) => Container( margin: const EdgeInsets.only(right: 8), width: 60, height: 60, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all(color: Colors.white, width: 2), ), child: ClipOval( child: Image.asset( Assets.imagesAvatarsExample, width: 60, height: 60, fit: BoxFit.cover, ), ), ), ), ), ), ], ), ); } Widget _buildMenuItem(String text, VoidCallback onTap) { return InkWell( onTap: onTap, child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Text( text, style: const TextStyle( fontSize: 14, color: Colors.black, ), ), ), ); } Widget _buildScrollableContent(double topSectionHeight, double screenHeight) { // 计算底部操作栏的高度(包括安全区域) final bottomBarHeight = 56 + MediaQuery.of(context).padding.bottom + 24; return Positioned( top: topSectionHeight - 30, left: 0, right: 0, bottom: bottomBarHeight, // Space for bottom action bar child: Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20), ), ), child: SingleChildScrollView( padding: const EdgeInsets.only(left: 16, right: 16, top: 50, bottom: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // User name and badges _buildUserNameSection(), const SizedBox(height: 12), // Self-description _buildSelfDescription(), const SizedBox(height: 16), // Tags/Interests _buildTagsSection(), const SizedBox(height: 16), // Location and ID _buildLocationAndId(), ], ), ), ), ); } Widget _buildUserNameSection() { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Wrap( spacing: 8, runSpacing: 8, crossAxisAlignment: WrapCrossAlignment.center, children: [ // User name Text( widget.userData.nickName, style: const TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Color(0xFF333333), ), ), // Age badge (pink icon with age) Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: const Color(0xFFFFE8F0), borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Container( width: 14, height: 14, decoration: BoxDecoration( color: const Color(0xFFFF69B4), shape: BoxShape.circle, ), child: const Center( child: Text( 'Q', style: TextStyle( fontSize: 10, color: Colors.white, fontWeight: FontWeight.bold, ), ), ), ), const SizedBox(width: 4), Text( '${widget.userData.age}', style: const TextStyle( fontSize: 12, color: Color(0xFFFF69B4), fontWeight: FontWeight.w500, ), ), ], ), ), // Online badge Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: const Color(0xFF2ED573), borderRadius: BorderRadius.circular(12), ), child: const Text( '在线', style: TextStyle( fontSize: 12, color: Colors.white, fontWeight: FontWeight.w500, ), ), ), // Real-name verified badge if (widget.userData.isRealNameCertified) Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: const Color(0xFFF3E9FF), borderRadius: BorderRadius.circular(12), ), child: const Text( '实名', style: TextStyle( fontSize: 12, color: Color(0xFFA05CFF), fontWeight: FontWeight.w500, ), ), ), // Male gender icon (placeholder) Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: Row( mainAxisSize: MainAxisSize.min, children: [ Image.asset( Assets.imagesManIcon, width: 16, height: 16, ), const SizedBox(width: 4), const Text( '19', style: TextStyle( fontSize: 12, color: Color(0xFF333333), ), ), ], ), ), ], ), ), // Voice message button with duration Row( mainAxisSize: MainAxisSize.min, children: [ GestureDetector( onTap: () { // Handle voice message playback }, child: Container( width: 40, height: 40, decoration: BoxDecoration( color: const Color(0xFFA05CFF), shape: BoxShape.circle, ), child: Stack( alignment: Alignment.center, children: [ Image.asset( Assets.imagesPlayIcon, width: 24, height: 24, color: Colors.white, ), Image.asset( Assets.imagesVoiceIcon, width: 20, height: 20, color: Colors.white, ), ], ), ), ), const SizedBox(width: 6), const Text( "6'", style: TextStyle( fontSize: 14, color: Color(0xFF333333), fontWeight: FontWeight.w500, ), ), ], ), ], ); } Widget _buildSelfDescription() { return Text( widget.userData.describeInfo, style: const TextStyle( fontSize: 14, color: Color(0xFF333333), ), ); } Widget _buildTagsSection() { // 构建标签列表 final List tags = []; // 添加城市 if (widget.userData.cityName.isNotEmpty) { tags.add(widget.userData.cityName); } if (widget.userData.districtName.isNotEmpty) { tags.add(widget.userData.districtName); } // 这里可以根据实际数据添加更多标签 // 例如:身高、学历、兴趣等 // 由于 MarriageData 模型中没有这些字段,暂时只显示城市信息 // 如果后续需要更多标签,可以在 MarriageData 中添加相应字段 if (tags.isEmpty) { return const SizedBox.shrink(); } return Wrap( spacing: 8, runSpacing: 8, children: tags.map((tag) { return Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: const Color(0xFFF5F5F5), borderRadius: BorderRadius.circular(16), ), child: Text( tag, style: const TextStyle( fontSize: 12, color: Color(0xFF333333), ), ), ); }).toList(), ); } Widget _buildLocationAndId() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (widget.userData.provinceName.isNotEmpty) Text( 'IP属地: ${widget.userData.provinceName}', style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), const SizedBox(height: 4), Text( '动我ID: ${widget.userData.userId}', style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), ], ); } Widget _buildBottomActionBar() { final bottomPadding = MediaQuery.of(context).padding.bottom; return Positioned( bottom: 0, left: 0, right: 0, child: Container( padding: EdgeInsets.only( left: 16, right: 16, top: 12, bottom: bottomPadding + 12, ), decoration: BoxDecoration( color: const Color(0xFF2C2C2C), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 8, offset: const Offset(0, -2), ), ], ), child: SafeArea( top: false, child: Row( children: [ // Send message button Expanded( child: ElevatedButton( onPressed: () { // Handle send message }, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF3A3A3A), foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(25), ), elevation: 0, ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( Assets.imagesTalkIcon, width: 20, height: 20, color: Colors.white, ), const SizedBox(width: 8), const Text( '发消息', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, ), ), ], ), ), ), const SizedBox(width: 12), // Follow button SizedBox( width: 100, child: ElevatedButton( onPressed: () { // Handle follow action }, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFFA05CFF), foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(25), ), ), child: const Text( '关注', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, ), ), ), ), ], ), ), ), ); } }