import 'package:dotted_border/dotted_border.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:keyboard/base/base_page.dart'; import 'package:keyboard/data/bean/keyboard_info.dart'; import 'package:keyboard/module/profile/profile_controller.dart'; import 'package:keyboard/utils/intimacy_util.dart'; import '../../resource/assets.gen.dart'; import '../../resource/string.gen.dart'; import '../../router/app_pages.dart'; import '../../utils/styles.dart'; import '../../widget/avatar/avatar_image_widget.dart'; class ProfilePage extends BasePage { const ProfilePage({super.key}); static start() { Get.toNamed(RoutePath.profile); } @override Color backgroundColor() { return const Color(0xFFF6F5FA); } @override immersive() { return true; } @override Widget buildBody(BuildContext context) { return Stack( children: [ SafeArea( child: CustomScrollView( physics: const BouncingScrollPhysics(), // 更流畅的滚动 slivers: [ SliverToBoxAdapter( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [_buildTitle(), SizedBox(height: 26.h)], ), ), // 键盘列表 Obx(() { if (controller.keyboardInfoList.isEmpty) { return SliverToBoxAdapter(child: _buildKeyboardListItem( keyboardInfo: null, isChosen: false, hasKeyboard: false, )); } return SliverList( delegate: SliverChildBuilderDelegate((context, index) { KeyboardInfo keyboardInfo = controller.keyboardInfoList[index]; return Obx(() { return _buildKeyboardListItem( keyboardInfo: keyboardInfo, isChosen: keyboardInfo.id == controller.currentCustomKeyboardInfo.id, hasKeyboard: true, ); }); }, childCount: controller.keyboardInfoList.length), ); }), ], ), ), Positioned( bottom: 20.h, left: 16.w, right: 16.w, child: InkWell( onTap: () { controller.clickSaveButton(); }, child: Container( height: 48.h, alignment: Alignment.center, decoration: Styles.getActivateButtonDecoration(31.r), child: Text( StringName.profileSave, style: Styles.getTextStyleWhiteW500(16.sp), ), ), ), ), // 背景图片 IgnorePointer(child: Assets.images.bgMine.image(width: 360.w)), ], ); } // 爱心 _buildLoveIndex(int? intimacy) { return Container( width: 87.w, height: 71.h, decoration: BoxDecoration( image: DecorationImage(image: Assets.images.bgProfileLove.provider()), ), child: Column( children: [ SizedBox(height: 45.h), Container( width: 47.w, height: 19.h, decoration: ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder( side: BorderSide(width: 1.18.w, color: const Color(0xFFFD649B)), borderRadius: BorderRadius.circular(12.36.r), ), ), child: (intimacy != null) ? Center( child: Text( IntimacyUtil.getIntimacyName(intimacy), style: TextStyle( color: const Color(0xFFFF73E0), fontSize: 11.sp, fontWeight: FontWeight.w500, ), ), ) : Center( child: Text( "?", style: TextStyle( color: const Color(0xFFFF73E0), fontSize: 11.sp, fontWeight: FontWeight.w500, ), ), ), ), ], ), ); } _buildTitle() { return Container( alignment: Alignment.centerLeft, padding: EdgeInsets.only(top: 12.h, left: 16.w, right: 16.w), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: () => controller.clickBack(), child: Assets.images.iconMineBackArrow.image( width: 24.w, height: 24.w, ), ), Text( StringName.profileList, style: Styles.getTextStyleBlack204W500(17.sp), ), GestureDetector( onTap: () => controller.clickAddButton(), child: Assets.images.iconProfileAdd.image( width: 24.w, height: 24.w, ), ), ], ), ); } Widget _buildKeyboardListItem({ KeyboardInfo? keyboardInfo, bool isChosen = false, required bool hasKeyboard, }) { final String title = hasKeyboard ? '我&${keyboardInfo?.name ?? ""}' : '我'; final int? intimacy = hasKeyboard ? keyboardInfo?.intimacy : null; final String? keyboardAvatar = hasKeyboard ? keyboardInfo?.avatar : null; final int gender = hasKeyboard ? (keyboardInfo?.gender ?? 1) : 1; return GestureDetector( onTap: hasKeyboard ? () => controller.clickOnChangeKeyboard(keyboardInfo!) : null, child: Container( height: 164.h, margin: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 12.h), decoration: isChosen ? ShapeDecoration( gradient: LinearGradient( begin: Alignment(0.02, 0.04), end: Alignment(1.00, 1.00), colors: [const Color(0xFFE7A0FF), const Color(0xFFAB8FFA)], ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(22.r), ), shadows: [ BoxShadow( color: Color(0x1CD6C1FF), blurRadius: 4.r, offset: Offset(0, 4.r), spreadRadius: 0, ), ], ) : ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20.r), ), ), child: Stack( children: [ if (isChosen) Opacity( opacity: 0.1, child: Assets.images.bgProfileSelected.image(), ), Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Padding( padding: EdgeInsets.only(left: 16.w, right: 16.w, top: 10.h), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Text( title, style: TextStyle( color: const Color(0xFF202020), fontSize: 16.sp, fontWeight: FontWeight.w700, ), ), ], ), ), SizedBox(height: 10.h), Padding( padding: EdgeInsets.symmetric(horizontal: 16.w), child: Divider( height: 1.h, color: isChosen ? Colors.transparent : Color(0xffF5F5F5), ), ), Expanded( child: Container( margin: isChosen ? EdgeInsets.symmetric(horizontal: 4.w, vertical: 4.w) : EdgeInsets.zero, decoration: ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20.r), ), shadows: [ BoxShadow( color: Color(0x1CD6C1FF), blurRadius: 4.r, offset: Offset(0, 4), spreadRadius: 0, ), ], ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _buildProfileAvatar( imageUrl: controller.userInfo?.imageUrl, gender: controller.userGender, onTap: () => controller.clickAvatar(isUser: true), genderIconAlignment: Alignment.topRight, ), SizedBox(width: 8.w), _buildLoveIndex(intimacy), SizedBox(width: 8.w), hasKeyboard ? _buildProfileAvatar( imageUrl: keyboardAvatar, gender: gender, onTap: () => controller.clickAvatar(isUser: false), genderIconAlignment: Alignment.topLeft, ) : _buildKeyboardListEmptyAvatar( onTap: () => controller.clickAddButton(), ), ], ), ), ), ], ), ], ), ), ); } // 头像 Widget _buildProfileAvatar({ required String? imageUrl, required int gender, required VoidCallback? onTap, Alignment genderIconAlignment = Alignment.topRight, }) { return GestureDetector( onTap: onTap, child: Stack( alignment: Alignment.bottomCenter, children: [ Container( margin: EdgeInsets.only(bottom: 10.h), width: 78.w, height: 78.w, decoration: ShapeDecoration( color: gender == 1 ? const Color(0xFFB7B6FF) : null, gradient: gender == 1 ? null : const LinearGradient( begin: Alignment(0.5, 0), end: Alignment(0.5, 1.0), colors: [Color(0xFFEBE6FF), Color(0xFFFFE6FE)], ), shape: RoundedRectangleBorder( side: BorderSide(width: 1.5.w, color: Colors.white), borderRadius: BorderRadius.circular(40.r), ), ), child: CircleAvatarWidget( image: Assets.images.iconKeyboardDefaultAvatar.provider(), imageUrl: imageUrl, size: 78.w, borderWidth: 0.r, placeholder: (_, __) { return const CupertinoActivityIndicator(); }, ), ), Positioned( top: 0, left: genderIconAlignment == Alignment.topLeft ? 0 : null, right: genderIconAlignment == Alignment.topRight ? 0 : null, child: gender == 1 ? Assets.images.iconProfileMale.image( width: 20.w, height: 20.w, ) : Assets.images.iconProfileFemale.image( width: 20.w, height: 20.w, ), ), Positioned( child: Container( width: 58.w, height: 28.h, decoration: ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder( side: BorderSide(width: 1, color: const Color(0x6BE1E1E1)), borderRadius: BorderRadius.circular(50.r), ), shadows: [ BoxShadow( color: Color(0x56E6D9FF), blurRadius: 4, offset: Offset(0, 3), spreadRadius: 0, ), ], ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Assets.images.iconProfileEdit.image( width: 12.w, height: 12.w, ), Text( StringName.profileEdit, style: Styles.getTextStyleBlack178W500(11.sp), ), ], ), ), ), ], ), ); } // 没有Keyboard时 _buildKeyboardListEmptyAvatar({required VoidCallback? onTap}) { return GestureDetector( onTap: onTap, child: Stack( alignment: Alignment.bottomCenter, children: [ Container( margin: EdgeInsets.only(bottom: 10.h), width: 78.w, height: 78.w, child: DottedBorder( color: const Color(0xFFA595C8), strokeWidth: 1.0.w, borderType: BorderType.Circle, child: Container( width: 78.w, height: 78.w, margin: EdgeInsets.only(bottom: 10.h), alignment: Alignment.center, child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.end, children: [ Assets.images.iconProfilePlus.image( width: 22.5.w, height: 22.5.w, fit: BoxFit.cover, ), SizedBox(height: 2.h), Text( StringName.profileAdd, style: TextStyle( color: const Color(0xB2755BAB), fontSize: 12.sp, fontWeight: FontWeight.w400, ), ), ], ), ), ) ), ], ), ); } }