📜  flutter pre intistate statefulwidget - Dart (1)

📅  最后修改于: 2023-12-03 14:41:15.357000             🧑  作者: Mango

Flutter Pre Instistate StatefulWidget - Dart

Flutter 是谷歌推出的一款跨平台移动应用开发框架。Flutter 可以让你在一套代码基础下同时开发 iOS 和 Android 应用程序,同时降低项目成本和维护难度。其中,StatefulWidget 是 Flutter 中的一个重要组件,它使得 Flutter 应用程序可以拥有动态的 UI,能够根据事件、用户交互等修改内部状态,实现复杂的应用逻辑。本文将介绍 StatefulWidget 的基本用法和常用方法。

StatelessWidget 与 StatefulWidget 的区别

在 Flutter 中,有 Stateful 和 Stateless 两种 Widget。StatelessWidget 不可变,一旦被创建便无法修改属性和状态,而 StatefulWidget 可以在属性、事件、动画等各种情况下修改内部状态。换言之,StatefulWidget 允许我们根据 UI 的变化而变化,StatelessWidget 一旦创建就不会再变了。

因此,如果我们需要的是一个简单的静态组件,StatelessWidget 是最佳的选择。它的构建会更快,也更容易维护。但是如果你需要对组件进行动态更新,例如增加计数器的值,使用 StatefulWidget 会更加合适。

如何创建 StatefulWidget?

下面是 StatefulWidget 的基本代码结构:

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({ Key? key }) : super(key: key);

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

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text('Hello, World!'),
    );
  }
}

代码中,我们定义了一个 MyStatefulWidget StatefulWidget 组件,并在其中添加了一个内部State类 _MyStatefulWidgetState。当父组件 MyStatefulWidget 第一次创建时,_MyStatefulWidgetState 也会被创建。我们可以通过实现 _MyStatefulWidgetState 类,添加需要响应状态的方法,来创建一个可以动态改变的组件。

StatefulWidget 的生命周期

当 StatefulWidget 被创建时,会按照如下顺序调用一些方法:

  1. createState():这是 StatefulWidget 创建时唯一被调用的方法,用于创建 StatefulWidget 的状态(State)。

  2. initState():此方法在 State 对象被创建后调用,并在 State 对象与 BuildContext 对象相关联时调用。

  3. 执行 build() 方法,返回渲染 UI(Widget)

将 StatefulWidget 从屏幕上删除时,会按照如下顺序调用一些方法:

  1. deactivate():在组件被移除前调用,用于清除资源(例如:停止动画)。

  2. destroyState():在 State 被永久删除之前调用,释放资源。

除此之外,Flutter 还提供了一个 dispose() 方法,用于处理那些不能被监听者监听到的资源清除,例如:正在进行中的动画。此方法的调用时机是在 destroyState() 调用后,即 State 被彻底销毁时。

获取当前 State

StatefulWidget 的状态保存在其对应的 State 里面。那么我们如何获取这个 State 对象呢?

我们可以通过 context 获取到构建当前 StatefulWidget 的 _MyStatefulWidgetState,代码如下:

_MyStatefulWidgetState state = context.findAncestorStateOfType<_MyStatefulWidgetState>();

值得注意的是,如果我们在一个异步任务中访问 state,其状态可能已经被修改,此时访问已经失效,因此我们应该尽量少量地关注 state 的细节。

setState()

在上文中,我们提到了 StatefulWidget 之所以能够动态更新 UI,是因为它的内部状态可以被修改。那么如何在组件内部改变状态呢?这就引出了 StatefulWidget 的核心方法 setState()

setState() 方法接受一个参数,这个参数是一个无返回值的回调函数。当这个回调函数执行完毕之后,Flutter 就会自动重新调用 build() 方法。

下面是一个例子:

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _counter = 0;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

在这个例子中,我们定义了一个 _counter 变量来保存按钮被按下的次数,并在 Build 方法中使用了 _counter 的值。当用户按下 FloatingAction button 按钮后,_incrementCounter() 方法被调用,设置了 _counter 的值,setState() 方法被调用,重新调用 Build 方法重新渲染 UI。

注意:我们不能直接使用 _counter 按钮值的更改会没有反应,提示我们需要调用 setState()

更多关于 Flutter 的使用介绍,可以参考官方文档:https://flutter.dev/docs.