首页 > 其他分享 >一统天下 flutter - widget 基础: 生命周期

一统天下 flutter - widget 基础: 生命周期

时间:2023-04-18 12:33:06浏览次数:49  
标签:widget const log counter 一统天下 key override super flutter

一统天下 flutter https://github.com/webabcd/flutter_demo
作者 webabcd

一统天下 flutter - widget 基础: 生命周期

示例如下:

lib\widget\basic\lifecycle.dart

/*
 * 生命周期
 */

import 'package:flutter/material.dart';

import '../../helper.dart';

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

  /// 用于创建相关的 Element
  @override
  StatefulElement createElement() {
    log("createElement()");
    return super.createElement();
  }

  /// 用于创建这个 StatefulWidget 的 State(注:State 是保存在 Element 树中的)
  @override
  _LifecycleDemoState createState() => _LifecycleDemoState();
}

/// 通过 with WidgetsBindingObserver 可以监听应用程序的状态
class _LifecycleDemoState extends State<LifecycleDemo> with WidgetsBindingObserver {

  int counter = 0;

  /// 在生命周期中只在初始时调用一次,可以在这里做一些初始化工作
  @override
  void initState() {
    log("initState()");

    /// 开始监听
    WidgetsBinding.instance.addObserver(this);

    super.initState();
  }

  /// State 对应的 Element 被从树中永久移除时
  @override
  void dispose() {
    log("dispose()");

    /// 停止监听
    WidgetsBinding.instance.removeObserver(this);

    super.dispose();
  }

  /// 在 dispose() 之前调用,或者对应的 Element 被从树中临时移除时(这个一般用不到)
  @override
  void deactivate() {
    log("deactivate()");
    super.deactivate();
  }

  /// 在对应的 Element 被从树中临时移除后,又加入到树中时(这个一般用不到)
  @override
  void activate() {
    log("activate()");
    super.activate();
  }

  /// 用于 debug 模式下的开发调试
  /// 在 debug 模式下,每次 hot reload 后是不会重新创建 State 实例的,也不会走到 initState()
  /// 但是每次 hot reload 后会先调用这里,然后再执行 build()
  @override
  void reassemble() {
    log("reassemble()");
    super.reassemble();
  }

  /// 来自 with WidgetsBindingObserver 可以监听应用程序的状态,需要先 WidgetsBinding.instance.addObserver(this);
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);

    /// AppLifecycleState.resumed - 前台活动状态
    /// AppLifecycleState.paused - 后台非活动状态
    /// AppLifecycleState.inactive - 前台非活动状态(比如接听了一个电话,或 ios 中显示了系统的下拉菜单,等等)
    log('state: $state');
  }


  /// 构造 widget
  /// 在 initState() 或 setState() 或 didUpdateWidget() 或 didChangeDependencies() 或 activate() 之后调用
  @override
  Widget build(BuildContext context) {
    log("build()");
    return Container(
      color: Colors.orange,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          MyButton(
            onPressed: () async {
              await Future.delayed(const Duration(milliseconds: 3000));

              /// mounted 用于表示 State 对应的 Element 是否挂载到树中
              ///   mounted 为 true 时,可以正常的 setState() 并渲染页面
              ///   mounted 为 false 时,如果调用 setState() 则会报错
              /// 如果异步任务回调后需要重新渲染页面,则建议先判断 mounted 以便确定是否可渲染
              /// 如果回调之前退出了页面的话,则 mounted 就变为 false 了,之后如果再去渲染页面的话就会报错
              if (mounted) {
                setState(() {

                });
              }
            },
            child: const Text('长时任务'),
          ),

          MyButton(
            onPressed: () {
              setState(() {
                counter++;
              });
            },
            child: const Text('计数器 +1'),
          ),
          MyText("counter:$counter"),
          _MyWidget1(counter: counter),
          _MyInheritedWidget(
            counter: counter,
            child: const _MyWidget2(),
          ),
        ],
      ),
    );
  }
}



class _MyWidget1 extends StatefulWidget {
  const _MyWidget1({required this.counter, Key? key}) : super(key: key);

  final int counter;

  @override
  _MyWidget1State createState() => _MyWidget1State();
}
class _MyWidget1State extends State<_MyWidget1> {

  /// 当父组件重绘时
  @override
  void didUpdateWidget(covariant _MyWidget1 oldWidget) {
    log("didUpdateWidget(), oldWidget:${oldWidget.counter}, newWidget:${widget.counter}");
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    return MyText("counter:${widget.counter}");
  }
}



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

  @override
  _MyWidget2State createState() => _MyWidget2State();
}
class _MyWidget2State extends State<_MyWidget2> {

  /// 当 initState() 调用后,或者当依赖的 InheritedWidget 的共享变量发生变化时
  @override
  void didChangeDependencies() {
    log("didChangeDependencies()");
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return MyText("counter:${_MyInheritedWidget.of(context)!.counter}");
  }
}



class _MyInheritedWidget extends InheritedWidget {
  const _MyInheritedWidget({Key? key, required Widget child, required this.counter}) : super(key:key, child: child);

  final int counter;

  static _MyInheritedWidget? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<_MyInheritedWidget>();
  }

  @override
  bool updateShouldNotify(covariant _MyInheritedWidget oldWidget) {
    return counter != oldWidget.counter;
  }
}

一统天下 flutter https://github.com/webabcd/flutter_demo
作者 webabcd

标签:widget,const,log,counter,一统天下,key,override,super,flutter
From: https://www.cnblogs.com/webabcd/p/flutter_lib_widget_basic_lifecycle.html

相关文章

  • Visual Studio编译和使用wxWidgets
    一、下载到官网:https://www.wxwidgets.org/官网会引导跳到github:https://github.com/wxWidgets/wxWidgets/releases/tag/v3.2.2github有很多个下载链接,有代码(source)和预编译包(binary),后者又分开发版(dev)和发布版(release)预编译包的VC版本和VS版本对应如下:*vc14x兼容20......
  • Flutter 集成 uni小程序(UniMPSDK)
    原文地址amoshk.top又是一段成为鸽子的日子,今天我们直接来上手一把,简单聊聊如何在Flutter中集成并使用小程序。在国内环境下,小程序盛行,随着功能的庞大,许多业务上也需要进行支持,帮助开发进行抽离(减少宿主APP频繁发版、方便形成生态、便于独立进行测试与漏洞修复等),使用者也......
  • pyqt5-QTreeWidget
    1、介绍树形组件2、类和初始化classQTreeWidget(QTreeView):"""QTreeWidget(parent:QWidget=None)"""def__init__(self,parent=None):pass3、属性4、方法(1)setColumnCount设置列数,参数为int类型。树形组件只能是设置为1(2)setHeaderLabels设......
  • pyqt5-QTableWidget
    1、介绍这是pyqt的表格组件。2、类和初始化classQTableWidget(QTableView):def__init__(self,*__args):pass示例:self.table=QTableWidget(self.w)3、属性4、方法(1)columnCount和rowCount返回int类型,即列数和行数,最低为0,即空白,此时没有表头(2)setColum......
  • pyqt5-QTabWidget
    QTabWidget详解–fengMisaka–博客园(cnblogs.com)1、介绍标签页组件。2、类和初始化classQTabWidget(QWidget):def__init__(self,parent=None):pass3、属性4、常用方法(1)addTabdefaddTab(self,QWidget,*__args):"""addTa......
  • pyqt5-QWidget
    1、介绍QWidget是几乎所有pyqt组件的直接或间接父类,其声明的属性和方法很具有代表性。其他组件极大可能是直接使用,所以一般不再阐述。除非少数可能做了个性化覆写。2、类和初始化classQWidget(__PyQt5_QtCore.QObject,__PyQt5_QtGui.QPaintDevice):def__init__(self,p......
  • QtableWidget插入数据卡顿优化方法
    最近要使用Qtablewidget保存4300多的数据,发现以下刷新4300条数据,界面会变得非常卡顿,于是想了优化一下;因为要对所有数据排序,想用一下Qtablewidget自动排序功能,而且数据量不多,不想采用动态加载的方式来实现;方法1复用内存,不重复清除创建以前每次都会清除,然后重新创建对象,写数据,发现......
  • Qt5.9 UI设计(五)——将Tabwidget与treeWidget相互关联
    前言前面一章介绍了ControlTabWidgetControlTreeWidgetmaintitlebar三个子页面同时布局到mainwindow的方法,本章介绍如何将ControlTreeWidget与ControlTabWidget联动。(一)TabWidget子页面实现在maincontent目录下创建otaparatarnsmittelnettester五个目录,用来......
  • 一统天下 flutter - UI: 其它
    一统天下flutterhttps://github.com/webabcd/flutter_demo作者webabcd一统天下flutter-UI:其它示例如下:lib\ui\other.dart/**其它*/import'dart:io';import'package:flutter/foundation.dart';import'package:flutter/material.dart'......
  • 一统天下 flutter - UI: MediaQuery - 获取屏幕的相关信息,使系统设置中的字体大小无效
    一统天下flutterhttps://github.com/webabcd/flutter_demo作者webabcd一统天下flutter-UI:MediaQuery-获取屏幕的相关信息,使系统设置中的字体大小无效示例如下:lib\ui\media_query.dart/**MediaQuery-获取屏幕的相关信息,使系统设置中的字体大小无效*/imp......