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 13 static const int _duration = 60;
14 14 /// 定时器数据流
15 15 final TimerTicker _ticker;
  16 + /// 是否正在计时
  17 + bool _isCountTimer = false;
  18 +
  19 + bool get isCountTimer => _isCountTimer;
16 20 // 流订阅
17 21 StreamSubscription<int>? _tickerSubscription;
18 22 TimerBloc({required TimerTicker ticker})
... ... @@ -33,6 +37,7 @@ class TimerBloc extends Bloc&lt;TimerEvent, TimerState&gt; {
33 37  
34 38 /// 开始计时
35 39 void _onStarted(StartEvent event,Emitter<TimerState> emitter) async {
  40 + _isCountTimer = true;
36 41 emitter(RunningState(event.duration));
37 42 _tickerSubscription?.cancel();
38 43 _tickerSubscription = _ticker
... ... @@ -42,7 +47,12 @@ class TimerBloc extends Bloc&lt;TimerEvent, TimerState&gt; {
42 47  
43 48 /// 计时中,判断是否剩余时间
44 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 58 ///暂停,判断当时是否state为PausedState类型,之后暂停订阅,发送暂停state
... ... @@ -64,6 +74,7 @@ class TimerBloc extends Bloc&lt;TimerEvent, TimerState&gt; {
64 74 /// 重置,初始化
65 75 void _onReset(ResetEvent event ,Emitter<TimerState> emit) async{
66 76 _tickerSubscription?.cancel();
  77 + _isCountTimer = false;
67 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 4 import 'package:wow_english/common/extension/string_extension.dart';
5 5 import 'package:wow_english/common/widgets/textfield_customer_widget.dart';
6 6 import 'package:wow_english/login/forgetpwd/bloc/forget_pwd_home_bloc.dart';
  7 +import 'package:wow_english/login/loginpage/time_widget.dart';
7 8 import 'package:wow_english/route/route.dart';
8 9  
9 10 class ForgetPasswordHomePage extends StatelessWidget {
... ... @@ -113,31 +114,7 @@ class _ForgetPasswordHomePageView extends StatelessWidget {
113 114 )
114 115 ),
115 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 1 import 'package:flutter/cupertino.dart';
  2 +import 'package:flutter/material.dart';
2 3 import 'package:flutter_bloc/flutter_bloc.dart';
3 4 import 'package:wow_english/common/blocs/timerbloc/timer_bloc.dart';
4 5 import 'package:wow_english/common/extension/string_extension.dart';
... ... @@ -19,61 +20,50 @@ class TimerWidget extends StatelessWidget {
19 20 }
20 21  
21 22 class TimerWidgetView extends StatelessWidget {
22   -
23 23 final bool canSendSms;
24 24  
25 25 const TimerWidgetView({super.key, required this.canSendSms});
26 26  
27   -
28 27 @override
29 28 Widget build(BuildContext context) {
30   - bool sendSmsIng = false;
31 29 return BlocListener<TimerBloc,TimerState>(
32 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 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 41 buildWhen: (prev, state) => prev.runtimeType != state.runtimeType,
48 42 builder: (context,state) {
49 43 final bloc = BlocProvider.of<TimerBloc>(context);
50   - final duration = bloc.state.duration;
51   - final secondsStr = (duration % 60).floor().toString().padLeft(2, '0');
52 44 return GestureDetector(
53 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 52 child: Container(
59 53 decoration: BoxDecoration(
60 54 image: DecorationImage(
61 55 image: AssetImage(
62   - canSendSms?'securitycode'.assetPng:'securitycode_dis'.assetPng
  56 + canSendSms && !bloc.isCountTimer ? 'securitycode'.assetPng:'securitycode_dis'.assetPng
63 57 ),
64 58 fit: BoxFit.fill
65 59 ),
66 60 ),
67 61 padding: const EdgeInsets.symmetric(horizontal:12.0,vertical: 15.0),
68   - child: Row(
  62 + child: Row(
69 63 children: [
70   - if (state is TimerInitial)...[
71   - const Text('获取验证码')
72   - ],
73 64 if (state is RunningState)...[
74   - Text('${secondsStr}s倒计时')
75   - ],
76   - if (state is FinishedState) ...[
  65 + const TimerText()
  66 + ] else ...[
77 67 const Text('获取验证码')
78 68 ]
79 69 ],
... ... @@ -82,4 +72,17 @@ class TimerWidgetView extends StatelessWidget {
82 72 );
83 73 },
84 74 );
85   -}
86 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 +}
... ...