import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:keyboard/base/base_page.dart'; import 'package:keyboard/module/login/login_controller.dart'; import 'package:get/get.dart'; import 'package:keyboard/router/app_pages.dart'; import 'package:keyboard/utils/common_expand.dart'; import '../../data/consts/web_url.dart'; import '../../resource/assets.gen.dart'; import '../../resource/colors.gen.dart'; import '../../resource/string.gen.dart'; import '../../utils/styles.dart'; import '../../widget/click_text_span.dart'; class LoginPage extends BasePage { const LoginPage({super.key}); static start() { Get.toNamed(RoutePath.login); } @override Color backgroundColor() { return const Color(0xFFF6F5FA); } @override immersive() { return true; } @override Widget buildBody(BuildContext context) { return Stack( children: [ Assets.images.bgLogin.image(fit: BoxFit.contain, width: 360.w), SafeArea( child: Column( children: [ SizedBox(height: 225.w), buildPhoneTextFiled(), SizedBox(height: 16.w), buildCodeTextFiled(), SizedBox(height: 46.w), buildLoginButton(), SizedBox(height: 25.w), _buildPrivacy(), SizedBox(height: 100.w), buildOtherLogin(), ], ), ), ], ); } Widget buildPhoneTextFiled() { return Container( height: 48.w, margin: EdgeInsets.symmetric(horizontal: 20.w), padding: EdgeInsets.symmetric(horizontal: 16.w), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(100.w), ), child: Row( children: [ Expanded( child: TextField( cursorHeight: 20.w, style: TextStyle( fontSize: 14.sp, color: Colors.black.withAlpha( 204), fontWeight: FontWeight.w500, ), maxLines: 1, maxLength: 11, keyboardType: TextInputType.phone, inputFormatters: [FilteringTextInputFormatter.digitsOnly], textAlignVertical: TextAlignVertical.center, textInputAction: TextInputAction.next, decoration: InputDecoration( hintText: StringName.loginEtPhoneHint, counterText: '', hintStyle: TextStyle( fontSize: 14.sp, color: Colors.black.withAlpha(61), fontWeight: FontWeight.normal, ), labelStyle: TextStyle( fontSize: 14.sp, color: ColorName.primaryTextColor, ), contentPadding: const EdgeInsets.all(0), border: const OutlineInputBorder(borderSide: BorderSide.none), enabled: true, ), onChanged: controller.onPhoneChanged, ), ), ], ), ); } Widget buildCodeTextFiled() { return Container( height: 48.w, margin: EdgeInsets.symmetric(horizontal: 20.w), padding: EdgeInsets.symmetric(horizontal: 16.w), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(100.w), ), child: Row( children: [ Expanded( child: TextField( cursorHeight: 20.w, style: TextStyle( fontSize: 14.sp, color: Colors.black.withAlpha( 204), fontWeight: FontWeight.w500, ), maxLines: 1, maxLength: 4, keyboardType: TextInputType.phone, inputFormatters: [FilteringTextInputFormatter.digitsOnly], textAlignVertical: TextAlignVertical.center, textInputAction: TextInputAction.next, decoration: InputDecoration( hintText: StringName.loginPrintVerificationCode, counterText: '', hintStyle: TextStyle( fontSize: 14.sp, color: Colors.black.withAlpha(61), fontWeight: FontWeight.normal, ), labelStyle: TextStyle( fontSize: 14.sp, color: ColorName.primaryTextColor, ), contentPadding: const EdgeInsets.all(0), border: const OutlineInputBorder(borderSide: BorderSide.none), enabled: true, ), onChanged: controller.onCodeChanged, ), ), buildVerificationCodeSendBtn(), ], ), ); } Widget buildVerificationCodeSendBtn() { return GestureDetector( onTap: controller.onSendVerificationCode, child: Container( margin: EdgeInsets.only(left: 12.w, right: 8.w), child: Obx(() { String txt = ""; if (controller.countDown != null) { txt = '${controller.countDown}${StringName.loginRetransmissionCode}'; } else { if (controller.isFirstSend) { txt = StringName.loginSendVerificationCode; } else { txt = StringName.loginResendCode; } } return Text( txt, style: TextStyle( fontSize: 14.sp, color: controller.isFirstSend ? Colors.black.withAlpha(204) : Color(0xCC7D46FC) ), ); }), ), ); } Widget buildLoginButton() { return GestureDetector( onTap: () { controller.onLoginClick(); }, child: Container( height: 48.w, margin: EdgeInsets.symmetric(horizontal: 24.w), child: Row( children: [ Expanded( child: Obx(() { return Container( height: 48.w, decoration: controller.phone.length == 11 && controller.code.isNotEmpty && controller.isAgree ? Styles.getActivateButtonDecoration(50.r) : Styles.getInactiveButtonDecoration(50.r), child: Center( child: Text( StringName.login, style: TextStyle(color: Colors.white, fontSize: 16.sp), ), ), ); }), ), ], ), ), ); } Widget _buildPrivacy() { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Obx(() { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { controller.clickAgree(); }, child: Padding( padding: EdgeInsets.symmetric(vertical: 20.w,horizontal: 20.w), child: controller.isAgree ? Assets.images.iconLoginAgreePrivacy.image( width: 14.w, height: 14.w, ) : Container( width: 14.w, height: 14.w, child: Container( decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: Colors.black.withAlpha(153), width: 1.w, ), ), ), ), ), ); }), Transform.translate(offset: Offset(-17.w,0),child: Text.rich( TextSpan( children: [ TextSpan( text: StringName.textSpanIHaveReadAndAgree, style: TextStyle( color: Colors.black.withAlpha(128), fontSize: 12.sp, fontWeight: FontWeight.w400, ), ), ClickTextSpan( text: StringName.textSpanPrivacyPolicy, url: WebUrl.privacyPolicy, fontSize: 12.sp, color: Colors.black.withAlpha(204), ), TextSpan( text: StringName.textSpanAnd, style: TextStyle( color: Colors.black.withAlpha(128), fontSize: 12.sp, fontWeight: FontWeight.w400, ), ), ClickTextSpan( text: StringName.textSpanServiceTerms, url: WebUrl.serviceAgreement, color: Colors.black.withAlpha(204), fontSize: 12.sp, ), ], ), ),), ], ); } Widget buildOtherLogin() { return Container( child: Column( children: [ Text( StringName.loginOtherlogin, style: TextStyle( color: Colors.black.withValues(alpha: 0.5), fontSize: 12.sp, height: 0, ), ), SizedBox(height: 18.h), Material( color: Colors.white, shape: const CircleBorder(), child: InkWell( customBorder: const CircleBorder(), // 保证点击区域是圆的 onTap: () { controller.clickWxLogin(); }, child: SizedBox( width: 44.w, height: 44.w, child: Center( child: Assets.images.iconWechatLogoBlack.image( width: 22.w, height: 22.w, ), ), ), ), ), SizedBox(height: 6.w), Text( StringName.wechat, textAlign: TextAlign.center, style: TextStyle( color: Colors.black.withValues(alpha: 0.5), fontSize: 12.sp, height: 0, ), ), ], ), ); } }