Flutter技术入门与实战
上QQ阅读APP看书,第一时间看更新

2.4 无状态组件和有状态组件

无状态组件(StatelessWidget)是不可变的,这意味着它们的属性不能改变,所有的值都是最终的。

有状态组件(StatefulWidget)持有的状态可能在Widget生命周期中发生变化。实现一个StatefulWidget至少需要两个类:

一个StatefulWidget类。

一个State类。StatefulWidget类本身是不变的,但是State类在Widget生命周期中始终存在。

Flutter的官方给出一个有状态组件的示例,点击右下角的+号按钮,应用界面中间的数字会加1,如图2-2所示。

图2-2 Flutter官方示例

这个示例有几个关键的部分,解析如下。

示例代码中MyHomePage必须继承自StatefulWidget类,如下所示:

        class MyHomePage extends StatefulWidget

重写createState方法,如下所示:

        @override
        MyHomePageState createState() => new _MyHomePageState();

状态类必须继承自State类,如下所示:

        class _MyHomePageState extends State<MyHomePage>

定义一个普通变量_counter作为计数器变量,调用setState方法来控制这个变量的值的变化,如下所示:

        int _counter = 0;
        void _incrementCounter() {
          setState(() {
            //计数器变量
            _counter++;
          });
        }

完整的示例代码如下所示:

    import 'package:flutter/material.dart';
    void main() => runApp(new MyApp());
    //MyApp不需要做状态处理,所以此组件继承StatelessWidget即可
    class MyApp extends StatelessWidget {
      // 这个组件是整个应用的主组件
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            //自定义主题
            primarySwatch: Colors.blue,
          ),
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    //主页需要继承自StatefulWidget
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      //标题
      final String title;
      //必须重写createState方法
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    //状态类必须继承State类,注意后面需要指定为<MyHomePage>
    class _MyHomePageState extends State<MyHomePage> {
      int _counter = 0; //计数器
      void _incrementCounter() {
        //调用State类里的setState方法来更改状态值,使得计数器加1
        setState(() {
          //计数器变量,每次点击让其加1
          _counter++;
        });
      }
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text(widget.title),
          ),
              //居中布局
              body: new Center(
                //垂直布局
                child: new Column(
                  //主轴居中对齐
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    new Text(
                      'You have pushed the button this many times:',
                    ),
                    new Text(
                      '$_counter', //绑定计数器的值
                      style: Theme.of(context).textTheme.display1,
                    ),
                  ],
                ),
              ),
              floatingActionButton: new FloatingActionButton(
                onPressed: _incrementCounter, //按下+号按钮调用自增函数
                tooltip: 'Increment',
                child: new Icon(Icons.add),
              ),
            );
          }
        }