Flutter体验 Day 6-Widget State

Widget状态管理

Widget 类别的原始码上有标注 @immutable,这个标注的意思是不可变的;简单的来说这个类别里的类别属性必需宣告成 final,经赋值後就不可改变。

@immutable
abstract class Widget extends DiagnosticableTree {
  /// Initializes [key] for subclasses.
  const Widget({ this.key });
  ...

State

在先前的范例中,我们有使用过 StatelessWidget,这类型的控件通常只需要定义布局内容,而 StatefulWidget 内部使用 State 来处理状态变化的管理,可以在收到异动後透过 setState 通知 Flutter 重新渲染画面。

StatefulWidget

Widget 在设计上是 immutable 的,也就是说控件在经过创建後就不能够修改,所以 Flutter 设计上将状态管理的这件事情交由 State 类别来处理。

继承 StatefulWidget 的控件需要覆写掉 createState 这个方式,回传自己定义的 State 对象,在 State 中,我们可以定义想要的属性,并且定义控件 build 方法,这个方法与 StatelessWidgetbuild 行为一样是用来定义布局的内容。

StatefulWidget 的实作可以参考下面时间控件的写法,在状态中我们有个字串类别的 _now 属性用来显示目前的时间。TimeModel 类别 mixin ChangeNotifier,每隔一秒钟就会触发时间变更的事件。

我们在生命周期阶段的 initState 监听时间变更的事件,并在收到事件後更新_now的资料并呼叫setState更新画面。

class Clock extends StatefulWidget {
  // 这边的 key 是底层 widget canUpdate 方法有关
  const Clock({Key? key}) : super(key: key);

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

class _Clock extends State<Clock> {
  // TimeModel 自己实作的时间类别
  // 此类别 mixin ChangeNotifier 类别,提供`观察者模式`的特性
  final TimeModel time = TimeModel();

  String _now = "";

   // 透过呼叫 setState 通知状态已异动
  _updateTime() {
    setState(() {
      _now = time.toString();
    });
  }

  // State 生命周期
  @override
  void initState() {
    print('====initState===');
    super.initState();
    // 监听事件
    time.addListener(_updateTime);
  }

  @override
  Widget build(BuildContext context) {
    print('====build====');
    return Text(_now);
  }
}

今日成果

statefulwidget_time

小结

练习成果

重点回顾:

  1. 从控件状态管理是否可变更来区分,控件有 StatelessWidgetStatefulWidget 两种。
  2. 需要状态的话使用 StatefulWidget,并定义 State 物件。
  3. 资料异动後,需要触发 setState 通知 widget

<<:  VPC (一)

>>:  [Day 14] 进入JavaScript,认识浏览器中的JS

Day-26 请问 REST 是什麽? GET 和 POST 是什麽?

传说中的 REST (表现层状态转换) 出现了!一个不太好解释的名词,但面试我还真的碰到了…初心者...

第26天:实作档案上传功能(3)

昨天我们档案上传功能有个问题是不能上传太大的档案,根据我的研究发现,写入档案的部分所需要的时间是不一...

Day26 - 移除没用到的 CSS,使用 Purge CSS (feat. Ant Design, Tailwind)

前言 在前端的世界中,我们经常会站在巨人的肩膀上,如果任何事情都需要自己从零开始动手做,後续的维护也...

[DAY27]将Line讯息存入资料库(01)

再来就是我们要利用Line来记录我们的资料了,以下程序码我放在一个新增程序档 import psyc...

Day18 - 使用ViewBinding取代Kotlin Android Extension

今天是预料之外的内容。 Kotlin在1.4.20-M2版本中弃用了Kotlin Android E...