From 4bf67b9199cffc25939f5acd923b7fee8386e9f9 Mon Sep 17 00:00:00 2001 From: lcy <2503978335@qq.com> Date: Thu, 8 Jun 2023 13:35:18 +0800 Subject: [PATCH] feat:设置密码 --- assets/images/login_error.png | Bin 0 -> 4595 bytes assets/images/login_pass.png | Bin 0 -> 5002 bytes assets/images/steven.png | Bin 0 -> 191393 bytes lib/app/app.dart | 21 ++++++++++++--------- lib/common/widgets/hide_keyboard_widget.dart | 21 +++++++++++++++++++++ lib/common/widgets/textfiled_customer_widget.dart | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/home/home_page.dart | 16 +++++++--------- lib/home/widgets/home_tab_header_widget.dart | 4 +++- lib/login/blocs/forget_pwd_bloc.dart | 15 +++++++++++++++ lib/login/blocs/forget_pwd_event.dart | 4 ++++ lib/login/blocs/forget_pwd_state.dart | 6 ++++++ lib/login/forget_password_page.dart | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/login/login_page.dart | 145 ++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------- lib/route/route.dart | 5 +++++ 14 files changed, 351 insertions(+), 118 deletions(-) create mode 100644 assets/images/login_error.png create mode 100644 assets/images/login_pass.png create mode 100644 assets/images/steven.png create mode 100644 lib/common/widgets/hide_keyboard_widget.dart create mode 100644 lib/common/widgets/textfiled_customer_widget.dart create mode 100644 lib/login/blocs/forget_pwd_bloc.dart create mode 100644 lib/login/blocs/forget_pwd_event.dart create mode 100644 lib/login/blocs/forget_pwd_state.dart create mode 100644 lib/login/forget_password_page.dart diff --git a/assets/images/login_error.png b/assets/images/login_error.png new file mode 100644 index 0000000..60c18d1 Binary files /dev/null and b/assets/images/login_error.png differ diff --git a/assets/images/login_pass.png b/assets/images/login_pass.png new file mode 100644 index 0000000..390cdb4 Binary files /dev/null and b/assets/images/login_pass.png differ diff --git a/assets/images/steven.png b/assets/images/steven.png new file mode 100644 index 0000000..6e3f68e Binary files /dev/null and b/assets/images/steven.png differ diff --git a/lib/app/app.dart b/lib/app/app.dart index 3766fce..2c45543 100644 --- a/lib/app/app.dart +++ b/lib/app/app.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:wow_english/common/widgets/hide_keyboard_widget.dart'; import 'package:wow_english/route/route.dart'; import 'package:wow_english/tab/blocs/tab_bloc.dart'; @@ -16,16 +17,18 @@ class App extends StatelessWidget { providers: [ BlocProvider(create: (_)=> TabBloc()) ], - child: MaterialApp( - title: 'WowEnglish', - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, + child: HideKeyboard( + child: MaterialApp( + title: 'WowEnglish', + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + ), + builder: EasyLoading.init(), + initialRoute: AppRouteName.splash, + navigatorKey: AppRouter.navigatorKey, + onGenerateRoute: AppRouter.generateRoute, ), - builder: EasyLoading.init(), - initialRoute: AppRouteName.splash, - navigatorKey: AppRouter.navigatorKey, - onGenerateRoute: AppRouter.generateRoute, )), ); } diff --git a/lib/common/widgets/hide_keyboard_widget.dart b/lib/common/widgets/hide_keyboard_widget.dart new file mode 100644 index 0000000..b2b77b7 --- /dev/null +++ b/lib/common/widgets/hide_keyboard_widget.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; + +class HideKeyboard extends StatelessWidget { + + const HideKeyboard({super.key,required this.child}); + + final Widget child; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: (){ + FocusScopeNode currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) { + FocusManager.instance.primaryFocus?.unfocus(); + } + }, + child: child, + ); + } +} \ No newline at end of file diff --git a/lib/common/widgets/textfiled_customer_widget.dart b/lib/common/widgets/textfiled_customer_widget.dart new file mode 100644 index 0000000..7eae1b3 --- /dev/null +++ b/lib/common/widgets/textfiled_customer_widget.dart @@ -0,0 +1,73 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:wow_english/common/extension/string_extension.dart'; + +class TextFiledCustomerWidget extends StatefulWidget { + const TextFiledCustomerWidget({super.key, + this.controller, + this.hitStyle, + this.textStyle, + this.bgImageName, + this.hitText, + this.width, + this.height, + this.textAlign, + this.textInputType, + this.onChangeValue + }); + + final TextEditingController? controller; + final TextStyle? hitStyle; + final TextStyle? textStyle; + final String? bgImageName; + final String? hitText; + final double? width; + final double? height; + final TextAlign? textAlign; + final TextInputType? textInputType; + final Function(String value)? onChangeValue; + + @override + State createState() { + return _TextFiledCustomerWidgetState(); + } +} + +class _TextFiledCustomerWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container( + height: widget.height??45.h, + width: widget.width??double.infinity, + alignment: Alignment.center, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + '${widget.bgImageName}'.assetPng + ), + fit: BoxFit.fill, + ) + ), + child: TextField( + controller: widget.controller, + textAlign: widget.textAlign??TextAlign.center, + textInputAction: TextInputAction.done, + keyboardType: widget.textInputType, + decoration: InputDecoration( + hintText: widget.hitText??'', + border: InputBorder.none, + hintStyle: widget.hitStyle?? TextStyle( + fontSize: 16.sp, + color:const Color(0xFF999999) + ) + ), + style: widget.textStyle?? TextStyle( + color: const Color(0xFF333333), + fontSize: 16.sp, + ), + onChanged: widget.onChangeValue, + ), + ); + } +} + diff --git a/lib/home/home_page.dart b/lib/home/home_page.dart index c82d20c..ffb649a 100644 --- a/lib/home/home_page.dart +++ b/lib/home/home_page.dart @@ -7,15 +7,13 @@ class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - body: SafeArea( - child: Container( - color: Colors.white, - child: const Center( - child: Column( - children: [ - HomeTabHeaderWidget(), - ], - ), + body: Container( + color: Colors.white, + child: const Center( + child: Column( + children: [ + HomeTabHeaderWidget(), + ], ), ), ), diff --git a/lib/home/widgets/home_tab_header_widget.dart b/lib/home/widgets/home_tab_header_widget.dart index 8cad2f3..32799ea 100644 --- a/lib/home/widgets/home_tab_header_widget.dart +++ b/lib/home/widgets/home_tab_header_widget.dart @@ -14,6 +14,7 @@ class HomeTabHeaderWidget extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 9.5.w), child: Row( children: [ + ScreenUtil().bottomBarHeight.horizontalSpace, ClipRRect( borderRadius:BorderRadius.circular(21), child: Image.network( @@ -55,7 +56,8 @@ class HomeTabHeaderWidget extends StatelessWidget { IconButton( onPressed: (){}, icon: Image.asset('shop'.assetPng) - ) + ), + ScreenUtil().bottomBarHeight.horizontalSpace, ], ), ); diff --git a/lib/login/blocs/forget_pwd_bloc.dart b/lib/login/blocs/forget_pwd_bloc.dart new file mode 100644 index 0000000..d941521 --- /dev/null +++ b/lib/login/blocs/forget_pwd_bloc.dart @@ -0,0 +1,15 @@ +import 'dart:async'; + +import 'package:bloc/bloc.dart'; +import 'package:meta/meta.dart'; + +part 'forget_pwd_event.dart'; +part 'forget_pwd_state.dart'; + +class ForgetPwdBloc extends Bloc { + ForgetPwdBloc() : super(ForgetPwdInitial()) { + on((event, emit) { + // TODO: implement event handler + }); + } +} diff --git a/lib/login/blocs/forget_pwd_event.dart b/lib/login/blocs/forget_pwd_event.dart new file mode 100644 index 0000000..4fce735 --- /dev/null +++ b/lib/login/blocs/forget_pwd_event.dart @@ -0,0 +1,4 @@ +part of 'forget_pwd_bloc.dart'; + +@immutable +abstract class ForgetPwdEvent {} diff --git a/lib/login/blocs/forget_pwd_state.dart b/lib/login/blocs/forget_pwd_state.dart new file mode 100644 index 0000000..b42b55a --- /dev/null +++ b/lib/login/blocs/forget_pwd_state.dart @@ -0,0 +1,6 @@ +part of 'forget_pwd_bloc.dart'; + +@immutable +abstract class ForgetPwdState {} + +class ForgetPwdInitial extends ForgetPwdState {} diff --git a/lib/login/forget_password_page.dart b/lib/login/forget_password_page.dart new file mode 100644 index 0000000..4fd6cdf --- /dev/null +++ b/lib/login/forget_password_page.dart @@ -0,0 +1,159 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:wow_english/common/extension/string_extension.dart'; +import 'package:wow_english/common/widgets/textfiled_customer_widget.dart'; + +import 'blocs/forget_pwd_bloc.dart'; + +class ForgetPassWordPage extends StatelessWidget { + const ForgetPassWordPage({super.key, this.phoneNum}); + final String? phoneNum; + + @override + Widget build(BuildContext context) { + // TODO: implement build + return BlocProvider( + create: (context) => ForgetPwdBloc(), + child: Scaffold( + body: Container( + color: Colors.white, + child: SafeArea( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 40.w), + child: Column( + children: [ + 34.verticalSpace, + Row( + children: [ + Image.asset( + 'wow_logo'.assetPng, + height: 49.w, + width: 83.5.h, + ), + 12.5.horizontalSpace, + Text( + '欢迎登录wow english\n接下来请设置一下您的密码吧!', + style: TextStyle( + fontSize: 16.sp, + color: const Color(0xFF666666) + ), + ) + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + 43.verticalSpace, + Row( + children: [ + Expanded( + child: TextFiledCustomerWidget( + height: 55.h, + hitText: '请输入八位以上密码', + bgImageName: 'Input_layer_up', + onChangeValue: (String value) { + + }, + ) + ), + 10.horizontalSpace, + Offstage( + offstage: false, + child: Image.asset( + 'login_pass'.assetPng, + height: 30, + width: 30, + ), + ) + ], + ), + 9.verticalSpace, + const Offstage( + offstage: false, + child: Text('您已达到密码最大输入数,请妥善调整密码'), + ), + 9.verticalSpace, + Row( + children: [ + Expanded( + child: TextFiledCustomerWidget( + height: 55.h, + hitText: '请再次输入相同密码', + bgImageName: 'Input_layer_up', + onChangeValue: (String value) { + + }, + ) + ), + 10.horizontalSpace, + Offstage( + offstage: false, + child: Image.asset( + 'login_error'.assetPng, + height: 30, + width: 30, + ), + ) + ], + ), + 9.verticalSpace, + const Offstage( + offstage: false, + child: Text('请确认两次输入的密码是否一致'), + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + GestureDetector( + onTap: () { + + }, + child: Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + 'login_enter'.assetPng + ), + fit: BoxFit.fill + ), + ), + padding: const EdgeInsets.symmetric( + horizontal: 28.0, + vertical: 14.0 + ), + child: const Text( + '确定', + style: TextStyle( + color: Colors.white + ), + ), + ), + ), + 50.horizontalSpace + ], + ) + ], + ), + ), + 30.horizontalSpace, + Image.asset( + 'steven'.assetPng, + height: 254.h, + width: 100.w, + ) + ], + ), + ], + ), + ), + ), + ), + ), + );; + } +} \ No newline at end of file diff --git a/lib/login/login_page.dart b/lib/login/login_page.dart index 28fc594..bf7e8c3 100644 --- a/lib/login/login_page.dart +++ b/lib/login/login_page.dart @@ -1,7 +1,10 @@ +import 'package:common_utils/common_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:wow_english/common/extension/string_extension.dart'; +import 'package:wow_english/common/widgets/textfiled_customer_widget.dart'; import 'package:wow_english/login/blocs/login_bloc.dart'; import 'package:wow_english/route/route.dart'; @@ -121,31 +124,15 @@ class LoginPage extends StatelessWidget { child: Column( children: [ 15.verticalSpace, - Container( - height: 55.h, - width: double.infinity, - alignment: Alignment.center, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - 'Input_layer_up'.assetPng - ), - fit: BoxFit.fitWidth - ), - ), - child: TextField( - controller: bloc.phoneNumController, - textAlign: TextAlign.center, - textInputAction: TextInputAction.done, - keyboardType: TextInputType.phone, - decoration: const InputDecoration( - hintText: '请输入手机号', - border: InputBorder.none, - ), - onChanged: (String value) { - bloc.add(PhoneNumChangeEvent()); - }, - ) + TextFiledCustomerWidget( + height: 55.h, + hitText: '请输入手机号', + textInputType: TextInputType.phone, + bgImageName: 'Input_layer_up', + onChangeValue: (String value) { + bloc.add(PhoneNumChangeEvent()); + }, + controller: bloc.phoneNumController, ), 6.5.verticalSpace, const Text('未注册用户登录默认注册'), @@ -154,31 +141,16 @@ class LoginPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( - child: Container( - height: 50.h, - width: double.infinity, - alignment: Alignment.center, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - 'Input_layer_down'.assetPng, - ), - ) - ), - child: TextField( - controller: bloc.checkNumController, - textAlign: TextAlign.center, - textInputAction: TextInputAction.done, - keyboardType: TextInputType.number, - decoration: const InputDecoration( - hintText: '请输入验证码', - border: InputBorder.none, - ), - onChanged: (String value) { - bloc.add(CheckFieldChangeEvent()); - }, - ) - ), + child: TextFiledCustomerWidget( + height: 50.h, + hitText: '请输入验证码', + textInputType: TextInputType.number, + bgImageName: 'Input_layer_down', + onChangeValue: (String value) { + bloc.add(CheckFieldChangeEvent()); + }, + controller: bloc.checkNumController, + ) ), GestureDetector( onTap: () { @@ -226,29 +198,17 @@ class LoginPage extends StatelessWidget { ), 10.5.horizontalSpace, Expanded( - child: Container( - height: 55.h, - width: double.infinity, - alignment: Alignment.center, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - 'Input_layer_up'.assetPng - ), - fit: BoxFit.fitWidth, - ) - ), - child: TextField( - controller: bloc.phoneNumController, - textAlign: TextAlign.center, - textInputAction: TextInputAction.done, - decoration: const InputDecoration( - hintText: '请输入手机号', - border: InputBorder.none, - ), - keyboardType: TextInputType.phone, - onChanged: (String value) {bloc.add(PhoneNumChangeEvent());},) - )), + child: TextFiledCustomerWidget( + height: 50.h, + hitText: '请输入手机号', + textInputType: TextInputType.phone, + bgImageName: 'Input_layer_up', + onChangeValue: (String value) { + bloc.add(PhoneNumChangeEvent()); + }, + controller: bloc.phoneNumController, + ) + ), 5.horizontalSpace, SizedBox( width: 100.w, @@ -267,36 +227,23 @@ class LoginPage extends StatelessWidget { ), 10.5.horizontalSpace, Expanded( - child: Container( - width: 397.5, - height: 55, - alignment: Alignment.center, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - 'Input_layer_down'.assetPng - ), - fit: BoxFit.fill, - ) - ), - child: TextField( - controller: bloc.checkNumController, - textAlign: TextAlign.center, - textInputAction: TextInputAction.done, - decoration: const InputDecoration( - hintText: '请输入密码', - border: InputBorder.none, - ), - onChanged: (String value) { - bloc.add(CheckFieldChangeEvent()); - }, - ) - ), + child: TextFiledCustomerWidget( + hitText: '请输入密码', + bgImageName: 'Input_layer_down', + onChangeValue: (String value) { + bloc.add(CheckFieldChangeEvent()); + }, + controller: bloc.checkNumController, + ) ), 5.horizontalSpace, GestureDetector( onTap: () { - Navigator.of(context).pushNamed(AppRouteName.home); + if(!RegexUtil.isMobileExact(bloc.phoneNumController.text)) { + Fluttertoast.showToast(msg: '手机号不正确!'); + return; + } + Navigator.of(context).pushNamed(AppRouteName.fogPwd,arguments: {'phoneNumber':bloc.phoneNumController.text}); }, child: Container( width: 100.w, diff --git a/lib/route/route.dart b/lib/route/route.dart index baf9d24..b4548c3 100644 --- a/lib/route/route.dart +++ b/lib/route/route.dart @@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:wow_english/app/splash_page.dart'; import 'package:wow_english/home/home_page.dart'; +import 'package:wow_english/login/forget_password_page.dart'; import 'package:wow_english/login/login_page.dart'; import 'package:wow_english/tab/tab_page.dart'; @@ -10,6 +11,7 @@ class AppRouteName { static const String splash = 'splash'; static const String login = 'login'; static const String home = 'home'; + static const String fogPwd = 'fogPwd'; static const String tab = '/'; } @@ -30,6 +32,9 @@ class AppRouter { return CupertinoPageRoute(builder: (_) => const LoginPage()); case AppRouteName.home: return CupertinoPageRoute(builder: (_) => const HomePage()); + case AppRouteName.fogPwd: + final phoneNum = (settings.arguments as Map)['phoneNumber'] as String; + return CupertinoPageRoute(builder: (_) => ForgetPassWordPage(phoneNum: phoneNum)); case AppRouteName.tab: return PageRouteBuilder( opaque: false, -- libgit2 0.22.2