原创声明:本文为作者原创,未经允许不得转载,经授权转载需注明作者和出处
///倒计时按钮
class CountDownButton extends StatefulWidget {
Function countDownPressed;
bool countDownStatus;
CountDownButton(
{Key key, this.countDownPressed, this.countDownStatus = false})
: super(key: key);
@override
State<StatefulWidget> createState() {
return _CountDownButton();
}
}
class _CountDownButton extends State<CountDownButton> {
int countDowmTime = 60;
String countDownText = '发送验证码';
@override
Widget build(BuildContext context) {
if (widget.countDownStatus && countDownTimer == null) {
countDownTimer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() {
if (countDowmTime - timer.tick > 0) {
countDownText = '${countDowmTime - timer.tick}秒';
} else {
countDownText = '发送验证码';
widget.countDownStatus = false;
countDownTimer.cancel();
countDownTimer = null;
}
});
});
}
return OutlineButton(
onPressed: widget.countDownStatus ? null : widget.countDownPressed,
child: Text(countDownText),
);
}
Timer countDownTimer;
@override
void dispose() {
countDownTimer?.cancel();
countDownTimer = null;
super.dispose();
}
}
Flutter中的控件主要分为有状态的和无状态的,在这里,主要使用的是有状态的控件进行实现。
CountDownButton类中的构造函数中自定义了两个参数countDownPressed(按钮点击后响应的方法)以及countDownStatus(当前按钮的状态:可发送和倒计时中)。
countDownStatus为true的时候,在build方法中则开启一个周期性的定时器,每秒触发一次,修改按钮中的文本
class RegisterPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _RegisterPage();
}
}
class _RegisterPage extends State<RegisterPage> {
BuildContext _context;
bool sendCodeStatus = false;
TextEditingController accountController = TextEditingController();
TextEditingController codeController = TextEditingController();
TextEditingController passwordController = TextEditingController();
TextEditingController passwordAgainController = TextEditingController();
@override
Widget build(BuildContext context) {
_context = context;
return Scaffold(
appBar: AppBar(
title: Text("Register"),
centerTitle: true,
),
body: Container(
padding: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text("账号"),
SizedBox(
width: 10.0,
),
Expanded(
child: TextField(
obscureText: false,
controller: accountController,
decoration: InputDecoration(
hintText: '请输入账号',
),
),
)
],
),
Row(
children: <Widget>[
Text("验证码"),
SizedBox(
width: 10.0,
),
Expanded(
child: TextField(
obscureText: false,
controller: codeController,
decoration: InputDecoration(
hintText: '请输入验证码',
),
),
),
CountDownButton(
countDownStatus: sendCodeStatus,
countDownPressed: sendCodeClick,
),
],
),
Row(
children: <Widget>[
Text('密码'),
SizedBox(
width: 10.0,
),
Expanded(
child: TextField(
obscureText: true,
controller: passwordController,
decoration: InputDecoration(
hintText: '请输入密码',
),
),
)
],
),
Row(
children: <Widget>[
Text('确认密码'),
SizedBox(
width: 10.0,
),
Expanded(
child: TextField(
obscureText: true,
controller: passwordAgainController,
decoration: InputDecoration(
hintText: '请输入密码',
),
),
)
],
),
Row(
children: <Widget>[
Expanded(
child: RaisedButton(
onPressed: registerClick,
child: Text('确认'),
),
)
],
)
],
),
),
);
}
void sendCodeClick() {
Toast.show(_context, msg: '发送验证码成功');
setState(() {
sendCodeStatus = true;
});
}