Flutter 即学即可使用系列博客——05 StatelessWidget vs StatefulWidget
前言
上一篇我们对 Flutter UI 有了一个基本的理解。
这一篇我们通过自己设置 Widget 来理解下如何写一个 Widget?
然而 Widget 有两个,StatelessWidget 和 StatefulWidget,我们要继承哪一个?
下面让我们跟着文章来探究一番。
目录
1. StatelessWidget
我们先来看下继承的 Widget 为 StatelessWidget 的情况。
第一步:新建一个文件 bold_text.dart
这里文件名后面后缀 .dart 可带可不带
文件名多个单词组成用下划线分隔。
这里我们演示直接在 lib 文件夹下面创立,实际项目记得文件夹结构的组织哦~
第二步:import 系统包
一般自己设置 Widget 都要 import 下面的一个包。
import 'package:flutter/material.dart';
IDE 有自动提醒和补全功能,因而不用死记硬背。
第三步:自己设置一个类继承自 StatelessWidget
一般类名跟文件名一致即可以,采用驼峰格式命名。
import 'package:flutter/material.dart';class BoldText extends StatelessWidget { }
第四步:实现一个需要 override 的方法 build
import 'package:flutter/material.dart';class BoldText extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return null; }}
一般第三步操作之后 IDE 有提醒,直接使用快捷修复自动追加 build 代码就可。如下图:
第五步:实现 Widget
上述代码的 TODO 表示我们要在里面实现对应的 Widget。所以我们删除 TODO,而后在写我们要返回的 Widget 来替换 null 就可。
我们写一个单独的方法 _buildWidget 来返回 Widget,同时返回我们之前写的 Text,如下:
import 'package:flutter/material.dart';class BoldText extends StatelessWidget { @override Widget build(BuildContext context) { return _buildWidget(); } Widget _buildWidget() { return Text( 'Hello, world!', textDirection: TextDirection.ltr, textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.bold), ); }}
可以看到我们这个 Widget 应该会显示成上篇我们界面所见的粗体文本。
但是这里 Hello, world! 写死了,我们要让这个自己设置 Widget 通用少量,可以定义一个必传参数文本内容,修改如下:
import 'package:flutter/material.dart';class BoldText extends StatelessWidget { final String data; BoldText(this.data); @override Widget build(BuildContext context) { return _buildWidget(); } Widget _buildWidget() { return Text( data, textDirection: TextDirection.ltr, textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.bold), ); }}
可以看到我们定义了一个变量,通过构造函数让外部传进来。
这里的 BoldText(this.data); 等价于 Android 下面代码:
BoldText(String data) { this.data = data; }
可以看到 dart 的语法糖简化了写法。具体更多构造函数写法可以查看 dart 官网。
2. 自己设置 Widget 使用
我们以之前的 main.dart 为例进行讲解。
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Text( 'Hello, world!', textDirection: TextDirection.ltr, textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.bold), ), ); }}
第一步:导入我们的自己设置 Widget 包
相对路径:
import 'bold_text.dart';
绝对路径:
import 'package:my_flutter/bold_text.dart';
上面任选其一就可。主要是相对路径和绝对路径的区别。
第二步:使用
import 'package:flutter/material.dart';import 'bold_text.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: BoldText('Hello, world!'), ); }}
比照可以看到节省了很多代码行,尤其对于有多个地方用到的公共组件更加可以这样解决。
3. StatelessWidget 通用模板
FileName为你文件名的驼峰形式:
import 'package:flutter/material.dart';class FileName extends StatelessWidget { @override Widget build(BuildContext context) { return _buildWidget(); } Widget _buildWidget() { //TODO build your widget }}
4. StatefulWidget
我们再来看下继承的 Widget 为 StatefulWidget 的情况。
第一步:新建 increment.dart 文件
第二步:import 系统包
第三步:自己设置一个类继承自 StatefulWidget
第四步:实现一个需要 override 的方法 createState
到这里就有点不一样了。我们先看下目前的代码。
import 'package:flutter/material.dart';class Increment extends StatefulWidget{ @override State<StatefulWidget> createState() { // TODO: implement createState return null; }}
和 StatelessWidget 不一样,这里不是返回 Widget。
我们看下如何操作。
第五步:创立一个类继承 State<T extends StatefulWidget>
这里我们创立 _IncrementState 类继承 State<Increment>,这里尖括号<>里面的类型就是我们一开始写的继承自 StatefulWidget 的类 Increment。
而后我们需要实现一个需要 override 的方法 build。
到这里是不是就是很熟习了。
直接看代码:
import 'package:flutter/material.dart';class Increment extends StatefulWidget{ @override State<StatefulWidget> createState() { return _IncrementState(); }}class _IncrementState extends State<Increment> { @override Widget build(BuildContext context) { // TODO: implement build return null; }}
所以接下来的工作就是相似的。
第六步:实现 Widget
参考一开始的例子我们简单写出下面代码:
import 'package:flutter/material.dart';class Increment extends StatefulWidget{ @override State<StatefulWidget> createState() { return _IncrementState(); }}class _IncrementState extends State<Increment> { int _count = 0; void _incrementCount() { setState(() { _count++; }); } @override Widget build(BuildContext context) { return _buildPage(); } Widget _buildPage() { return MaterialApp( home: Scaffold( body: Center( child : Text('$_count') ), floatingActionButton: FloatingActionButton( onPressed: _incrementCount, tooltip: 'Increment', child: Icon(Icons.add), ), ), ); } }
这里面需要说明的是多了一个新的 Widget FloatingActionButton。
可以看到它是作为 Scaffold 自带的一个属性的。
FloatingActionButton 讲解:
onPressed 后面是这个按钮点击之后会回调的一个方法。
tooltip 是长按之后会显示的提醒文字。
child 是这个按钮显示的图标。
我们修改 main.dart 文件如下,看下效果:
import 'package:flutter/material.dart';import 'increment.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return Increment(); }}
效果如下:
这里重点的代码是下面:
setState(() { _count++;});
它表示将数字加一之后升级界面。
需要升级界面时需要调用 setState 方法。
升级数据源可以在 setState 方法里面写。
5. StatefulWidget 通用模板
FileName为你文件名的驼峰形式,_FileNameState 里面的 FileName 也是哦~
import 'package:flutter/material.dart';class FileName extends StatefulWidget{ @override State<StatefulWidget> createState() { return _FileNameState(); }}class _FileNameState extends State<FileName> { @override Widget build(BuildContext context) { return _buildPage(); } Widget _buildPage() { //TODO build your widget } }
到了这里你回过头去看新建 Flutter 项目时自动创立的 main.dart 文件就看得懂了。
6. StatelessWidget vs StatefulWidget
好了,上面讲解完了 StatelessWidget 和 StatefulWidget,相信大家应该知道如何自己设置一个 Widget 了,也知道如何在其余页面引入了。
但是我们实际上在使用的时候究竟是要继承 StatelessWidget 还是 StatefulWidget 呢?
其实根据名称可以看出取决于你这个 Widget 是有状态还是无状态?
不过「状态」这个词也不是好了解。
所以笔者是这样来区分使用 StatelessWidget 还是 StatefulWidget的?
看界面能否需要升级
比方我们上面的例子,点击按钮文本升级了,所以我们选择了 StatefulWidget。
而第一个只是字体调整,界面渲染之后不再需要升级了,所以我们选择了 StatelessWidget。
所以我们可以认为当界面需要升级时,我们的自己设置 Widget 就要继承 StatefulWidget 而不是 StatelessWidget。
更多阅读:
Flutter 即学即可使用系列博客——01 环境调试
Flutter 即学即可使用系列博客——02 一个纯 Flutter Demo 说明
Flutter 即学即可使用系列博客——03 在旧有项目引入 Flutter
Flutter 即学即可使用系列博客——04 Flutter UI 初窥
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Flutter 即学即可使用系列博客——05 StatelessWidget vs StatefulWidget