Flutter 保持组件不被回收
场景:
列表页游发送验证码计时器,可同时发送计时
遇到问题:
给该界面的State 和 AutomaticKeepAliveClientMixin 关联一起:
再重写 wantKeepAlive 方法:
完整代码:
包含按钮状态样式
// ignore: must_be_immutable
class TimerCountDownWidget extends StatefulWidget {
Function onTimerFinish;
EmployeeManagerEntity entity;
TimerCountDownWidget({this.onTimerFinish, this.entity}) : super();
@override
State<StatefulWidget> createState() => TimerCountDownWidgetState();
}
class TimerCountDownWidgetState extends State<TimerCountDownWidget>
with AutomaticKeepAliveClientMixin {
Timer _timer;
void changeButtonState() {
if (widget.entity.countdownTime == 0) {
setState(() {
widget.entity.countdownTime = 60;
});
//开始倒计时
startCountdownTimer();
}
}
@override
void initState() {
super.initState();
if(widget.entity.countdownTime>0){
startCountdownTimer();
}
}
@override
Widget build(BuildContext context) {
return OutlineButton(
onPressed: () {
if (widget.entity.countdownTime <= 0) {
showDialog(context);
}
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(ScreenUtil().setWidth(36)),
),
borderSide: BorderSide(color: ColorConstant.borderGrayColor, width: 1),
splashColor: Colors.transparent,
highlightedBorderColor: ColorConstant.borderGrayColor,
child: Text(
widget.entity.countdownTime > 0
? '${widget.entity.countdownTime}后重新获取'
: '下发验证码',
style: TextStyle(
fontSize: ScreenUtil().setSp(24),
color: widget.entity.countdownTime > 0
? ColorConstant.thirdTextColor
: ColorConstant.firstTextColor,
)),
);
}
showDialog(BuildContext buildContext) {
BeaconAlertDialog.showCustomDialog(buildContext,
title: widget.entity?.phoneNumber ?? '',
content: Container(
child: Text('xxxxxxx,有效期为30分钟',
textAlign: TextAlign.center,
style: TextStyle(
color: ColorConstant.secondTextColor,
fontSize: ScreenUtil().setSp(24)))),
rightText: '确认',
leftText: '取消',
tip: '验证码接收手机号',
onConfirm: sendSmsResult);
}
Future<void> sendSmsResult() async {
ResultData resultData =
await PaymentAccountApi.fetchSendSmsCode(widget.entity.userId);
if (!resultData.success || resultData.data == null) {
//Toast(resultData.msg ?? '发送失败');
return;
}
try {
changeButtonState();
//Toast('验证码已发送');
} catch (e) {}
}
void startCountdownTimer() {
const oneSec = const Duration(seconds: 1);
var callback = (timer) => {
setState(() {
if (widget.entity.countdownTime < 1) {
widget.onTimerFinish();
_timer.cancel();
} else {
widget.entity.countdownTime = widget.entity.countdownTime - 1;
}
})
};
_timer = Timer.periodic(oneSec, callback);
}
@override
void dispose() {
super.dispose();
if (_timer != null) {
_timer.cancel();
}
}
@override
// TODO: 滑动刷新时计时器不被回收
bool get wantKeepAlive => true;
}