login_page.dart 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
  4. import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
  5. import 'package:lszlgl/router/my_navigator.dart';
  6. import 'package:lszlgl/widget/button.dart';
  7. import '../../base/base_state.dart';
  8. import '../main_tab_page.dart';
  9. /// 登录页面
  10. class LoginPage extends StatefulWidget {
  11. const LoginPage({Key? key}) : super(key: key);
  12. @override
  13. State<LoginPage> createState() => _LoginPageState();
  14. }
  15. class _LoginPageState extends BaseState<LoginPage> {
  16. late TextEditingController accountCtrl;
  17. late TextEditingController pwdCtrl;
  18. void onLogin() {
  19. var account = accountCtrl.text;
  20. var pwd = pwdCtrl.text;
  21. if (account.isEmpty || pwd.isEmpty) {
  22. SmartDialog.showToast('请输入账号和密码');
  23. return;
  24. }
  25. MyRouter.startMain(popAll: true);
  26. }
  27. @override
  28. void initState() {
  29. super.initState();
  30. accountCtrl = TextEditingController();
  31. pwdCtrl = TextEditingController();
  32. }
  33. @override
  34. void dispose() {
  35. accountCtrl.dispose();
  36. pwdCtrl.dispose();
  37. super.dispose();
  38. }
  39. @override
  40. Widget build(BuildContext context) {
  41. return Scaffold(
  42. backgroundColor: const Color(0xFF49AAF2),
  43. body: KeyboardDismissOnTap(
  44. dismissOnCapturedTaps: true,
  45. child: SingleChildScrollView(
  46. physics: const BouncingScrollPhysics(),
  47. child: Stack(
  48. children: [
  49. Positioned.fill(child: Image.asset(imgLoginBg, fit: BoxFit.fill)),
  50. SizedBox(
  51. height: MediaQuery.of(context).size.height,
  52. child: buildBody(),
  53. ),
  54. ],
  55. ),
  56. ),
  57. ),
  58. );
  59. }
  60. Widget buildBody() {
  61. return Column(
  62. children: [
  63. const SizedBox(height: 88),
  64. Container(
  65. width: double.infinity,
  66. padding: const EdgeInsets.symmetric(horizontal: 72),
  67. child: Image.asset(imgLoginTitle, fit: BoxFit.fill),
  68. ),
  69. const SizedBox(height: 32),
  70. loginContainer(),
  71. ],
  72. );
  73. }
  74. Widget loginContainer() {
  75. return SizedBox(
  76. width: double.infinity,
  77. child: Stack(
  78. alignment: Alignment.topCenter,
  79. children: [
  80. buildInputContent(),
  81. userTitle(),
  82. ],
  83. ),
  84. );
  85. }
  86. Widget userTitle() {
  87. return Container(
  88. height: 48,
  89. width: 174,
  90. alignment: Alignment.center,
  91. decoration: const BoxDecoration(
  92. color: Colors.white,
  93. borderRadius: BorderRadius.all(Radius.circular(100)),
  94. border: Border.fromBorderSide(BorderSide(color: Color(0xFF49AAF2), width: 1)),
  95. boxShadow: [BoxShadow(color: Color(0x941C90FF), offset: Offset(0, 3))],
  96. ),
  97. child: const Text(
  98. '用户登录',
  99. style: TextStyle(color: Color(0xFF1187DE), fontSize: 18),
  100. ),
  101. );
  102. }
  103. Widget buildInputContent() {
  104. return Container(
  105. margin: const EdgeInsets.only(top: 14, left: 18, right: 18),
  106. padding: const EdgeInsets.all(10),
  107. decoration: BoxDecoration(
  108. color: Colors.white.withOpacity(0.2),
  109. borderRadius: const BorderRadius.all(Radius.circular(24)),
  110. ),
  111. child: Container(
  112. padding: const EdgeInsets.symmetric(horizontal: 32),
  113. alignment: Alignment.center,
  114. decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(24))),
  115. child: Column(
  116. children: [
  117. const SizedBox(height: 72),
  118. buildEdit(
  119. ctrl: accountCtrl,
  120. hint: '请输入登录账号',
  121. icon: imgLoginAccount,
  122. action: TextInputAction.next,
  123. ),
  124. const SizedBox(height: 32),
  125. buildEdit(
  126. ctrl: pwdCtrl,
  127. hint: '请输入登录密码',
  128. icon: imgLoginPwd,
  129. obscure: true,
  130. onSubmit: (value) => onLogin(),
  131. ),
  132. const SizedBox(height: 80),
  133. buildLoginBtn(),
  134. const SizedBox(height: 56),
  135. ],
  136. ),
  137. ),
  138. );
  139. }
  140. Widget buildEdit({
  141. required TextEditingController ctrl,
  142. required String hint,
  143. String? icon,
  144. TextInputAction action = TextInputAction.done,
  145. bool obscure = false,
  146. ValueChanged? onSubmit,
  147. }) {
  148. return TextField(
  149. controller: ctrl,
  150. decoration: InputDecoration(
  151. prefixIcon: icon == null
  152. ? null
  153. : Padding(
  154. padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
  155. child: Image.asset(icon, height: 22),
  156. ),
  157. prefixIconConstraints: const BoxConstraints(),
  158. border: const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(100))),
  159. enabledBorder: const OutlineInputBorder(
  160. borderSide: BorderSide(color: Color(0xFFE6E6E6), width: 1),
  161. borderRadius: BorderRadius.all(Radius.circular(100)),
  162. ),
  163. hintText: hint,
  164. hintStyle: const TextStyle(color: Color(0xFFBBBBBB)),
  165. isDense: true,
  166. contentPadding: EdgeInsets.zero,
  167. ),
  168. style: const TextStyle(fontSize: 14),
  169. textInputAction: action,
  170. obscureText: obscure,
  171. onSubmitted: onSubmit,
  172. );
  173. }
  174. Widget buildLoginBtn() {
  175. return MyButton(
  176. '登录',
  177. onTap: onLogin,
  178. gradient: const LinearGradient(colors: [Color(0xFF60B5F4), Color(0xFF62A4D6)]),
  179. );
  180. return GestureDetector(
  181. onTap: onLogin,
  182. child: Container(
  183. alignment: Alignment.center,
  184. padding: const EdgeInsets.symmetric(vertical: 12),
  185. decoration: const BoxDecoration(
  186. gradient: LinearGradient(colors: [Color(0xFF60B5F4), Color(0xFF62A4D6)]),
  187. borderRadius: BorderRadius.all(Radius.circular(100)),
  188. ),
  189. child: const Text('登录', style: TextStyle(fontSize: 16, color: Colors.white)),
  190. ),
  191. );
  192. }
  193. }