这是CaiYouHui前端,一个关于flutter的安卓app,前端使用flutter实现

login_screen.dart 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. import '../../providers/auth_provider.dart';
  4. import '../../../core/constants/route_constants.dart';
  5. import '../../widgets/common/app_button.dart';
  6. import '../../widgets/common/app_text_field.dart';
  7. import '../../widgets/common/loading_indicator.dart';
  8. class LoginScreen extends StatefulWidget {
  9. final VoidCallback? onSuccess;
  10. const LoginScreen({super.key, this.onSuccess});
  11. @override
  12. State<LoginScreen> createState() => _LoginScreenState();
  13. }
  14. class _LoginScreenState extends State<LoginScreen> {
  15. final _formKey = GlobalKey<FormState>();
  16. final _emailController = TextEditingController(text: 'test@example.com');
  17. final _passwordController = TextEditingController(text: '123456');
  18. @override
  19. void dispose() {
  20. _emailController.dispose();
  21. _passwordController.dispose();
  22. super.dispose();
  23. }
  24. @override
  25. Widget build(BuildContext context) {
  26. final authProvider = Provider.of<AuthProvider>(context);
  27. return Scaffold(
  28. appBar: AppBar(
  29. title: const Text('登录'),
  30. ),
  31. body: SingleChildScrollView(
  32. child: Padding(
  33. padding: const EdgeInsets.all(24.0),
  34. child: Form(
  35. key: _formKey,
  36. child: Column(
  37. crossAxisAlignment: CrossAxisAlignment.start,
  38. children: [
  39. const SizedBox(height: 40),
  40. const Center(
  41. child: Text(
  42. '欢迎回来',
  43. style: TextStyle(
  44. fontSize: 28,
  45. fontWeight: FontWeight.bold,
  46. ),
  47. ),
  48. ),
  49. const SizedBox(height: 8),
  50. const Center(
  51. child: Text(
  52. '请输入您的账号信息',
  53. style: TextStyle(
  54. fontSize: 16,
  55. color: Colors.grey,
  56. ),
  57. ),
  58. ),
  59. const SizedBox(height: 40),
  60. AppTextField(
  61. controller: _emailController,
  62. labelText: '邮箱地址',
  63. hintText: '请输入邮箱',
  64. keyboardType: TextInputType.emailAddress,
  65. prefixIcon: const Icon(Icons.email_outlined),
  66. validator: (value) {
  67. if (value == null || value.isEmpty) {
  68. return '请输入邮箱地址';
  69. }
  70. if (!value.contains('@')) {
  71. return '请输入有效的邮箱地址';
  72. }
  73. return null;
  74. },
  75. ),
  76. const SizedBox(height: 20),
  77. AppTextField(
  78. controller: _passwordController,
  79. labelText: '密码',
  80. hintText: '请输入密码',
  81. obscureText: true,
  82. prefixIcon: const Icon(Icons.lock_outline),
  83. validator: (value) {
  84. if (value == null || value.isEmpty) {
  85. return '请输入密码';
  86. }
  87. if (value.length < 6) {
  88. return '密码至少需要6位字符';
  89. }
  90. return null;
  91. },
  92. ),
  93. const SizedBox(height: 30),
  94. if (authProvider.error != null)
  95. Padding(
  96. padding: const EdgeInsets.only(bottom: 16),
  97. child: Text(
  98. authProvider.error!,
  99. style: const TextStyle(
  100. color: Colors.red,
  101. fontSize: 14,
  102. ),
  103. ),
  104. ),
  105. if (authProvider.isLoading)
  106. const LoadingIndicator()
  107. else
  108. AppButton(
  109. text: '登录',
  110. onPressed: () async {
  111. if (_formKey.currentState!.validate()) {
  112. await authProvider.login(
  113. _emailController.text.trim(),
  114. _passwordController.text,
  115. );
  116. if (authProvider.isAuthenticated) {
  117. widget.onSuccess?.call();
  118. Navigator.of(context).pushReplacementNamed(RouteConstants.home);
  119. }
  120. }
  121. },
  122. ),
  123. const SizedBox(height: 20),
  124. Center(
  125. child: TextButton(
  126. onPressed: () {
  127. Navigator.of(context).pushNamed(RouteConstants.register);
  128. },
  129. child: const Text(
  130. '还没有账号?立即注册',
  131. style: TextStyle(
  132. fontSize: 14,
  133. color: Colors.blue,
  134. ),
  135. ),
  136. ),
  137. ),
  138. const SizedBox(height: 30),
  139. const Row(
  140. children: [
  141. Expanded(child: Divider()),
  142. Padding(
  143. padding: EdgeInsets.symmetric(horizontal: 16),
  144. child: Text('或'),
  145. ),
  146. Expanded(child: Divider()),
  147. ],
  148. ),
  149. const SizedBox(height: 20),
  150. Row(
  151. mainAxisAlignment: MainAxisAlignment.center,
  152. children: [
  153. IconButton(
  154. onPressed: () {},
  155. icon: Container(
  156. padding: const EdgeInsets.all(10),
  157. decoration: BoxDecoration(
  158. color: Colors.grey[100],
  159. borderRadius: BorderRadius.circular(50),
  160. ),
  161. child: const Icon(Icons.wechat, color: Colors.green),
  162. ),
  163. ),
  164. IconButton(
  165. onPressed: () {},
  166. icon: Container(
  167. padding: const EdgeInsets.all(10),
  168. decoration: BoxDecoration(
  169. color: Colors.grey[100],
  170. borderRadius: BorderRadius.circular(50),
  171. ),
  172. child: const Icon(Icons.wechat, color: Colors.blue),
  173. ),
  174. ),
  175. ],
  176. ),
  177. ],
  178. ),
  179. ),
  180. ),
  181. ),
  182. );
  183. }
  184. }