view.dart 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. import 'package:electronic_assistant/base/base_page.dart';
  2. import 'package:electronic_assistant/data/repositories/account_repository.dart';
  3. import 'package:electronic_assistant/resource/assets.gen.dart';
  4. import 'package:electronic_assistant/resource/colors.gen.dart';
  5. import 'package:electronic_assistant/utils/expand.dart';
  6. import 'package:electronic_assistant/widget/login_code_btn.dart';
  7. import 'package:flutter/material.dart';
  8. import 'package:flutter/services.dart';
  9. import 'package:flutter_screenutil/flutter_screenutil.dart';
  10. import 'package:get/get.dart';
  11. import 'controller.dart';
  12. class LoginPage extends BasePage<LoginController> {
  13. const LoginPage({super.key});
  14. @override
  15. bool immersive() {
  16. return true;
  17. }
  18. // 点击空白处收起键盘
  19. @override
  20. void backgroundOnTapEvent() {
  21. super.backgroundOnTapEvent();
  22. FocusScope.of(Get.context!).requestFocus(FocusNode());
  23. }
  24. @override
  25. Widget buildBody(BuildContext context) {
  26. return Stack(
  27. children: [
  28. _buildBackgroundImage(),
  29. Scaffold(
  30. resizeToAvoidBottomInset: false,
  31. backgroundColor: Colors.transparent,
  32. appBar: AppBar(
  33. leading: IconButton(
  34. icon: const Icon(Icons.arrow_back_ios_new_rounded),
  35. onPressed: () {
  36. Get.back(result: accountRepository.isLogin.value);
  37. },
  38. ),
  39. backgroundColor: Colors.transparent,
  40. systemOverlayStyle: SystemUiOverlayStyle.dark,
  41. ),
  42. body: Column(
  43. crossAxisAlignment: CrossAxisAlignment.start,
  44. children: [
  45. Container(
  46. margin: EdgeInsets.only(left: 28.w, top: 64.h),
  47. width: 194.w,
  48. height: 71.h,
  49. child: Image(image: Assets.images.iconLoginLogo.provider()),
  50. ),
  51. _buildPhoneTextField(),
  52. _buildCodeTextField(),
  53. _buildLoginBtn(),
  54. _buildAgreeText(),
  55. ],
  56. ),
  57. ),
  58. ],
  59. );
  60. }
  61. // 背景图片
  62. Widget _buildBackgroundImage() {
  63. return Image(image: Assets.images.bgLogin.provider());
  64. }
  65. // 电话号码输入框
  66. Widget _buildPhoneTextField() {
  67. return Container(
  68. margin: EdgeInsets.only(top: 44.h, left: 28.w, right: 28.w),
  69. alignment: Alignment.center,
  70. height: 44.h,
  71. decoration: BoxDecoration(
  72. border: Border(
  73. bottom: BorderSide(
  74. width: 1.0,
  75. color: "#F0F0F0".toColor(),
  76. ),
  77. ),
  78. ),
  79. child: TextField(
  80. focusNode: controller.phoneFocusNode,
  81. maxLines: 1,
  82. textAlignVertical: TextAlignVertical.center,
  83. textInputAction: TextInputAction.next,
  84. decoration: InputDecoration(
  85. hintText: '输入手机号码',
  86. hintStyle: TextStyle(fontSize: 16, color: "#AFAFAF".toColor()),
  87. labelStyle: const TextStyle(
  88. fontSize: 16,
  89. color: ColorName.primaryTextColor,
  90. ),
  91. contentPadding: const EdgeInsets.all(0),
  92. border: const OutlineInputBorder(borderSide: BorderSide.none),
  93. enabled: true,
  94. ),
  95. style: TextStyle(fontSize: 14.sp),
  96. onChanged: (value) {
  97. controller.setPhone(value);
  98. },
  99. ),
  100. );
  101. }
  102. // 验证码输入框
  103. Widget _buildCodeTextField() {
  104. return Container(
  105. margin: EdgeInsets.only(top: 36.h, left: 28.w, right: 28.w),
  106. alignment: Alignment.center,
  107. height: 44.h,
  108. decoration: BoxDecoration(
  109. border: Border(
  110. bottom: BorderSide(
  111. width: 1.0,
  112. color: "#F0F0F0".toColor(),
  113. ),
  114. ),
  115. ),
  116. child: Row(
  117. children: [
  118. Expanded(
  119. child: TextField(
  120. maxLines: 1,
  121. textAlignVertical: TextAlignVertical.center,
  122. textInputAction: TextInputAction.done,
  123. decoration: InputDecoration(
  124. hintText: '输入验证码',
  125. hintStyle: TextStyle(fontSize: 16, color: "#AFAFAF".toColor()),
  126. labelStyle: const TextStyle(
  127. fontSize: 16,
  128. color: ColorName.primaryTextColor,
  129. ),
  130. contentPadding: const EdgeInsets.all(0),
  131. border: const OutlineInputBorder(borderSide: BorderSide.none),
  132. enabled: true,
  133. ),
  134. style: TextStyle(fontSize: 14.sp),
  135. onChanged: (value) {
  136. controller.setCode(value);
  137. },
  138. ),
  139. ),
  140. LoginCodeBtn(
  141. onTapCallback: () {
  142. controller.getUserCode();
  143. },
  144. available: true,
  145. ),
  146. ],
  147. ),
  148. );
  149. }
  150. // 登录按钮
  151. Widget _buildLoginBtn() {
  152. return GestureDetector(
  153. onTap: () {
  154. controller.login();
  155. },
  156. child: Container(
  157. margin: EdgeInsets.only(
  158. top: 54.h,
  159. left: 28.w,
  160. right: 28.w,
  161. ),
  162. height: 48.h,
  163. alignment: Alignment.center,
  164. decoration: BoxDecoration(
  165. gradient: LinearGradient(
  166. colors: ['#6177F2'.toColor(), '#8B9DFF'.toColor()],
  167. stops: const [0, 1.0],
  168. ),
  169. borderRadius: BorderRadius.circular(8),
  170. ),
  171. child: const Text(
  172. "登录",
  173. style: TextStyle(
  174. color: ColorName.white,
  175. fontSize: 16,
  176. fontWeight: FontWeight.w500,
  177. ),
  178. ),
  179. ),
  180. );
  181. }
  182. Widget _buildAgreeText() {
  183. return Container(
  184. margin: EdgeInsets.only(left: 28.w, top: 16.h),
  185. child: Row(
  186. children: [
  187. Obx(
  188. () {
  189. return GestureDetector(
  190. onTap: () {
  191. controller.isAgree.value = !controller.isAgree.value;
  192. },
  193. child: SizedBox(
  194. width: 20.w,
  195. height: 20.w,
  196. child: controller.isAgree.value
  197. ? Assets.images.iconSelectTrue.image()
  198. : Assets.images.iconSelectFalse.image()),
  199. );
  200. },
  201. ),
  202. Text(
  203. "我已阅读并同意",
  204. style: TextStyle(
  205. color: "#AFAFAF".toColor(),
  206. fontSize: 12,
  207. ),
  208. ),
  209. GestureDetector(
  210. onTap: () {},
  211. child: Text(
  212. "《隐私政策》",
  213. style: TextStyle(
  214. color: "#5E8BFF".toColor(),
  215. fontSize: 12,
  216. ),
  217. ),
  218. ),
  219. Text(
  220. "和",
  221. style: TextStyle(
  222. color: "#AFAFAF".toColor(),
  223. fontSize: 12,
  224. ),
  225. ),
  226. GestureDetector(
  227. onTap: () {},
  228. child: Text(
  229. "《用户使用协议》",
  230. style: TextStyle(
  231. color: "#5E8BFF".toColor(),
  232. fontSize: 12,
  233. ),
  234. ),
  235. ),
  236. ],
  237. ),
  238. );
  239. }
  240. }