您现在的位置: 主页 > 嵌入式操作系统 > Android > Flutter即学即用系列博客05StatelessWidgetvsStatefulWidget
本文所属标签:
为本文创立个标签吧:

Flutter即学即用系列博客05StatelessWidgetvsStatefulWidget

来源:net 网络用户发布,如有版权联系网管删除 2019-02-27 

前言

上一篇我们对 Flutter UI 有了一个基本的了解。

这一篇我们通过自定义 Widget 来了解下如何写一个 Widget?

然而 Widget 有两个,StatelessWidget 和 StatefulWidget,我们要继承哪一个?

下面让我们跟着文章来探索一番。

目录

1. StatelessWidget

我们先来看下继承的 Widget 为 StatelessWidget 的情况。

第一步:新建一个文件 bold_text.dart

这里文件名后面后缀 .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 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 createState() {    return _IncrementState();  }}class _IncrementState extends State {  @override  Widget build(BuildContext context) {    // TODO: implement build    return null;  }}

所以接下来的工作就是类似的。

第六步:实现 Widget

参考一开始的例子我们简单写出下面代码:

import 'package:flutter/material.dart';class Increment extends StatefulWidget{  @override  State createState() {    return _IncrementState();  }}class _IncrementState extends State {  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 createState() {    return _FileNameState();  }}class _FileNameState extends State {  @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 初窥



              查看评论 回复



嵌入式交流网主页 > 嵌入式操作系统 > Android > Flutter即学即用系列博客05StatelessWidgetvsStatefulWidget
 我们 一个 这里

"Flutter即学即用系列博客05StatelessWidgetvsStatefulWidget"的相关文章

网站地图

围观()