在Flutter中实现“验证码倒计时”的功能
Posted 郭霖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Flutter中实现“验证码倒计时”的功能相关的知识,希望对你有一定的参考价值。
https://juejin.im/post/5de484135188255de419c728
const timeout = const Duration(seconds: 3);
const ms = const Duration(milliseconds: 1);
startTimeout([int milliseconds]) {
var duration = milliseconds == null ? timeout : ms * milliseconds;
return new Timer(duration, handleTimeout);
}
...
void handleTimeout() { // callback function
...
}
Timer.periodic(
Duration duration,
void callback(
Timer timer
)
)
Timer _countDownTimer;
int _currentTime = 60;
bool get _isTimeCountingDown => _currentTime != 60;
void _startTimeCountDown() {
if (_countDownTimer != null) {
timer.cancel();
timer = null;
}
_countDownTimer = Timer.periodic(Duration(seconds: 1), (timer) {
if (timer.tick == 60) {
_currentTime = 60;
_countDownTimer.cancel();
_countDownTimer = null;
} else {
_currentTime--;
}
setState(() {
});
});
}
@override
void dispose() {
_countDownTimer?.cancel();
_countDownTimer = null;
super.dispose();
}
import 'dart:async';
import 'package:flutter/material.dart';
/// 计时器组件
class CountDownTimeModel extends ChangeNotifier {
final int timeMax;
final int interval;
int _time;
Timer _timer;
int get currentTime => _time;
bool get isFinish => _time == timeMax;
CountDownTimeModel(this.timeMax, this.interval) {
_time = timeMax;
}
void startCountDown() {
if (_timer != null) {
_timer.cancel();
_timer = null;
}
_timer = Timer.periodic(Duration(seconds: interval), (timer) {
if (timer.tick == timeMax) {
_time = timeMax;
timer.cancel();
timer = null;
} else {
_time--;
}
notifyListeners();
});
}
void cancel() {
if (_timer != null) {
_timer.cancel();
_timer = null;
}
}
@override
void dispose() {
_timer.cancel();
_timer = null;
super.dispose();
}
}
class _LoginPageState extends State<TestPage> {
@override
Widget build(BuildContext context) {
final logo = Hero(
tag: 'hero',
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: 48.0,
child: Image.asset(ImageAssets.holder_logo),
),
);
final email = TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
initialValue: 'alucard@gmail.com',
decoration: InputDecoration(
hintText: 'Email',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
),
);
final password = TextFormField(
autofocus: false,
initialValue: 'some password',
obscureText: true,
decoration: InputDecoration(
hintText: 'Password',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
),
);
final loginButton = Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
onPressed: () {
},
padding: EdgeInsets.all(12),
color: Colors.lightBlueAccent,
child: Text('Log In', style: TextStyle(color: Colors.white)),
),
);
final forgotLabel = FlatButton(
child: Text(
'Forgot password?',
style: TextStyle(color: Colors.black54),
),
onPressed: () {},
);
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.only(left: 24.0, right: 24.0),
children: <Widget>[
logo,
SizedBox(height: 48.0),
email,
SizedBox(height: 8.0),
ScreenUtils.verticalSpace(2),
Stack(
children: <Widget>[
password,
PartialConsumeComponent<CountDownTimeModel>(
model: CountDownTimeModel(60, 1),
builder: (context, model, _) => Positioned(
right: 10,
bottom: 1,
top: 1,
child: FlatButton(
disabledColor: Colors.grey.withOpacity(0.36),
color: Colors.white70.withOpacity(0.7),
onPressed: !model.isFinish ? null : () {
model.startCountDown();
},
child: Text(
model.isFinish ? '获取验证码' : model.currentTime.toString()+'秒后重新获取',
style: TextStyle(color: model.isFinish ? Colors.lightBlueAccent : Colors.white),
)
),
),
),
],
),
SizedBox(height: 24.0),
loginButton,
forgotLabel
],
),
),
);
}
}
class PartialConsumeComponent<T extends ChangeNotifier> extends StatefulWidget {
final T model;
final Widget child;
final ValueWidgetBuilder<T> builder;
PartialConsumeComponent({
Key key,
@required this.model,
@required this.builder,
this.child
}) : super(key: key);
@override
_PartialConsumeComponentState<T> createState() => _PartialConsumeComponentState<T>();
}
class _PartialConsumeComponentState<T extends ChangeNotifier> extends State<PartialConsumeComponent<T>> {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<T>.value(
value: widget.model,
child: Consumer<T>(
builder: widget.builder,
child: widget.child,
),
);
}
}
以上是关于在Flutter中实现“验证码倒计时”的功能的主要内容,如果未能解决你的问题,请参考以下文章