在Flutter中何时使用setState?

时间:2018-07-11 10:25:00

标签: android dart flutter

作为新手,在SELECt a.*, b.x FROM @tbl a OUTER APPLY ( SELECT TOP 1 1 FROM (VALUES(a.Col1),(a.Col2),(a.Col3)) c(a) WHERE c.a = 1 ) b(x) 应用程序中使用setState时,我感到非常困惑。在下面的代码中,Flutter中使用了布尔searching和var resBody。我的问题是,为什么setState中只有setStatesearching?为什么其他人没有名气?

resBody

6 个答案:

答案 0 :(得分:6)

根据docs

  

调用setState会通知框架此对象的内部状态已更改,该方式可能会影响此子树中的用户界面,这会导致框架为该State对象安排构建。

因此,如果窗口小部件的状态更改了您必须调用setState来触发视图重建,并立即查看新状态所隐含的更改。

无论如何以下片段都是等效的。

第一种情况(直接来自flutter create <myproject>):

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {

    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

第二种情况:

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    _counter++;
    setState(() {});
  }

我不知道的原因是,如果第一种情况是使用setState的常规方式,那么我会说是因为代码的可读性。

答案 1 :(得分:4)

如果您查看 setState 的实现:

  void setState(VoidCallback fn) {
    assert(fn != null);
    assert(...);
    final dynamic result = fn() as dynamic;
    assert(...);
    _element.markNeedsBuild();
  }

你看到它唯一做的事情是:断言一些事情来帮助你调试它的错误使用,执行回调,并标记元素以使其重建。

因此,从技术上讲,只要调用了 setState,在 setState 回调内部或外部更改某些变量都没有关系。

然而,为了可读性,有很大的不同。重建小部件会影响应用程序的性能,因此您希望尽可能少地这样做。对需要小部件在 setState 回调中重建的变量进行所有(且仅是那些)更改,可以让人们(包括您未来的自己)清楚为什么需要重建。

答案 2 :(得分:2)

更改有状态窗口小部件的状态时,请使用setState()来重建窗口小部件及其后代。
您无需在构造函数中或小部件的setState()中调用initState(),因为无论如何build()都将随后运行。

也不要在setState()内部的同步代码中调用build()。您无需从build()内部重新运行build()

答案 3 :(得分:1)

根据documentations

通常建议仅将setState方法用于 包装实际的状态更改,而不是可能的任何计算 与变更相关联。例如,此处是 build函数递增,然后将更改写入 磁盘,但是只有增量存储在setState中:

Future<void> _incrementCounter() async {
  setState(() {
    _counter++;
  });
  Directory directory = await getApplicationDocumentsDirectory();
  final String dirName = directory.path;
  await File('$dir/counter.txt').writeAsString('$_counter');
}

答案 4 :(得分:1)

每当您想要更新小部件树(通常使用一些新数据)时,您都可以调用 setState。它只能在 State 类中使用。这是简单的实现:

class _MyPageState extends State<MyPage> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(
          onPressed: () => setState(() => _count++),
          child: Text('Count = $_count'),
        ),
      ),
    );
  }
}

答案 5 :(得分:0)

当您需要更改任何小部件时,例如应用程序内,应在完成某些任务点添加后将某些任务添加到钱包中,但问题是我们需要刷新应用程序以查看钱包上的点来解决此问题我们在按钮按下时使用Setstate

例如:

RaisedButton(

    onpressed(){

    setstate(){

     points+10;
    }
    }
    )

每按一次按钮,它将按Setstate检查是否有任何新数据或点,并且它将重建UI,而无需刷新整个应用程序