import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:kaer_with_panels/app/model/enum/kr_request_type.dart'; import 'package:kaer_with_panels/app/model/kr_area_code.dart'; import 'package:kaer_with_panels/app/modules/kr_login/views/kr_search_area_code_view.dart'; import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart'; import 'package:kaer_with_panels/app/widgets/kr_local_image.dart'; import '../../../routes/app_pages.dart'; import '../controllers/kr_login_controller.dart'; import 'package:kaer_with_panels/app/localization/app_translations.dart'; import 'package:kaer_with_panels/app/services/api_service/api.dart'; import 'package:kaer_with_panels/app/common/app_config.dart'; class KRLoginView extends GetView { const KRLoginView({super.key}); @override Widget build(BuildContext context) { final theme = Theme.of(context); return GestureDetector( onTap: () { if (!FocusScope.of(context).hasPrimaryFocus) { FocusScope.of(context).unfocus(); } _hideDropdown(); }, child: Container( color: theme.scaffoldBackgroundColor, child: SingleChildScrollView( padding: EdgeInsets.symmetric(horizontal: 20.w), child: Obx(() { switch (controller.kr_loginStatus.value) { case KRLoginProgressStatus.kr_check: return _buildCheckView(context); case KRLoginProgressStatus.kr_loginByCode: return _buildLoginByCodeView(context); case KRLoginProgressStatus.kr_loginByPsd: return _buildLoginByPsdView(context); case KRLoginProgressStatus.kr_registerSendCode: return _buildRegisterSendCodeView(context); case KRLoginProgressStatus.kr_registerSetPsd: return _buildRegisterSetPsdView(context); case KRLoginProgressStatus.kr_forgetPsdSendCode: return _buildForgetPsdSendCodeView(context); case KRLoginProgressStatus.kr_forgetPsdSetPsd: return _buildForgetPsdSetPsdView(context); default: return Container(); } }), ), ), ); } Widget _buildCheckView(BuildContext context) { // 构建检查视图的代码 return Column( mainAxisSize: MainAxisSize.min, children: [ Obx(() => Visibility( visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check, child: _buildBackButton(Theme.of(context)), )), _buildHeaderSection(Theme.of(context)), _buildInputSection(context, Theme.of(context)), _buildDynamicContent(Theme.of(context)), _buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)), SizedBox(height: _getBottomPadding()), ], ); } /// 获取底部间距 double _getBottomPadding() { switch (controller.kr_loginStatus.value) { case KRLoginProgressStatus.kr_check: case KRLoginProgressStatus.kr_loginByCode: case KRLoginProgressStatus.kr_loginByPsd: // 这些状态内容较少,减小底部间距 return 48.w; case KRLoginProgressStatus.kr_registerSetPsd: case KRLoginProgressStatus.kr_forgetPsdSetPsd: // 这些状态有额外的输入框,保持原有间距 return 48.w; default: // 其他状态使用中等间距 return 48.w; } } Widget _buildLoginByCodeView(BuildContext context) { // 构建验证码登录视图的代码 return Column( mainAxisSize: MainAxisSize.min, children: [ Obx(() => Visibility( visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check, child: _buildBackButton(Theme.of(context)), )), _buildHeaderSection(Theme.of(context)), _buildInputSection(context, Theme.of(context)), _buildDynamicContent(Theme.of(context)), _buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)), SizedBox(height: _getBottomPadding()), ], ); } Widget _buildLoginByPsdView(BuildContext context) { // 构建密码登录视图的代码 return Column( mainAxisSize: MainAxisSize.min, children: [ Obx(() => Visibility( visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check, child: _buildBackButton(Theme.of(context)), )), _buildHeaderSection(Theme.of(context)), _buildInputSection(context, Theme.of(context)), _buildDynamicContent(Theme.of(context)), _buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)), SizedBox(height: _getBottomPadding()), ], ); } Widget _buildRegisterSendCodeView(BuildContext context) { // 构建注册发送验证码视图的代码 return Column( mainAxisSize: MainAxisSize.min, children: [ Obx(() => Visibility( visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check, child: _buildBackButton(Theme.of(context)), )), _buildHeaderSection(Theme.of(context)), _buildInputSection(context, Theme.of(context)), _buildDynamicContent(Theme.of(context)), _buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)), SizedBox(height: _getBottomPadding()), ], ); } Widget _buildRegisterSetPsdView(BuildContext context) { // 构建注册设置密码视图的代码 return Column( mainAxisSize: MainAxisSize.min, children: [ Obx(() => Visibility( visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check, child: _buildBackButton(Theme.of(context)), )), _buildHeaderSection(Theme.of(context)), _buildInputSection(context, Theme.of(context)), Column( children: [ SizedBox(height: 8.w), _buildInputContainer(context, true, Theme.of(context)), SizedBox(height: 8.w), _buildInviteCodeInput(Theme.of(context)), ], ), _buildDynamicContent(Theme.of(context)), _buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)), SizedBox(height: _getBottomPadding()), ], ); } Widget _buildForgetPsdSendCodeView(BuildContext context) { // 构建忘记密码发送验证码视图的代码 return Column( mainAxisSize: MainAxisSize.min, children: [ Obx(() => Visibility( visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check, child: _buildBackButton(Theme.of(context)), )), _buildHeaderSection(Theme.of(context)), _buildInputSection(context, Theme.of(context)), _buildDynamicContent(Theme.of(context)), _buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)), SizedBox(height: _getBottomPadding()), ], ); } Widget _buildForgetPsdSetPsdView(BuildContext context) { // 构建忘记密码设置密码视图的代码 return Column( mainAxisSize: MainAxisSize.min, children: [ Obx(() => Visibility( visible: controller.kr_loginStatus.value != KRLoginProgressStatus.kr_check, child: _buildBackButton(Theme.of(context)), )), _buildHeaderSection(Theme.of(context)), _buildInputSection(context, Theme.of(context)), if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSetPsd) Column( children: [ SizedBox(height: 8.w), _buildInputContainer(context, true, Theme.of(context)), ], ), _buildDynamicContent(Theme.of(context)), _buildNextButton(controller.kr_getNextBtnText(), Theme.of(context)), SizedBox(height: _getBottomPadding()), ], ); } /// 构建头部文本部分 Widget _buildHeaderSection(ThemeData theme) { // 根据不同状态决定是否显示额外信息 switch (controller.kr_loginStatus.value) { case KRLoginProgressStatus.kr_loginByCode: case KRLoginProgressStatus.kr_registerSendCode: case KRLoginProgressStatus.kr_forgetPsdSendCode: // 验证码相关状态 if (!controller.kr_canSendCode.value) { // 已发送验证码状态 return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 24.w), _buildHeaderText(AppTranslations.kr_login.welcome, theme), SizedBox(height: 8.w), _buildHeaderText( _isSendPhone() ? AppTranslations.kr_login.verifyPhone : AppTranslations.kr_login.verifyEmail, theme ), SizedBox(height: 8.w), Text( AppTranslations.kr_login.codeSent(controller.accountController.text), style: theme.textTheme.bodySmall?.copyWith( fontSize: 13.sp, fontFamily: 'AlibabaPuHuiTi-Regular', color: const Color(0xFF666666), ), ), SizedBox(height: 24.w), ], ); } // 未发送验证码状态,显示简单标题 return Padding( padding: EdgeInsets.only(top: 24.w, bottom: 24.w), child: _buildHeaderText(AppTranslations.kr_login.welcome, theme), ); case KRLoginProgressStatus.kr_loginByPsd: // 密码登录状态 return Padding( padding: EdgeInsets.only(top: 24.w, bottom: 24.w), child: _buildHeaderText(AppTranslations.kr_login.welcome, theme), ); case KRLoginProgressStatus.kr_registerSetPsd: // 注册设置密码状态 return Padding( padding: EdgeInsets.only(top: 24.w, bottom: 24.w), child: _buildHeaderText(AppTranslations.kr_login.welcome, theme), ); case KRLoginProgressStatus.kr_forgetPsdSetPsd: // 忘记密码设置新密码状态 return Padding( padding: EdgeInsets.only(top: 24.w, bottom: 24.w), child: _buildHeaderText(AppTranslations.kr_login.welcome, theme), ); case KRLoginProgressStatus.kr_check: default: // 初始状态和其他状态 return Padding( padding: EdgeInsets.only(top: 24.w, bottom: 24.w), child: _buildHeaderText(AppTranslations.kr_login.welcome, theme), ); } } /// 判断是否为验证码输入状态 bool _isCodeInput() { switch (controller.kr_loginStatus.value) { case KRLoginProgressStatus.kr_loginByCode: case KRLoginProgressStatus.kr_registerSendCode: case KRLoginProgressStatus.kr_forgetPsdSendCode: return true; default: return false; } } /// 判断是否手机号验证 bool _isSendPhone() { return controller.kr_loginType == KRLoginType.kr_telephone; } /// 修改 _buildInputSection 方法 Widget _buildInputSection(BuildContext context, ThemeData theme) { return Obx(() { final loginStatus = controller.kr_loginStatus.value; if (loginStatus == KRLoginProgressStatus.kr_check) { return CompositedTransformTarget( link: controller.kr_layerLink, child: Container( width: double.infinity, child: Row( children: [ Obx(() => Visibility( visible: controller.kr_loginType.value == KRLoginType.kr_telephone, maintainState: true, maintainSize: false, maintainAnimation: true, child: Row( mainAxisSize: MainAxisSize.min, children: [ _buildAreaSelector(theme), SizedBox(width: 8.w), ], ), )), Expanded( child: Container( height: 52.w, padding: EdgeInsets.symmetric(horizontal: 12.w), decoration: ShapeDecoration( color: theme.cardColor, shape: RoundedRectangleBorder( side: BorderSide(width: 0.5, color: const Color(0xFFD2D2D2)), borderRadius: BorderRadius.circular(10.r), ), ), child: Row( children: [ Obx(() => Visibility( visible: controller.kr_loginType.value != KRLoginType.kr_telephone, maintainState: true, maintainAnimation: true, child: Row( mainAxisSize: MainAxisSize.min, children: [ _buildIcon("login_account"), SizedBox(width: 8.w), ], ), )), Expanded( child: TextField( focusNode: controller.kr_accountFocusNode, controller: controller.accountController, keyboardType: TextInputType.text, decoration: InputDecoration( hintText: 'login.enterEmailOrPhone'.tr, hintStyle: theme.textTheme.bodySmall?.copyWith( fontSize: 14.sp, fontFamily: 'AlibabaPuHuiTi-Regular', ), border: InputBorder.none, ), style: theme.textTheme.bodyMedium?.copyWith( fontSize: 14.sp, fontFamily: 'AlibabaPuHuiTi-Regular', ), onChanged: (value) { if (controller.kr_emailList.isNotEmpty) { _showDropdown(context); } else { _hideDropdown(); } }, ), ), _buildClearButton(), ], ), ), ), ], ), ), ); } return _buildInputContainer(context, false, theme); }); } /// 构建输入容器 Widget _buildInputContainer(BuildContext context, bool isNewPsd, ThemeData theme) { if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check && controller.kr_loginType.value == KRLoginType.kr_telephone) { return Row( children: [ _buildAreaSelector(theme), SizedBox(width: 8.w), Expanded( child: _buildPhoneInput(context, theme), ), ], ); } return CompositedTransformTarget( link: controller.kr_layerLink, child: Container( width: double.infinity, height: 52.w, decoration: ShapeDecoration( color: theme.cardColor, shape: RoundedRectangleBorder( side: BorderSide(width: 0.5, color: const Color(0xFFD2D2D2)), borderRadius: BorderRadius.circular(10.r), ), ), child: Row( children: [ Padding( padding: EdgeInsets.only(left: 12.w), child: _buildInputLeftWideget(theme), ), SizedBox(width: 8.w), Expanded( child: TextField( controller: controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check ? controller.accountController : controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByCode || controller.kr_loginStatus.value == KRLoginProgressStatus.kr_registerSendCode || controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSendCode ? controller.codeController : isNewPsd ? controller.agPsdController : controller.psdController, keyboardType: (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByCode || controller.kr_loginStatus.value == KRLoginProgressStatus.kr_registerSendCode || controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSendCode) ? TextInputType.number : TextInputType.text, decoration: InputDecoration( hintText: controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check ? 'login.enterEmailOrPhone'.tr : controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByCode || controller.kr_loginStatus.value == KRLoginProgressStatus.kr_registerSendCode || controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSendCode ? 'login.enterCode'.tr : isNewPsd ? 'login.reenterPassword'.tr : 'login.enterPassword'.tr, hintStyle: theme.textTheme.bodySmall?.copyWith( fontSize: 14.sp, fontFamily: 'AlibabaPuHuiTi-Regular', ), border: InputBorder.none, contentPadding: EdgeInsets.symmetric(vertical: 16.w), suffixIcon: (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByPsd || controller.kr_loginStatus.value == KRLoginProgressStatus.kr_registerSetPsd || controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSetPsd) && (isNewPsd ? controller.kr_agPsdHasText.value : controller.kr_psdHasText.value) ? IconButton( icon: Icon( controller.kr_obscureText.value ? Icons.visibility_off : Icons.visibility, color: const Color(0xFF999999), ), onPressed: () { controller.kr_obscureText.value = !controller.kr_obscureText.value; }, ) : null, ), style: theme.textTheme.bodyMedium?.copyWith( fontSize: 14.sp, fontFamily: 'AlibabaPuHuiTi-Regular', ), obscureText: (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByPsd || controller.kr_loginStatus.value == KRLoginProgressStatus.kr_registerSetPsd || controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSetPsd) && controller.kr_obscureText.value, onChanged: (value) { if (controller.kr_emailList.length > 0) { _showDropdown(context); } else { _hideDropdown(); } }, ), ), if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByCode || controller.kr_loginStatus.value == KRLoginProgressStatus.kr_registerSendCode || controller.kr_loginStatus.value == KRLoginProgressStatus.kr_forgetPsdSendCode) ...[ if (controller.kr_codeHasText.value) GestureDetector( onTap: () { controller.codeController.clear(); }, child: Container( height: double.infinity, padding: EdgeInsets.symmetric(horizontal: 8.w), child: _buildIcon("login_close"), ), ), _buildSendCodeButton(theme), ] else if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check ? controller.kr_accountHasText.value : isNewPsd ? controller.kr_agPsdHasText.value : controller.kr_psdHasText.value) ...[ GestureDetector( onTap: () { if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check) { controller.kr_emailList.clear(); _hideDropdown(); } if (controller.kr_loginStatus.value == KRLoginProgressStatus.kr_check) { controller.accountController.clear(); } else if (isNewPsd) { controller.agPsdController.clear(); } else { controller.psdController.clear(); } }, child: Container( height: double.infinity, padding: EdgeInsets.symmetric(horizontal: 8.w), child: _buildIcon("login_close"), ), ), ], ], ), ), ); } /// 构建发送验证码按钮 Widget _buildSendCodeButton(ThemeData theme) { return Obx(() => GestureDetector( onTap: controller.kr_canSendCode.value ? () => controller.kr_sendCode() : null, child: Container( alignment: Alignment.center, width: 100.w, padding: EdgeInsets.only(right: 4.w), child: Text( controller.kr_countdownText.value, style: theme.textTheme.bodySmall?.copyWith( fontSize: 14.sp, color: controller.kr_canSendCode.value ? const Color(0xFF1797FF) : const Color(0xFF999999), fontFamily: 'AlibabaPuHuiTi-Regular', ), ), ), )); } /// 显示悬浮框 void _showDropdown(BuildContext context) { final theme = Theme.of(context); if (controller.isDropdownVisible) return; controller.overlayEntry = OverlayEntry( builder: (_) => Positioned( width: MediaQuery.of(context).size.width - 40.w, child: CompositedTransformFollower( link: controller.kr_layerLink, showWhenUnlinked: false, offset: Offset(0, 54.w), child: Material( elevation: 4, borderRadius: BorderRadius.circular(10.r), child: Obx(() { return Container( constraints: BoxConstraints(maxHeight: 216.w), decoration: ShapeDecoration( color: theme.cardColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.r), ), ), child: ListView.builder( padding: EdgeInsets.zero, shrinkWrap: true, itemCount: controller.kr_emailList.length, itemBuilder: (context, index) { final email = controller.kr_emailList[index]; return InkWell( onTap: () { controller.accountController.text = email; controller.accountController.selection = TextSelection.fromPosition( TextPosition(offset: email.length), ); _hideDropdown(); }, child: Container( padding: EdgeInsets.symmetric( vertical: 12.w, horizontal: 15.w, ), child: Text( email, style: theme.textTheme.bodyMedium?.copyWith( fontSize: 14.sp, fontFamily: 'AlibabaPuHuiTi-Regular', ), ), ), ); }, ), ); }), ), ), ), ); Overlay.of(context).insert(controller.overlayEntry!); controller.isDropdownVisible = true; } /// 隐藏悬浮框 void _hideDropdown() { if (controller.isDropdownVisible) { controller.overlayEntry?.remove(); controller.overlayEntry = null; controller.isDropdownVisible = false; } } /// 构建输入框左侧组件 Widget _buildInputLeftWideget(ThemeData theme) { return Obx(() { switch (controller.kr_loginStatus.value) { case KRLoginProgressStatus.kr_check: // 检查状态下,根据登录类型判断返回内容 return controller.kr_loginType.value == KRLoginType.kr_telephone ? _buildChoiceCode(theme) : _buildIcon("login_account"); case KRLoginProgressStatus.kr_loginByCode: case KRLoginProgressStatus.kr_registerSendCode: case KRLoginProgressStatus.kr_forgetPsdSendCode: // 验证码相关状态,返回通用图标 return _buildIcon("login_code"); case KRLoginProgressStatus.kr_registerSetPsd: case KRLoginProgressStatus.kr_forgetPsdSetPsd: // 设置密码相关状态,返回通用图标 return _buildIcon("login_psd"); default: // 默认返回通用图标 return SizedBox(); } }); } /// 动态显示内容部分 Widget _buildDynamicContent(ThemeData theme) { // 先确定内容 Widget? content; switch (controller.kr_loginStatus.value) { case KRLoginProgressStatus.kr_check: content = _buildAgreementText(theme); case KRLoginProgressStatus.kr_loginByCode: case KRLoginProgressStatus.kr_loginByPsd: content = _buildLoginBtns(theme); default: return SizedBox(height: 17.w); // 移除 const,因为使用了扩展方法 } // 有内容时的布局 return Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 12.w), // 与输入框的间距 content, SizedBox(height: 17.w), // 与下一步按钮的间距 ], ); } /// 构建协议文本 Widget _buildAgreementText(ThemeData theme) { return Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ KrLocalImage( imageName: "selete_s", width: 20.w, height: 20.w, ), SizedBox(width: 4.w), Expanded( child: Wrap( alignment: WrapAlignment.start, spacing: 4.w, runSpacing: 4.w, crossAxisAlignment: WrapCrossAlignment.center, children: [ Text( 'login.agreeTerms'.tr, style: _commonTextStyle(fontSize: 13), ), GestureDetector( onTap: () => Get.toNamed(Routes.KR_WEBVIEW, arguments: { 'url': Api.kr_getSiteTos, 'title': 'login.termsOfService'.tr, }), child: Text( 'login.termsOfService'.tr, style: _commonTextStyle(fontSize: 13, color: const Color(0xFF1796FF)), ), ), Text( AppTranslations.kr_login.and, style: _commonTextStyle(fontSize: 13), ), GestureDetector( onTap: () => Get.toNamed(Routes.KR_WEBVIEW, arguments: { 'url': Api.kr_getSitePrivacy, 'title': 'login.privacyPolicy'.tr, }), child: Text( 'login.privacyPolicy'.tr, style: _commonTextStyle(fontSize: 13, color: const Color(0xFF1796FF)), ), ), ], ), ), ], ); } /// 构建登录按钮行 Widget _buildLoginBtns(ThemeData theme) { return SizedBox( height: 24.w, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: () => controller.kr_loginStatus.value = KRLoginProgressStatus.kr_forgetPsdSendCode, behavior: HitTestBehavior.opaque, child: Text( 'login.forgotPassword'.tr, style: theme.textTheme.bodySmall?.copyWith( fontSize: 13.sp, color: const Color(0xFF666666), fontWeight: FontWeight.w500, fontFamily: 'AlibabaPuHuiTi-Medium', ), ), ), GestureDetector( onTap: () { controller.kr_loginStatus.value = controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByPsd ? KRLoginProgressStatus.kr_loginByCode : KRLoginProgressStatus.kr_loginByPsd; }, behavior: HitTestBehavior.opaque, child: Text( controller.kr_loginStatus.value == KRLoginProgressStatus.kr_loginByPsd ? 'login.codeLogin'.tr : "login.passwordLogin".tr, style: theme.textTheme.bodySmall?.copyWith( fontSize: 13.sp, color: const Color(0xFF666666), fontWeight: FontWeight.w500, fontFamily: 'AlibabaPuHuiTi-Medium', ), ), ), ], ), ); } /// 构建下一步按钮 Widget _buildNextButton(String text, ThemeData theme) { return TextButton( onPressed: () { switch (controller.kr_loginStatus.value) { case KRLoginProgressStatus.kr_check: controller.kr_check(); break; case KRLoginProgressStatus.kr_loginByCode: case KRLoginProgressStatus.kr_loginByPsd: controller.kr_login(); break; case KRLoginProgressStatus.kr_registerSendCode: controller.kr_checkCode(); break; case KRLoginProgressStatus.kr_registerSetPsd: controller.kr_register(); break; case KRLoginProgressStatus.kr_forgetPsdSendCode: controller.kr_checkCode(); break; case KRLoginProgressStatus.kr_forgetPsdSetPsd: controller.kr_setNewPsdByForgetPsd(); break; } }, style: TextButton.styleFrom( padding: EdgeInsets.zero, minimumSize: Size.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), child: Container( width: double.infinity, height: 52.w, decoration: BoxDecoration( color: const Color(0xFF1797FF), borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: const Color(0xFF1797FF).withOpacity(0.3), blurRadius: 8.r, offset: Offset(0, 4.w), ), ], ), alignment: Alignment.center, child: Text( text, style: TextStyle( fontSize: 17.sp, color: Colors.white, fontWeight: FontWeight.w600, letterSpacing: 0.5, fontFamily: 'AlibabaPuHuiTi-Medium', ), ), ), ); } /// Widget _buildIcon(String name) { return KrLocalImage( imageName: name, width: 20.w, height: 20.w, ); } /// 修改区域选择器样式 Widget _buildChoiceCode(ThemeData theme) { return GestureDetector( onTap: () { KRSearchAreaView.show((KRAreaCodeItem selectedArea, int index) { controller.kr_cutSeleteCodeIndex.value = index; }); }, child: Container( padding: EdgeInsets.symmetric(horizontal: 12.w), child: Row( mainAxisSize: MainAxisSize.min, children: [ Obx(() => Text( controller.kr_areaCodeList[controller.kr_cutSeleteCodeIndex.value].kr_icon, style: theme.textTheme.bodyMedium?.copyWith( fontSize: 28.sp, fontFamily: 'AlibabaPuHuiTi-Regular', fontWeight: FontWeight.w400, height: 1.40, ), )), SizedBox(width: 8.w), Obx(() => Text( '+${controller.kr_areaCodeList[controller.kr_cutSeleteCodeIndex.value].kr_dialCode}', style: theme.textTheme.bodyMedium?.copyWith( fontSize: 15.sp, fontFamily: 'AlibabaPuHuiTi-Regular', fontWeight: FontWeight.w400, height: 1.40, ), )), SizedBox(width: 4.w), Icon( Icons.keyboard_arrow_down, color: theme.textTheme.bodyMedium?.color, size: 20.w, ), ], ), ), ); } /// 通用文本样式 TextStyle _commonTextStyle({ required double fontSize, FontWeight fontWeight = FontWeight.w400, Color? color, }) { return KrAppTextStyle( fontSize: fontSize, fontWeight: fontWeight, color: color, ); } /// 构建标题文本 Widget _buildHeaderText(String text, ThemeData theme) { return Text( text, style: theme.textTheme.headlineMedium?.copyWith( fontSize: 24.sp, fontFamily: 'AlibabaPuHuiTi-Bold', color: theme.textTheme.bodyMedium?.color, height: 1.3, ), ); } Widget _buildInviteCodeInput(ThemeData theme) { return Container( width: double.infinity, padding: EdgeInsets.symmetric(horizontal: 12.w), height: 52.w, decoration: ShapeDecoration( color: theme.cardColor, shape: RoundedRectangleBorder( side: BorderSide(width: 0.5, color: const Color(0xFFD2D2D2)), borderRadius: BorderRadius.circular(10.r), ), ), child: Row( children: [ _buildIcon("login_psd"), SizedBox(width: 8.w), Expanded( child: TextField( controller: controller.inviteCodeController, decoration: InputDecoration( hintText: AppTranslations.kr_login.enterInviteCode, hintStyle: theme.textTheme.bodySmall?.copyWith( fontSize: 14.sp, fontFamily: 'AlibabaPuHuiTi-Regular', ), border: InputBorder.none, ), style: theme.textTheme.bodyMedium?.copyWith( fontSize: 14.sp, fontFamily: 'AlibabaPuHuiTi-Regular', ), ), ), Obx(() => Visibility( visible: controller.kr_inviteCodeHasText.value, child: GestureDetector( onTap: () { controller.inviteCodeController.clear(); }, child: Container( height: double.infinity, padding: EdgeInsets.only(left: 5.w, right: 5.w), child: _buildIcon("login_close"), ), ), )), ], ), ); } Widget _buildBackButton(ThemeData theme) { return GestureDetector( onTap: () { controller.kr_back(); }, child: Padding( padding: EdgeInsets.fromLTRB(0, 20.w, 0, 0), child: Row( children: [ Icon( size: 16.w, Icons.arrow_back_ios_sharp, color: theme.textTheme.bodyMedium?.color, ), SizedBox(width: 4.w), Text( AppTranslations.kr_login.back, textAlign: TextAlign.center, style: theme.textTheme.bodySmall?.copyWith( fontSize: 14.sp, fontFamily: 'AlibabaPuHuiTi-Medium', fontWeight: FontWeight.w500, color: theme.textTheme.bodyMedium?.color, height: 1.60, ), ), ], ), ), ); } Widget _buildPhoneInput(BuildContext context, ThemeData theme) { return Container( height: 52.w, padding: EdgeInsets.symmetric(horizontal: 12.w), decoration: ShapeDecoration( color: theme.cardColor, shape: RoundedRectangleBorder( side: BorderSide(width: 0.5, color: const Color(0xFFD2D2D2)), borderRadius: BorderRadius.circular(10.r), ), ), child: Row( children: [ _buildIcon("login_account"), SizedBox(width: 8.w), Expanded( child: Focus( onFocusChange: (hasFocus) { if (hasFocus) { controller.kr_accountFocusNode.requestFocus(); } }, child: TextField( focusNode: controller.kr_accountFocusNode, controller: controller.accountController, keyboardType: TextInputType.phone, decoration: InputDecoration( hintText: 'login.enterEmailOrPhone'.tr, hintStyle: theme.textTheme.bodySmall?.copyWith( fontSize: 14.sp, fontFamily: 'AlibabaPuHuiTi-Regular', ), border: InputBorder.none, ), style: theme.textTheme.bodyMedium?.copyWith( fontSize: 14.sp, fontFamily: 'AlibabaPuHuiTi-Regular', ), ), ), ), _buildClearButton(), ], ), ); } Widget _buildClearButton() { return Obx(() => Visibility( visible: controller.kr_accountHasText.value, child: GestureDetector( onTap: () { controller.accountController.clear(); }, child: Container( height: double.infinity, padding: EdgeInsets.only(left: 5.w, right: 5.w), child: _buildIcon("login_close"), ), ), )); } Widget _buildAreaSelector(ThemeData theme) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { KRSearchAreaView.show((KRAreaCodeItem selectedArea, int index) { controller.kr_cutSeleteCodeIndex.value = index; }); }, child: Container( height: 52.w, decoration: ShapeDecoration( color: theme.cardColor, shape: RoundedRectangleBorder( side: BorderSide(width: 0.5, color: const Color(0xFFD2D2D2)), borderRadius: BorderRadius.circular(10.r), ), ), child: _buildChoiceCode(theme), ), ); } }