login_page.dart 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/gestures.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter/src/widgets/framework.dart';
  5. import 'package:flutter_screenutil/flutter_screenutil.dart';
  6. import 'package:get/get.dart';
  7. import 'package:get/get_core/src/get_main.dart';
  8. import 'package:location/base/base_page.dart';
  9. import 'package:location/data/consts/web_url.dart';
  10. import 'package:location/resource/assets.gen.dart';
  11. import 'package:location/resource/colors.gen.dart';
  12. import 'package:location/resource/string.gen.dart';
  13. import 'package:location/router/app_pages.dart';
  14. import 'package:location/utils/common_expand.dart';
  15. import '../browser/browser_view.dart';
  16. import 'login_controller.dart';
  17. class LoginPage extends BasePage<LoginController> {
  18. const LoginPage({super.key});
  19. static void start() {
  20. Get.toNamed(RoutePath.login);
  21. }
  22. @override
  23. bool immersive() {
  24. return true;
  25. }
  26. @override
  27. Widget buildBody(BuildContext context) {
  28. return Stack(
  29. children: [
  30. AspectRatio(
  31. aspectRatio: 360 / 285,
  32. child: Assets.images.bgLoginHeadContainer
  33. .image(width: double.infinity)),
  34. buildLoginHeader(),
  35. SafeArea(
  36. child: Column(
  37. children: [
  38. SizedBox(height: 150.5.w),
  39. Expanded(
  40. child: Container(
  41. width: double.infinity,
  42. height: double.infinity,
  43. decoration: BoxDecoration(
  44. color: ColorName.white,
  45. borderRadius: BorderRadius.only(
  46. topLeft: Radius.circular(18.w),
  47. topRight: Radius.circular(18.w),
  48. ),
  49. ),
  50. child: Column(
  51. children: [
  52. SizedBox(height: 27.w),
  53. buildPhoneTextFiled(),
  54. SizedBox(height: 12.w),
  55. buildCodeTextFiled(),
  56. SizedBox(height: 10.w),
  57. buildPrivacyTxt(),
  58. SizedBox(height: 148.h),
  59. buildLoginBtn(),
  60. ],
  61. ),
  62. ),
  63. )
  64. ],
  65. ),
  66. )
  67. ],
  68. );
  69. }
  70. Widget buildPrivacyTxt() {
  71. return Padding(
  72. padding: EdgeInsets.symmetric(horizontal: 24.w),
  73. child: GestureDetector(
  74. onTap: controller.onPrivacyClick,
  75. child: Row(
  76. children: [
  77. Obx(() {
  78. return Image(
  79. image: controller.isAgreePrivacy
  80. ? Assets.images.iconCheckboxSelected.provider()
  81. : Assets.images.iconCheckboxUnSelect.provider(),
  82. width: 20.w,
  83. height: 20.w);
  84. }),
  85. RichText(
  86. text: TextSpan(
  87. style: TextStyle(
  88. color: '#A7A7A7'.color,
  89. fontSize: 12.sp,
  90. decoration: TextDecoration.none),
  91. children: [
  92. TextSpan(text: StringName.loginEtPrivacyRead),
  93. buildLinkText(StringName.privacyPolicy, WebUrl.privacyPolicy),
  94. TextSpan(text: StringName.loginEtPrivacyAnd),
  95. buildLinkText(StringName.termOfService, WebUrl.userAgreement),
  96. ]))
  97. ],
  98. ),
  99. ),
  100. );
  101. }
  102. TextSpan buildLinkText(String text, String url) {
  103. return TextSpan(
  104. text: text,
  105. style: TextStyle(color: '#2F79FF'.color),
  106. recognizer: TapGestureRecognizer()
  107. ..onTap = () {
  108. BrowserPage.start(url);
  109. },
  110. );
  111. }
  112. Widget buildCodeTextFiled() {
  113. return Container(
  114. height: 50.w,
  115. margin: EdgeInsets.symmetric(horizontal: 24.w),
  116. padding: EdgeInsets.symmetric(horizontal: 12.w),
  117. decoration: BoxDecoration(
  118. color: '#FAFAFA'.color, borderRadius: BorderRadius.circular(6.w)),
  119. child: Row(
  120. children: [
  121. Expanded(
  122. child: TextField(
  123. cursorHeight: 20.w,
  124. style: TextStyle(
  125. fontSize: 16.sp,
  126. color: ColorName.primaryTextColor,
  127. fontWeight: FontWeight.bold),
  128. maxLines: 1,
  129. maxLength: 4,
  130. keyboardType: TextInputType.phone,
  131. textAlignVertical: TextAlignVertical.center,
  132. textInputAction: TextInputAction.next,
  133. decoration: InputDecoration(
  134. hintText: StringName.loginPrintVerificationCode,
  135. counterText: '',
  136. hintStyle: TextStyle(
  137. fontSize: 16.sp,
  138. color: "#A7A7A7".toColor(),
  139. fontWeight: FontWeight.normal),
  140. labelStyle: TextStyle(
  141. fontSize: 16.sp,
  142. color: ColorName.primaryTextColor,
  143. ),
  144. contentPadding: const EdgeInsets.all(0),
  145. border: const OutlineInputBorder(borderSide: BorderSide.none),
  146. enabled: true,
  147. ),
  148. onChanged: controller.onCodeChanged,
  149. ),
  150. ),
  151. buildVerificationCodeSendBtn()
  152. ],
  153. ),
  154. );
  155. }
  156. Widget buildVerificationCodeSendBtn() {
  157. return Obx(() {
  158. return GestureDetector(
  159. onTap: controller.onSendVerificationCode,
  160. child: Container(
  161. margin: EdgeInsets.only(left: 12.w),
  162. decoration: BoxDecoration(
  163. color: controller.phone.length == 11 &&
  164. controller.countDown == null
  165. ? '#7B7DFF'.color
  166. : '#337B7DFF'.color,
  167. borderRadius: BorderRadius.circular(4.w)),
  168. padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 6.w),
  169. child: Obx(() {
  170. String txt = "";
  171. if (controller.countDown != null) {
  172. txt =
  173. '${controller.countDown}${StringName.loginRetransmissionCode}';
  174. } else {
  175. txt = StringName.loginSendVerificationCode;
  176. }
  177. return Text(txt,
  178. style: TextStyle(fontSize: 14.sp, color: ColorName.white));
  179. })),
  180. );
  181. });
  182. }
  183. Widget buildPhoneTextFiled() {
  184. return Container(
  185. height: 50.w,
  186. margin: EdgeInsets.symmetric(horizontal: 24.w),
  187. padding: EdgeInsets.symmetric(horizontal: 12.w),
  188. decoration: BoxDecoration(
  189. color: '#FAFAFA'.color, borderRadius: BorderRadius.circular(6.w)),
  190. child: Row(
  191. children: [
  192. Text('+86',
  193. style: TextStyle(
  194. fontSize: 16.sp,
  195. color: '#202020'.color,
  196. fontWeight: FontWeight.bold)),
  197. SizedBox(width: 8.w),
  198. Container(width: 1.w, height: 20.w, color: '#E2E2E2'.color),
  199. SizedBox(width: 25.w),
  200. Expanded(
  201. child: TextField(
  202. cursorHeight: 20.w,
  203. style: TextStyle(
  204. fontSize: 16.sp,
  205. color: ColorName.primaryTextColor,
  206. fontWeight: FontWeight.bold),
  207. maxLines: 1,
  208. maxLength: 11,
  209. keyboardType: TextInputType.phone,
  210. textAlignVertical: TextAlignVertical.center,
  211. textInputAction: TextInputAction.next,
  212. decoration: InputDecoration(
  213. hintText: StringName.loginEtPhoneHint,
  214. counterText: '',
  215. hintStyle: TextStyle(
  216. fontSize: 16.sp,
  217. color: "#A7A7A7".toColor(),
  218. fontWeight: FontWeight.normal),
  219. labelStyle: TextStyle(
  220. fontSize: 16.sp,
  221. color: ColorName.primaryTextColor,
  222. ),
  223. contentPadding: const EdgeInsets.all(0),
  224. border: const OutlineInputBorder(borderSide: BorderSide.none),
  225. enabled: true,
  226. ),
  227. onChanged: controller.onPhoneChanged,
  228. ),
  229. )
  230. ],
  231. ),
  232. );
  233. }
  234. Widget buildLoginHeader() {
  235. return SafeArea(
  236. child: Container(
  237. margin: EdgeInsets.only(top: 23.w, left: 12.w),
  238. child: Row(
  239. children: [
  240. GestureDetector(
  241. onTap: controller.onBackClick,
  242. child: Assets.images.iconWhiteBack
  243. .image(width: 25.w, height: 25.w)),
  244. SizedBox(width: 4.w),
  245. Text(StringName.login,
  246. style: TextStyle(fontSize: 17.sp, color: ColorName.white))
  247. ],
  248. )),
  249. );
  250. }
  251. Widget buildLoginBtn() {
  252. return Obx(() {
  253. return GestureDetector(
  254. onTap: controller.onLoginClick,
  255. child: Container(
  256. decoration: BoxDecoration(
  257. color: controller.phone.length == 11 &&
  258. controller.code.isNotEmpty &&
  259. controller.isAgreePrivacy
  260. ? '#7B7DFF'.color
  261. : '#337B7DFF'.color,
  262. borderRadius: BorderRadius.circular(30.w)),
  263. width: 280.w,
  264. height: 44.w,
  265. child: Center(
  266. child: Text(StringName.login,
  267. style: TextStyle(
  268. fontSize: 16.sp,
  269. color: ColorName.white,
  270. fontWeight: FontWeight.bold)),
  271. ),
  272. ),
  273. );
  274. });
  275. }
  276. }