【Flutter】Stateful widgets与Stateless widgets

原文

Stateful or Stateless widgets?git

前言

在建立一个Flutter App的时候,会遇到两种类型的控件github

  1. 有状态控件(stateful widgets)
  2. 无状态控件(stateless widgets)

Stateless Widgets

在建立控件的时候,有一些控件不须要管理控件内部状态,这个时候就能够选择无状态控件。无状态控件除了用数据初始化之外的时刻,不须要改变它的状态。bash

在Flutter中,比较常见的有Text,Raised Button,Icon。less

Texture

以Text控件为例(源码),这个控件没有能够被改变的状态。异步

const Text.rich(
   TextSpan(
     text: 'Hello', // default text style
     children: <TextSpan>[
       TextSpan(text: ' beautiful ', style: TextStyle(fontStyle: FontStyle.italic)),
       TextSpan(text: 'world', style: TextStyle(fontWeight: FontWeight.bold)),
     ],
   ),
 )
复制代码

Text使用一个构造函数进行初始化,初始化时设置一些属性用于构建控件和控制显示内容。函数

父控件经过设置alignment、direction、text,来控制本身的显示,和管理子控件的显示。ui

什么样的控件是stateless的

那何时该选择使用stateless的控件呢?spa

例子一: 建立一个自定义的ProgressBar控件,使用的时候经过几个参数初始化就能展示给用户。这个控件不须要保留任何状态,它将被添加到父控件的控件树中,或者从父控件的控件树中移除,它的父控件经过管理本身的状态来控制ProgressBar的显示或隐藏。code

例子二: 建立一个内容列表中的列表子控件,好比一个蛋糕列表,蛋糕就是这个控件。这个控件将被填入蛋糕的信息,用于展现蛋糕。但这个控件不会保留状态,它只是使用填充的数据,经过父控件的设置来展现给用户。orm

从这些例子中能够看出,stateless的控件是非动态的。它只须要将数据传入其中,也就是说它只能经过构造函数传入的数据来控制如何显示。

Stateful widgets

Statefule widgets是Stateless widgets的对立面,它是动态的。它能够被随时的、动态的修改内容,不像Stateles widgets只能经过构造函数设置。改变的方式多是用户的输入,异步的响应或者对另外一个状态的变化作出反应。

在Flutter中,比较常见的有Image、Form、Checkbox等。

Image

以Image为例(源码),Image控件的源文件看起来略有不一样,它是继承自StatefulWidget类,也能够经过构造函数传入数据来进行初始化,这些都和StatelessWidget相同。

不一样的地方是,这个控件中多了一个createState方法(源码

_ImageState createState() => new _ImageState();
复制代码

这个覆写的方法用来为控件建立状态。不用深刻Image如何运做的源码,就能够发现_ImageState是用来保存不一样的属性。

ImageStream _imageStream;
  ImageInfo _imageInfo;
  bool _isListeningToStream = false;
  bool _invertColors;
复制代码

ImageInfo用来为控件加载实际图片的属性。

_handleImageChanged函数(源码)中使用了State类的setState函数,来表示状态发生了变动。

setState(() { 
    _imageInfo = imageInfo; 
});
复制代码

当发生了状态变动时,控件将根据新状态从新构建,也就是说控件将加载更新后的imageInfo图片数据。这就是Image的动态行为的表现方式,它会一直监听图片引用,当引用放生变化时,它的状态也会改变。所以Image控件管理着它本身的状态,不依赖于父控件。

什么样的控件是Stateful widgets

例子一: 建立一个控件用来显示一个记录是否被用户添加了书签。这个能够点击的控件将保留一个isBookmarked的属性,当控件被点击的时候,它的状态将会被修改,在控件的build函数中将会为记录设置上已经“已经添加过书签”的标志。

例子二: 建立一个控件用来保存当前被选中的记录数量,当点击“+”按钮的时候将会增长被选中的记录数量。这个控件将保存一个数量的状态,每次点击“+”按钮时,新的数量都会记录到State中,而且在build函数中更新显示为新的数量。

相关文章
相关标签/搜索