小册试读2 - Flutter基础知识简述

176 阅读4分钟

如小册前言所述,本小册的读者对象需要有一定的Dart语言和Flutter框架基础知识。本小册并不会再去赘述这些基础知识,基础知识是比较重要的,如果您刚刚接触Flutter,推荐阅读《Flutter实战·第二版》- Preview快速入门。虽不去长篇大论的赘述基础知识,但以下几个基本知识点,我觉得还是有必要简述一下。

1,Flutter是声明式UI框架,数据驱动视图的改变

从命令式UI变革到声明式UI,是大前端发生的变革。
什么是命令式UI
UI的更新是由程序员使用代码主动刷新,UI与数据并无必然的映射关系,这种我们称之为命令式UI 更改一个View的背景颜色值,我们看看在命令式UI中是如何实现的:
iOS(Android类似):

UIView* view = [[UIView alloc] initWithFrame:frame]; 
view.backgroundColor = [UIColor redColor];

web前端

$("view").css("background-color","red");

可以看到,在命令式UI中,都是由程序员主动获取view对象,然后通过setter()等方法对view进行改变。 命令式UI的一些问题:

  • UI维护工作繁重,UI的改变全部需要程序员用代码来处理,无论是前端还是移动端,过去程序员有一大部分工作是在处理UI的各种刷新上。
  • UI的刷新时机很多,如下拉刷新获取数据通知UI变更,网络错误通知UI变更等等,需要处理的工作一旦多起来,出错便难以避免。
  • UI与数据的不一致,命令式UI中,程序员会首先调用方法获取数据,然后再由另一些方法去刷新UI,难免会出现数据变更而忘记UI刷新的可能性。

由于以上问题,声明式UI应运而生,声明式UI和命令式UI最核心的区别在于:

  • UI是数据的映射与描述,甚至一些框架中,程序员是无法持有UI组件的。更谈不上去调用这个组件的方法刷新UI了。
  • 程序员关心的只是数据,只需要在合适的时机刷新数据就行了。UI则根据映射,由技术背后的机制帮你去刷新处理。 我们来看看上述改变view背景色的例子在Flutter声明式UI中如何实现:
class HomePageState extends State<HomePage> {
  var bgColor = Colors.blue;
  @override
  Widget build(BuildContext context) {
    return Container(
        color:bgColor,
        alignment:Alignment.center,
        child: RaisedButton(
          child: Text("刷新颜色"),
          onPressed: () => setState(() {bgColor = Colors.red;}))
    );
  }
}

我们只需要变更数据源bgColor的值,便能实现Container()背景色的变更,这便是声明式UI

2,Flutter 2.x 空安全(Sound Null Safety)

什么是空安全?我们先来看下面一段代码:

var text:String = null;  //定义一个String类型的text变量
print(text.length);      //输出text的长度

上面的代码片段在Flutter 2.0之前,编译阶段是没有问题,而在运行时就crash了。
而空安全的出现,使得上述代码在代码编译时间就无法通过,使得Bug的发现提前了。不必在App上线后再出现很多恼人的Bug
下面看看在Flutter 2.0之后上述的代码如何编写:

var text:String?;       //定义一个String?类型的text变量
print(text.length);     //输出text的长度

这样的代码在编译阶段就会报错,原因在于text可能为null,而null是无法去调用length属性的。
修改如下:

var text:String?;       //定义一个String?类型的text变量
print(text?.length);    //输出text的长度

text?.length表示如果text如果为null,整个表达式都会为null。当然如果你确定你的text不会为null,你可以通过!进行解包,text!.length

在定义变量的时候,如下代码也是无法通过的,因为textString类型,它必然不能为null,必须在初始化的时候给它赋值。我们可以把text更改为String?类型。

var text: String;

另一个修改方法:使用late关键字告诉编译器,text属性,我之后再去赋值。

late var text: String;

其他类型如List,Map,Class等空安全叙述请自行学习。