Commit 41b60caf9f512f6d8d3f9c02226c82755de4fd9c

Authored by liangchengyou
1 parent e1f36554

feat:倒计时组件功能完善

lib/common/blocs/timerbloc/timer_bloc.dart
@@ -13,6 +13,10 @@ class TimerBloc extends Bloc<TimerEvent, TimerState> { @@ -13,6 +13,10 @@ class TimerBloc extends Bloc<TimerEvent, TimerState> {
13 static const int _duration = 60; 13 static const int _duration = 60;
14 /// 定时器数据流 14 /// 定时器数据流
15 final TimerTicker _ticker; 15 final TimerTicker _ticker;
  16 + /// 是否正在计时
  17 + bool _isCountTimer = false;
  18 +
  19 + bool get isCountTimer => _isCountTimer;
16 // 流订阅 20 // 流订阅
17 StreamSubscription<int>? _tickerSubscription; 21 StreamSubscription<int>? _tickerSubscription;
18 TimerBloc({required TimerTicker ticker}) 22 TimerBloc({required TimerTicker ticker})
@@ -33,6 +37,7 @@ class TimerBloc extends Bloc&lt;TimerEvent, TimerState&gt; { @@ -33,6 +37,7 @@ class TimerBloc extends Bloc&lt;TimerEvent, TimerState&gt; {
33 37
34 /// 开始计时 38 /// 开始计时
35 void _onStarted(StartEvent event,Emitter<TimerState> emitter) async { 39 void _onStarted(StartEvent event,Emitter<TimerState> emitter) async {
  40 + _isCountTimer = true;
36 emitter(RunningState(event.duration)); 41 emitter(RunningState(event.duration));
37 _tickerSubscription?.cancel(); 42 _tickerSubscription?.cancel();
38 _tickerSubscription = _ticker 43 _tickerSubscription = _ticker
@@ -42,7 +47,12 @@ class TimerBloc extends Bloc&lt;TimerEvent, TimerState&gt; { @@ -42,7 +47,12 @@ class TimerBloc extends Bloc&lt;TimerEvent, TimerState&gt; {
42 47
43 /// 计时中,判断是否剩余时间 48 /// 计时中,判断是否剩余时间
44 void _onTicked(TickEvent event,Emitter<TimerState> emitter) async { 49 void _onTicked(TickEvent event,Emitter<TimerState> emitter) async {
45 - emitter(event.duration>0?RunningState(event.duration):const FinishedState()); 50 + if(event.duration > 0) {
  51 + emitter(RunningState(event.duration));
  52 + } else {
  53 + _isCountTimer = false;
  54 + emitter(const FinishedState());
  55 + }
46 } 56 }
47 57
48 ///暂停,判断当时是否state为PausedState类型,之后暂停订阅,发送暂停state 58 ///暂停,判断当时是否state为PausedState类型,之后暂停订阅,发送暂停state
@@ -64,6 +74,7 @@ class TimerBloc extends Bloc&lt;TimerEvent, TimerState&gt; { @@ -64,6 +74,7 @@ class TimerBloc extends Bloc&lt;TimerEvent, TimerState&gt; {
64 /// 重置,初始化 74 /// 重置,初始化
65 void _onReset(ResetEvent event ,Emitter<TimerState> emit) async{ 75 void _onReset(ResetEvent event ,Emitter<TimerState> emit) async{
66 _tickerSubscription?.cancel(); 76 _tickerSubscription?.cancel();
  77 + _isCountTimer = false;
67 emit(const TimerInitial(_duration)); 78 emit(const TimerInitial(_duration));
68 } 79 }
69 } 80 }
lib/login/forgetpwd/forget_password_home_page.dart
@@ -4,6 +4,7 @@ import &#39;package:flutter_screenutil/flutter_screenutil.dart&#39;; @@ -4,6 +4,7 @@ import &#39;package:flutter_screenutil/flutter_screenutil.dart&#39;;
4 import 'package:wow_english/common/extension/string_extension.dart'; 4 import 'package:wow_english/common/extension/string_extension.dart';
5 import 'package:wow_english/common/widgets/textfield_customer_widget.dart'; 5 import 'package:wow_english/common/widgets/textfield_customer_widget.dart';
6 import 'package:wow_english/login/forgetpwd/bloc/forget_pwd_home_bloc.dart'; 6 import 'package:wow_english/login/forgetpwd/bloc/forget_pwd_home_bloc.dart';
  7 +import 'package:wow_english/login/loginpage/time_widget.dart';
7 import 'package:wow_english/route/route.dart'; 8 import 'package:wow_english/route/route.dart';
8 9
9 class ForgetPasswordHomePage extends StatelessWidget { 10 class ForgetPasswordHomePage extends StatelessWidget {
@@ -113,31 +114,7 @@ class _ForgetPasswordHomePageView extends StatelessWidget { @@ -113,31 +114,7 @@ class _ForgetPasswordHomePageView extends StatelessWidget {
113 ) 114 )
114 ), 115 ),
115 16.5.horizontalSpace, 116 16.5.horizontalSpace,
116 - GestureDetector(  
117 - onTap: () {  
118 - if (bloc.canSendSms) {  
119 - bloc.add(SendSmsCodeEvent());  
120 - }  
121 - },  
122 - child: Container(  
123 - decoration: BoxDecoration(  
124 - image: DecorationImage(  
125 - image: AssetImage(  
126 - bloc.canSendSms?'securitycode'.assetPng:'securitycode_dis'.assetPng  
127 - ),  
128 - fit: BoxFit.fill  
129 - ),  
130 - ),  
131 - padding: const EdgeInsets.symmetric(horizontal:12.0,vertical: 15.0),  
132 - child: const Text(  
133 - '获取验证码',  
134 - style: TextStyle(  
135 - fontSize: 16,  
136 - color: Colors.white  
137 - ),  
138 - ),  
139 - ),  
140 - ) 117 + TimerWidget(canSendSms: bloc.canSendSms)
141 ], 118 ],
142 ) 119 )
143 ], 120 ],
lib/login/loginpage/time_widget.dart
1 import 'package:flutter/cupertino.dart'; 1 import 'package:flutter/cupertino.dart';
  2 +import 'package:flutter/material.dart';
2 import 'package:flutter_bloc/flutter_bloc.dart'; 3 import 'package:flutter_bloc/flutter_bloc.dart';
3 import 'package:wow_english/common/blocs/timerbloc/timer_bloc.dart'; 4 import 'package:wow_english/common/blocs/timerbloc/timer_bloc.dart';
4 import 'package:wow_english/common/extension/string_extension.dart'; 5 import 'package:wow_english/common/extension/string_extension.dart';
@@ -19,61 +20,50 @@ class TimerWidget extends StatelessWidget { @@ -19,61 +20,50 @@ class TimerWidget extends StatelessWidget {
19 } 20 }
20 21
21 class TimerWidgetView extends StatelessWidget { 22 class TimerWidgetView extends StatelessWidget {
22 -  
23 final bool canSendSms; 23 final bool canSendSms;
24 24
25 const TimerWidgetView({super.key, required this.canSendSms}); 25 const TimerWidgetView({super.key, required this.canSendSms});
26 26
27 -  
28 @override 27 @override
29 Widget build(BuildContext context) { 28 Widget build(BuildContext context) {
30 - bool sendSmsIng = false;  
31 return BlocListener<TimerBloc,TimerState>( 29 return BlocListener<TimerBloc,TimerState>(
32 listener: (context, s) { 30 listener: (context, s) {
33 - if (s is RunningState) {  
34 - sendSmsIng = true;  
35 - } if (s is FinishedState) {  
36 - sendSmsIng = false; 31 + if (s is FinishedState) {
  32 + ///重置计时器
37 context.read<TimerBloc>().add(ResetEvent()); 33 context.read<TimerBloc>().add(ResetEvent());
38 - } else {  
39 - sendSmsIng = false;  
40 } 34 }
41 }, 35 },
42 - child: _buildCountdownWidget(sendSmsIng:sendSmsIng), 36 + child: _buildCountdownWidget(),
43 ); 37 );
44 } 38 }
45 39
46 - Widget _buildCountdownWidget({required bool sendSmsIng}) => BlocBuilder<TimerBloc,TimerState>( 40 + Widget _buildCountdownWidget() => BlocBuilder<TimerBloc,TimerState>(
47 buildWhen: (prev, state) => prev.runtimeType != state.runtimeType, 41 buildWhen: (prev, state) => prev.runtimeType != state.runtimeType,
48 builder: (context,state) { 42 builder: (context,state) {
49 final bloc = BlocProvider.of<TimerBloc>(context); 43 final bloc = BlocProvider.of<TimerBloc>(context);
50 - final duration = bloc.state.duration;  
51 - final secondsStr = (duration % 60).floor().toString().padLeft(2, '0');  
52 return GestureDetector( 44 return GestureDetector(
53 onTap: () { 45 onTap: () {
54 - if (canSendSms && !sendSmsIng) {  
55 - bloc.add(ResetEvent()); 46 + print(bloc.isCountTimer);
  47 + if (canSendSms && !bloc.isCountTimer ) {
  48 + print(state.duration);
  49 + bloc.add(StartEvent(duration: state.duration));
56 } 50 }
57 }, 51 },
58 child: Container( 52 child: Container(
59 decoration: BoxDecoration( 53 decoration: BoxDecoration(
60 image: DecorationImage( 54 image: DecorationImage(
61 image: AssetImage( 55 image: AssetImage(
62 - canSendSms?'securitycode'.assetPng:'securitycode_dis'.assetPng 56 + canSendSms && !bloc.isCountTimer ? 'securitycode'.assetPng:'securitycode_dis'.assetPng
63 ), 57 ),
64 fit: BoxFit.fill 58 fit: BoxFit.fill
65 ), 59 ),
66 ), 60 ),
67 padding: const EdgeInsets.symmetric(horizontal:12.0,vertical: 15.0), 61 padding: const EdgeInsets.symmetric(horizontal:12.0,vertical: 15.0),
68 - child: Row( 62 + child: Row(
69 children: [ 63 children: [
70 - if (state is TimerInitial)...[  
71 - const Text('获取验证码')  
72 - ],  
73 if (state is RunningState)...[ 64 if (state is RunningState)...[
74 - Text('${secondsStr}s倒计时')  
75 - ],  
76 - if (state is FinishedState) ...[ 65 + const TimerText()
  66 + ] else ...[
77 const Text('获取验证码') 67 const Text('获取验证码')
78 ] 68 ]
79 ], 69 ],
@@ -82,4 +72,17 @@ class TimerWidgetView extends StatelessWidget { @@ -82,4 +72,17 @@ class TimerWidgetView extends StatelessWidget {
82 ); 72 );
83 }, 73 },
84 ); 74 );
85 -}  
86 \ No newline at end of file 75 \ No newline at end of file
  76 +}
  77 +
  78 +class TimerText extends StatelessWidget {
  79 + const TimerText({super.key});
  80 +
  81 + @override
  82 + Widget build(BuildContext context) {
  83 + final duration = context.select((TimerBloc bloc) => bloc.state.duration);
  84 + final secondsStr = duration.toString().padLeft(2, '0');
  85 + return Text(
  86 + '${secondsStr}s后再次获取',
  87 + );
  88 + }
  89 +}