1.1 Flutter的特点与核心概念
Flutter的特点如下所示:
跨平台:现在Flutter至少可以跨5种平台,甚至支持嵌入式开发。我们常用的有MacOS、Windows、Linux、Android、iOS,甚至可以在谷歌最新的操作系统Fuchsia上运行。到目前为止,Flutter算是支持平台最多的框架了,良好的跨平台性,直接带来的好处就是减少开发成本。
丝滑般的体验: 使用Flutter内置高大上的Material Design和Cupertino风格组件、丰富的motion API、平滑而自然的滑动效果和平台感知,为用户带来全新体验。
响应式框架:使用Flutter的、响应式框架和一系列基础组件,可以轻松构建用户界面。使用功能强大且灵活的API(针对2D、动画、手势、效果等)能解决艰难的UI挑战。
支持插件:通过Flutter的插件可以访问平台本地API,如相机、蓝牙、WiFi等。借助现有的Java、Swift、Objective C、C++代码实现对原生系统的调用。
60fps超高性能:Flutter采用GPU渲染技术,所以性能极高。Flutter编写的应用是可以达到60fps(每秒传输帧数),这也就是说,它完全可以胜任游戏的制作。官方宣称用Flutter开发的应用甚至会超过原生应用的性能。
Flutter包括一个现代的响应式框架、一个2D渲染引擎、现成的组件和开发工具。这些组件可以帮助你快速地设计、构建、测试和调试应用程序。Flutter的核心概念有:组件、构建、状态、框架等,下面分别介绍。
1.1.1 一切皆为组件
组件(Widget)是Flutter应用程序用户界面的基本构建块。不仅按钮、输入框、卡片、列表这些内容可作为Widget,甚至将布局方式、动画处理都视为Widget。所以Flutter具有一致的统一对象模型:Widget。
Widget可以定义为:
一个界面组件(如按钮或输入框)。
一个文本样式(如字体或颜色)。
一种布局(如填充或滚动)。
一种动画处理(如缓动)。
一种手势处理(GestureDetector)。
Widget具有丰富的属性及方法,属性通常用来改变组件的状态(颜色、大小等)及回调方法的处理(单击事件回调、手势事件回调等)。方法主要是提供一些组件的功能扩展。比如:TextBox是一个矩形的文本组件,其属性及方法如下:
bottom:底部间距属性。
direction:文本排列方向属性。
left:左侧间距属性。
right:右侧间距属性。
top:上部间距属性。
toRect:导出矩形方法。
toString:转换成字符串方法。
1.1.2 组件嵌套
复杂的功能界面通常都是由一个一个简单功能的组件组装完成的。有的组件负责布局,有的负责定位,有的负责调整大小,有的负责渐变处理,等等。这种嵌套组合的方式带来的最大好处就是解耦。
例如,界面中添加了一个居中组件Center,居中组件里嵌套了一个容器组件Container,容器组件里嵌套了一个文本组件Text和一个装饰器BoxDecoration。代码如下所示:
return new Center( //添加容器 child: new Container( //添加装饰器 decoration: new BoxDecoration( ), child: new Text( //添加文本组件 ), ), ),
大家如果是首次看到这段代码会觉得嵌套层次太多,太复杂。其实不然,随着对组件的深入了解及熟练使用,写起来还是非常得心应手的。
最基础的组件类是Widget,其他所有的组件都是继承Widget的,如图1-1所示。紧接着下面有两大类组件:有状态组件及无状态组件。有状态组件是界面会发生变化的组件,如Scrollable、Animatable等,无状态的组件即界面不发生变化的组件,如Text、AssetImage等。
图1-1 类层次结构
1.1.3 构建Widget
可以重写Widget的build方法来构建一个组件,如下代码所示:
@protected Widget build(BuildContext context);
build即为创建一个Widget的意思,返回值也是一个Widget对象,不管返回的是单个组件还是返回通过嵌套的方式组合的组件,都是Widget的实例。
1.1.4 处理用户交互
如果Widget需要根据用户交互或其他因素进行更改,则该Widget是有状态的。例如,如果一个Widget的计数器在用户点击一个按钮时递增,那么该计数器的值就是该Widget的状态。当该值发生变化时,需要重新构建Widget以更新UI。
这些Widget将继承StatefulWidget(而不是State)并将它们的可变状态存储在State的子类中,如图1-2所示。
图1-2 有状态Widget继承示意图
每当你改变一个State对象时(例如增加计数器),必须调用setState()来通知框架,框架会再次调用State的构建方法来更新用户界面。
有了独立的状态和Widget对象,其他Widget可以以同样的方式处理无状态和有状态的Widget,而不必担心丢失状态。父Widget可以自由地创造子Widget的新实例且不会失去子Widget的状态,而不是通过持有子Widget来维持其状态。框架在适当的时候完成查找和重用现有状态对象的所有工作。
1.1.5 什么是状态
Flutter中的状态和React中的状态概念一致。React的核心思想是组件化的思想,应用由组件搭建而成,而组件中最重要的概念是State(状态), State是一个组件的UI数据模型,是组件渲染时的数据依据。Flutter程序的运行可以认为是一个巨大的状态机,用户的操作、请求API和系统事件的触发都是推动状态机运行的触发点,触发点通过调用setState方法推动状态机进行响应。状态的生命周期如图1-3所示。
图1-3 状态的生命周期
1.1.6 分层的框架
Flutter框架是一个分层的结构,每一层都建立在前一层之上。图1-4显示了Flutter框架,上层比下层的使用频率更高。
图1-4 Flutter框架
提示
有关构成Flutter分层框架的完整库,请参阅官方的API文档,地地为:https://docs.flutter.io/。
分层设计的目标是帮助开发者用更少的代码做更多的事情。例如,Material层通常组合来自Widget层的基本Widget,而Widget层通过较低级对象渲染层来构建。
分层结构为构建应用程序提供了许多选项。选择一种自定义的方法来释放框架的全部表现力,或者使用构件层中的构建块,或混合搭配。可以使用Flutter提供的所有现成的Widget,也可以使用Flutter团队用于构建框架的相同工具和技术创建定制的Widget。也就是说,你可以从高层次、统一的Widget概念中获得开发效率优势,也可以深入到下层施展才能。