Flutter圈子程序员Android开发经验谈

新贵 Flutter StatefulWidget(8)

2019-06-26  本文已影响30人  zidea
flutter

会介绍 StatefulWidget 与 StatelessWidget 的不同以及 StatefulWidget 是如何工作的。如果已经查看我们之前的分享,想必大家对 StatelessWidget 应该有了一定的了解和认识。不过 StatelessWidget 中的数据是需要从外层传入的,随后固定不变了,当数据改变了 StatelessWidget 也不会随之重新渲染界面进行改变。为了解决这个问题就出现了 StatefulWidget。在 StatefulWidget 中会有 state 对象根据数据改变重新触发 Widget 构建来实现重新渲染界面。

在下面代码中我们需要 _tut 是可以随时间改变的。不过 StatefulWidget 是由 Widget 和 state 对象两部分组成的。Widget 负责做两件事持有不可变的变量例如 startingTut 和一个 state。

有关他们是如何工作我们可以看一看下图,Widget Tree 和 Element Tree


widget

StatefulWidget 也会对应一个 StatefulElement,StatefulWidget 作为 StatefulElement 的蓝图,StatefulElement 是对应屏幕上用户看到组件。

class TutManager extends StatefulWidget {
  final String startingTut;

  TutManager({this.startingTut = 'default tut'});

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _TutManagerState();
  }
}

接下来 StatefulElement 反过来会要求 StatefulWidget 创建一个状态,这时候就会调用 createState() 方法来创建一个状态。



在 state 中维护着变量 _tuts,和一个 StatelessWidget

以为 state 对象持有一个 widget 的引用,该 Widget 具有状态。



现在我们所有内容已经建立好关系,也渲染到界面上,现在我们通过 setState 方法来更改状态

onPressed: () {
              setState(() {
                _tuts.add("Dart");
              });
            },

当我们调用 setState 方法更改 state 中 tuts 的值,这样 _TutManager 就会将 _tuts 标记为脏数据,在以下帧渲染时候会将最新的数据更新到界面上。Tuts Widget 将会被新的 Tuts 所替换。
statefulWidget 还有一个好处就是即使我们 startTut 值发生改变从而产生了新的 StatefulWidget 只要其他不发生改变,最会只改变这个节点然后进行替换并不会重新生成结构。

  @override
  void didUpdateWidget(HomeScreenTopPart oldWidget) {
    // TODO: implement didUpdateWidget
    super.didUpdateWidget(oldWidget);
  }

如果 state 对象需要知道哪一个 Widget 替换就可以用上面的方法。

import 'package:flutter/material.dart';
import './tuts.dart';
class TutManager extends StatefulWidget {
  final String startingTut;

   TutManager({this.startingTut = 'default tut'});

   @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _TutManagerState();
  }
}

class _TutManagerState extends State<TutManager> {
  List<String> _tuts = [];

  @override
  void initState() {
    // TODO: implement initState
    _tuts.add(widget.startingTut);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Column(
      children: [
        Container(
          margin: EdgeInsets.all(10.0),
          child: RaisedButton(
            color: Theme.of(context).primaryColor,
            onPressed: () {
              setState(() {
                _tuts.add("Dart");
              });
            },
            child: Text('Add Tut'),
          ),
        ),
        Tuts(_tuts),
      ],
    );
  }
}

上一篇下一篇

猜你喜欢

热点阅读