当前位置: 首页 > news >正文

深度理解Flutter:有状态Widget与无状态Widget的详细对比

image.png

有状态Widget

什么是有状态Widget (StatefulWidget)

官方解释: 如果用户与 widget 交互,widget 会发生变化,那么它就是 有状态的
有状态的 widget 自身是可动态改变的(基于State)。 例如用户交互而改变 Widget 的 state。
Checkbox、Radio、Slider class - material library - Dart API、 InkWell、Form 和 TextField 都是有状态 widget,它们都是 StatefulWidget 的子类。

Widget 的 状态(state )保存在一个 State 的对象中。 StateWidget 是分离的,当 Widget状态变化时,State 对象调用 setState() 来通知框架去重绘 Widget

如何创建一个有状态Widget

实现一个有状态Widget需要创建两个类:

  • 一个 StatefulWidget 的子类,用来定义一个 widget 类。
  • 一个 State 的子类,包含该widget状态并定义该 widget 的 build() 方法。

我们可以通过 VSCode Flutter 命令补全来快速场景一个 有状态组件:

fstful

image.png

import 'package:flutter/material.dart';class FulStatePage extends StatefulWidget {const FulStatePage({super.key});_FulStatePageState createState() => _FulStatePageState();
}class _FulStatePageState extends State<FulStatePage> {Widget build(BuildContext context) {return Container();}
}
创建StatefulWidget 子类

上面代码中,我创建了一个 FulStatePage 类 继承了 StatefulWidget ,这时它是一个有状态的Widget
框架在 构建 Widget 时会调用 createState()创建管理state ,上面代码中,我们创建了 _FulStatePageState 实例.

class FulStatePage extends StatefulWidget {const FulStatePage({super.key});_FulStatePageState createState() => _FulStatePageState();
}

上面代码详细解释:

  1. FulStatePage类继承自StatefulWidget,表示这是一个具有可变状态的小部件。
  2. 构造函数const FulStatePage({super.key})接收一个可选参数key,用于在构建小部件时标识它。
  3. createState()方法返回一个与FulStatePage关联的状态对象,即_FulStatePageState
  4. _FulStatePageStateFulStatePage对应的状态类,它继承自State类
  5. _FulStatePageState中可以定义和管理该小部件的可变状态,并实现相关的业务逻辑。
  6. 通过重写build()方法,在其中构建小部件树来描述该小部件的外观和行为。
  7. FulStatePage类通常会被作为其他小部件的子部件使用,以提供动态交互和数据驱动的功能。

需要注意的是:

  • FulStatePage类的构造函数使用了const关键字,表示该小部件是不可变的,即其属性在构建后不能更改。
  • key参数用于在小部件树中唯一标识该小部件,以便在进行更新、重建等操作时进行准确定位。
  • createState()方法必须被重写,用于创建与该小部件关联的状态对象
  • 状态对象State负责管理和更新小部件的可变状态,并通过setState()方法通知Flutter框架进行重建。
创建State的子类

_FulStatePageState 类存储可不的信息。

class _FulStatePageState extends State<FulStatePage> {int num = 0; void setNum(){setState(() {++num})}Widget build(BuildContext context) {return Container();}
}

上面代码详细解释:

  1. _FulStatePageState类继承自State<FulStatePage>,表示它是FulStatePage小部件的状态类。
  2. build()方法中,可以构建并返回描述该小部件外观和行为的小部件树。
  3. 当状态发生变化时,build()方法会被调用,以重新构建小部件树来反映新的状态。

需要注意的是:

  • BuildContext context参数提供了与当前小部件相关的上下文信息,可以用于获取主题、媒体查询等。
  • build()方法中,可以使用各种小部件来构建界面,例如Container、Text、Image等。
  • 返回的小部件树描述了该小部件的外观和行为,可以包含其他小部件作为子部件。
  • 可以在build()方法中使用状态对象的属性来动态生成小部件,实现根据状态变化而改变界面的效果。
  • 避免在build()方法中进行耗时操作,以保持应用程序的响应性能。
  • 如果需要更新状态并触发重建,应使用setState()方法。这将通知Flutter框架重新调用build()方法。

无状态Widget StatelessWidget

在Flutter中,无状态小部件(Stateless Widget)是一种不包含可变状态的小部件。它们是不可变的,意味着一旦构建完成,它们的内容就不能再改变。
无状态小部件通过继承StatelessWidget类来创建,并重写build方法来描述其UI。build方法接收一个BuildContext参数,并返回一个小部件树,用于构建界面。

import 'package:flutter/material.dart';class CollectPage extends StatelessWidget {
const CollectPage({super.key,});Widget build(BuildContext context){return Container();}
}

什么时候使用无状态Widget

  1. 当小部件的内容是静态的,不需要根据外部事件或数据进行更新时,可以使用无状态小部件。例如,一个简单的文本展示小部件或一个静态的图标按钮。
  2. 当小部件的状态由父级管理时,可以使用无状态小部件。父级可以通过传递参数来控制子部件的外观和行为。
  3. 当小部件不需要响应用户交互时,可以使用无状态小部件。无状态小部件主要用于展示静态内容,而不涉及与用户的交互。
  4. 当性能要求较高时,无状态小部件比有状态小部件具有更轻量级的性能开销,因为它们不需要维护状态对象。所以,在性能要求较高的场景下,可以考虑使用无状态小部件。

例如一些纯静态展示内容 [文章列表,listview 显示的内容(不需要交互改变weidget), 一些按钮等]
总之,无状态小部件适用于静态内容、由父级管理状态、不需要响应用户交互或对性能要求较高的情况。

相关文章:

  • 华为ipsec双冗余配置案例
  • 为什么游戏服务端用开发效率低的C++来写,其他语言无法胜任吗?
  • Go语言程序设计-第5章--函数
  • 【Swagger】常用注解的使用、SpringBoot的整合及生产环境下屏蔽Swagger
  • [每周一更]-(第43期):Golang版本的升级历程
  • linux安装anaconda
  • 自定义html5中日期选取器的样式
  • uniapp-H5项目的坑
  • 经典卷积神经网络-VGGNet
  • Qt 中使用 MySQL 数据库保姆级教程(下)
  • Springer build pdf乱码
  • Android 理解Context
  • Oracle-深入了解cache buffer chain
  • Postman常见问题及解决方法
  • 目标检测-One Stage-SSD
  • 【Amaple教程】5. 插件
  • 【翻译】babel对TC39装饰器草案的实现
  • Cookie 在前端中的实践
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • JAVA并发编程--1.基础概念
  • JS函数式编程 数组部分风格 ES6版
  • leetcode98. Validate Binary Search Tree
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • mysql外键的使用
  • nodejs调试方法
  • Node项目之评分系统(二)- 数据库设计
  • oschina
  • Python连接Oracle
  • spring boot 整合mybatis 无法输出sql的问题
  • vue-router 实现分析
  • 电商搜索引擎的架构设计和性能优化
  • 前端工程化(Gulp、Webpack)-webpack
  • 什么软件可以剪辑音乐?
  • 写给高年级小学生看的《Bash 指南》
  • 一些关于Rust在2019年的思考
  • 正则表达式小结
  • gunicorn工作原理
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (规划)24届春招和25届暑假实习路线准备规划
  • (数据结构)顺序表的定义
  • ***原理与防范
  • .bat文件调用java类的main方法
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)
  • .Net接口调试与案例
  • .NET中 MVC 工厂模式浅析
  • .NET中的Exception处理(C#)
  • .NET中的十进制浮点类型,徐汇区网站设计
  • ?.的用法
  • @JsonFormat与@DateTimeFormat注解的使用
  • [@Controller]4 详解@ModelAttribute