flutter中监控widget传入的值变化从而改变view层

301 阅读1分钟

今天在写一个组件的时候遇到了一点麻烦,这是一个倒计时的组件,在传入的倒计时结束时间发生改变之后要及时更新倒计时,这个时候我需要用到didUpdateWidget这个生命周期。

具体的用法如下:

class CountDown extends StatefulWidget {
  final DateTime endTime;

  const CountDown({
    Key? key,
    required this.endTime,
  }) : super(key: key);

  @override
  _CountDownState createState() => _CountDownState();
}

class _CountDownState extends State<CountDown> {
  late int periodSeconds;
  late Timer _timer;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    initTimer();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    if (widget.endTime.isAfter(DateTime.now())) {
      _timer.cancel();
    }
  }
  
  // 注意这里的使用,随着widget传入值改变而改变:
  @override
  void didUpdateWidget(CountDown oldWidget) {
    // TODO: implement didUpdateWidget
    _timer.cancel();
    initTimer();
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(8),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.all(Radius.circular(90)),
        color: widget.bgColor),
      child: Row(
        children: [
          Text(
            '$periodSeconds',
            style: AppTextStyle.small(color: widget.textColor))
        ],
      ),
    );
  }

  // 重置定时器
  void initTimer () {
    if (widget.endTime.isAfter(DateTime.now())) {
      periodSeconds = DateTimeRange(start: DateTime.now(), end: widget.endTime)
        .duration
        .inSeconds;
      _timer = Timer.periodic(Duration(seconds: 1), (timer) {
        if (mounted) {
          setState(() {
            if (periodSeconds > 0) periodSeconds--;
          });
        }
      });
    } else {
      setState(() {
        _timer.cancel();
      });
    }
  }
 }