📜  在构建期间调用 setState() 或 markNeedsBuild(). (1)

📅  最后修改于: 2023-12-03 15:37:43.792000             🧑  作者: Mango

在构建期间调用setState()或markNeedsBuild()

在Flutter中,我们经常需要更新控件的状态或重新渲染控件。在构建期间调用setState()markNeedsBuild()是实现这个目标的两种主要方法。这些方法都是State类中的方法,因为State是负责管理控件状态的类。

setState()

setState()方法可以让我们更新控件的状态并触发重新渲染。调用setState()时,Flutter会将标记设置为“dirty”,表示需要重新构建此控件和其所有后代控件。当我们在build()方法中使用了setState()时,Flutter会首先重建控件树,并在此期间更新控件的状态。然后,Flutter会使用新的状态重新构建控件树。

以下是一个简单的示例,展示如何使用setState()来更改文本控件的文本:

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  String _text = 'Hello';

  void _changeText() {
    setState(() {
      _text = 'Goodbye';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('MyWidget'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(_text),
            RaisedButton(
              onPressed: _changeText,
              child: Text('Change Text'),
            ),
          ],
        ),
      ),
    );
  }
}

在上面的代码中,我们在一个StatefulWidget的实现中定义了一个私有变量_text,并在构建方法中使用了它。我们还定义了一个名为_changeText()的方法,以更新此变量并调用setState()方法。每次单击RaisedButton时,都会触发此方法并更改文本控件的文本。

markNeedsBuild()

另一方面,我们也可以使用markNeedsBuild()方法来标记控件树中的控件需要重新渲染。这是一个比setState()更低级别的方法,我们通常不需要在Flutter开发中使用它,但有时可能会有用。

以下是一个简单的示例,展示如何在构建方法外部使用markNeedsBuild()

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  String _text = 'Hello';
  bool _disabled = true;

  void _toggleDisabled() {
    setState(() {
      _disabled = !_disabled;
    });
  }

  void _changeText() {
    _text = 'Goodbye';
    (context as Element).markNeedsBuild(); // 使用 markNeedsBuild()
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('MyWidget'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(_text),
            RaisedButton(
              onPressed: _disabled ? null : _changeText,
              child: Text('Change Text'),
            ),
            SizedBox(height: 32),
            RaisedButton(
              onPressed: _toggleDisabled,
              child: Text(_disabled ? 'Enabled' : 'Disabled'),
            ),
          ],
        ),
      ),
    );
  }
}

在上面的代码中,我们为RaisedButton设置了onPressed回调。当_disabledfalse时,此按钮将激活并调用_changeText()方法。然而,我们还将_text设置为'Goodbye',并使用markNeedsBuild()方法标记此控件需要重新渲染。

当我们单击toggleDisabled按钮时,控件将更改其状态并重新渲染。当我们再次单击changeText按钮时,Flutter会重新渲染控件树,并在此期间发现此控件已标记为需要重新渲染。然后,Flutter会使用新的状态重新构建控件树。

总结

在构建期间调用setState()markNeedsBuild()是Flutter中管理控件的状态和渲染的重要方法。setState()方法允许我们更新控件的状态并触发重新渲染,而markNeedsBuild()方法让我们标记控件需要重新渲染。虽然setState()用得更频繁,markNeedsBuild()也具有一些应用场景。无论您选择哪个方法,都要确保根据需要仔细思考并选择正确的选项。