【问题标题】:How to periodically set state?如何定期设置状态?
【发布时间】:2019-05-15 00:42:33
【问题描述】:

我正在尝试为特殊日子构建一个倒计时应用程序,例如 11 d 2 h 30 m 23s 到新年,但我无法每秒重新加载我的状态,所以它只显示我加载页面的第二秒不知道如何动态重新加载页面。

 import 'package:flutter/material.dart';

    class RopSayac extends StatefulWidget {
      _RopSayacState createState() => _RopSayacState();
    }

    class _RopSayacState extends State<RopSayac> {

      var now = DateTime.now().second.toString();
      String asd(){
        setState(() {
        now = DateTime.now().second.toString();

        });
        return now;
      }

      @override
      Widget build(BuildContext context) {


        return Container(
          child: new Text(asd()),
        );
      }
    }

这是我得到的,它没有重新加载时间。我对扑腾很陌生。

【问题讨论】:

标签: flutter dart setstate


【解决方案1】:

正如 pskink 和 Günter 所说,使用 Timer。您甚至可以使用适合您的场景的 periodic 构造函数。

请注意,您不需要 asd() 函数。当您调用setState() 时,将自动调用build 方法并传递新的now 属性值。

如果您愿意,可以使用initState 设置初始值,如本例所示,设置Timer

import 'dart:async';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(title: 'Timer Periodic Demo', home: RopSayac());
  }
}

class RopSayac extends StatefulWidget {
  _RopSayacState createState() => _RopSayacState();
}

class _RopSayacState extends State<RopSayac> {
  String _now;
  Timer _everySecond;

  @override
  void initState() {
    super.initState();

    // sets first value
    _now = DateTime.now().second.toString();

    // defines a timer 
    _everySecond = Timer.periodic(Duration(seconds: 1), (Timer t) {
      setState(() {
        _now = DateTime.now().second.toString();
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: new Text(_now),
      ),
    );
  }
}

【讨论】:

  • 非常感谢。现在我更好地理解了初始化状态逻辑。在 java 和 .net 之后,Flutter 感觉很奇怪
  • 你能解释一下 dipose() 的作用吗
  • dispose 在不再需要小部件并且即将被销毁时调用。假设您在initState 中打开了一个连接,并且出于某种原因使其保持打开状态,您将实现dispose 方法,因为这是关闭该连接的好时机。这是一个不好的例子,但给了你想法。 Check also this.
【解决方案2】:

这种递归方法应该足以满足您的需求。 seconds 设置为 1 将保持每秒触发 setState,从而刷新您的小部件树。

void _timer() {
    Future.delayed(Duration(seconds: 1)).then((_) {
      setState(() {
        print("1 second closer to NYE!");
        // Anything else you want
      });
      _timer();
    });
  }

【讨论】:

  • 程序中是否需要至少调用一次定时器函数?
  • 是的。你应该至少调用一次。
  • 当您的小部件离开屏幕时,这将崩溃。检查日志。
【解决方案3】:

有一个名为timer_builder 的优秀库。我想它会帮助你。

来自 pub 页面的示例:

import 'package:timer_builder/timer_builder.dart';

class ClockWidget extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return TimerBuilder.periodic(Duration(seconds: 1), //updates every second
      builder: (context) {
        return Text("${DateTime.now()}");
      }
    );
  }

}

【讨论】:

  • 当整个应用程序是基于时间的时很有用
【解决方案4】:

这就是我所做的。就我而言,我正在 _liveUpdate() 中轮询网络服务

void startUpdates(AppState appState) async {
await new Future.delayed(const Duration(milliseconds: 100));
while (true) {
  _liveUpdate();
  appState.setState(() {});

  await new Future.delayed(const Duration(seconds : 15));
}

【讨论】:

  • 这是 RealBadAdvice(tm)
猜你喜欢
  • 2022-11-08
  • 1970-01-01
  • 2019-08-13
  • 2021-10-17
  • 2021-09-23
  • 2021-06-30
  • 2012-12-30
  • 1970-01-01
  • 2019-04-02
相关资源
最近更新 更多