Flutter 食髓知味

移动开发演变

  1. 原生开发

   早期针对各平台(操做系统差别),使用相应平台支持的开发语言,开发应用。就 ios 和 android 两大阵营来说,须要两套代码来实现一款应用,生产效率相对较低。前端

  1. 混合开发(Hybrid)

   H5 技术的出现,为 web 运行在原生应用中提供了更好的支持。webview + jsBridge 让 web 开发者也可以开发原生应用,而且一套代码适配两端。vue

  1. 原生渲染

   前端框架群雄逐鹿,React 社区推出了 React-Native ,经过 JS 控制原生控件,一样作到了适配两端,但性能依然是瓶颈,JS 语言成为了限制所在。android

  1. 自制 UI 引擎

   吸取其余框架所长,自制 UI 引擎。Flutter 使用 dart 语言开发,静态类型,编译型语言,AOT 让运行时速度更快。既不使用 webview 也不使用操做系统原生控件, 自制 UI 引擎,能够保证在 android 和 ios 的一致性。ios

Flutter UI

绘图原理

   一切前端编码都是 GUI 编程,即针对于操做系统硬件绘图能力的应用。git

UI (用户界面)
        /\
        ||
        GPU
        /\
        ||
        CPU
复制代码

   用户界面由大量的显像单元组成,每一个像素点的颜色构成了整个视图界面。咱们经过编码来控制像素点色号,从而控制视图成像。编码发出系统指令,CPU 首先根据指令计算内容数据,再交由 GPU 生成每一个像素点的色彩数据,最终输出给显像单元呈色。github

   flutter 在原生应用平台之上构建了一套完整的 UI 系统,调用 OpenGL 库来间接调用操做系统 API。从而实现跨平台操做,而且保证了原生的渲染性能。web

Flutter
      ||
      \/
    OpenGL
      ||
      \/
    OS API
复制代码

Flutter UI 系统

   有 web 开发经验,使用过诸如 React, vue 等框架的同窗,理解 Flutter 系统会更加容易些。吸取现代前端系统架构,采用组件化及声明式,Flutter 也是这一思想的践行者。算法

Widget                  Component
      ||                       ||
      \/                       \/
    Element                VirtualDOM
      ||                       ||
      \/                       \/
  RenderObject                dom
复制代码

   一样以组件为 UI 构成的最小单元,将视图单元抽象成相应的数据结构单元,在交互致使的状态变化时使用优化后的对比算法来获取最小修改集合,经过 batchUpdate 来更新视图, 总体思想与 web 前端框架一模一样。编程

   其中 Widget (同比组件) 分为 StatelessWidget 和 StatefulWidget 两类,可类比无状态组件和有状态组件。缓存

Dart 与 Flutter

  1. Dart 单线程模型

使用 Event Loop 事件调度模型,Dart 与 JS 一样选用单线程循环执行任务。

  1. final 和 const

为何 dart 要支持两种不可变量声明方式,final 和 const 到底有什么不同的?

var count = 10;
final Num = count;  // final 只能赋值一次
const Num1 = 10; // const赋值必须是编译时常量
复制代码

const 特殊之处在于,它所声明的变量值必须是运行时常量。

  1. 定义必传参数
const Scrollbar({Key key, @required Widget child})
复制代码

经过 @required 修饰的命名参数为必传参数,调用时不传会致使编译报错。

  1. 初始化列表

dart 支持了在建立实例时,初始化实例对象成员的能力,被称为 初始化列表

import 'dart:math';

class Point {
  final int x;
  final int y;
  final num distance;

  // 在 : 后进行初始化列表操做
  Person(x, y):
    x = x,
    y = y,
    distance = sqrt(x * x + y * y);
}

void main() {
  final i = new Point(2, 3);
  print(i.distance)
}
复制代码
  1. Widget build

widget 须要实现 build,做为 UI 输出函数。

Widget build(BuildContext context);
复制代码

context 为当前结点的上下文,指代组件实例对象。

  1. 建立 cacheable 对象

若是你想建立缓存对象,能够考虑使用工厂构造函数。

class Logger {
  final String name;
  bool mute = false;
  static final Map<String, Logger> _cache = {};

  factory Logger(String name) {
    // 工厂构造函数中不能使用 this
    if (_cache.contains(name)) {
      // 返回缓存对象
      return _cache[name]
    } else {
      // 经过命名构造函数建立 Logger 实例
      final Logger log = Logger.internal(name);
      _cache[name] = log;
      return log;
    }
  }

  Logger.internal(this.name);

  void log (String msg) {
    if (!mute) print(msg);
  }
}

var logger = Logger('UI');
logger.log('clicked');
复制代码

使用体验

优势

  1. 类型系统带来的稳定性

   出身 web 开发,深切感觉了 JS 语言编写应用的不稳定性,其根本缘由是 JS 为弱类型语言,无 AOT 机制,即使引入了 Typescript 仍是没法完全解决这一问题,由于不少前端开发人员并无意识到面向接口编程的利好。
   在 Flutter 中并不存在问题,Flutter 使用的 dart 语言自带类型系统,支持 JIT 的同时也支持 AOT,类型为必选项,而且若是类型错误是没法编译经过的。
   因而在咱们类型编写无误的状况下,编译阶段能够帮助咱们检验编码中的错误, 杜绝取值隐患,鲜有可能再出现相似以下错误。

  1. 优质的用户使用体验

   在 Flutter 以前,也有 RN ,Weex 等跨平台移动端框架,但因为其设计是在原生系统之上又构建了一个统一调度层,所以在性能表现上有所降低,尤为在动画渲染中须要时刻同步原生系统,不足之处更为明显。
   Flutter 使用了自制 UI 引擎,在底层兼容了平台差别,取代了 Android 与 Ios 原生渲染引擎,暴露给开发者的一致性的 API,这一点既保证了跨平台兼容,也解决了性能问题。

缺点

  1. widget 嵌套地狱

   Flutter 在语法层面也并不是尽善尽美,经过组合来构建 UI 的常见模式广为接受,但其语法设定显得十分累赘。

   简单的样式描述,就须要许多 widget 进行组合,致使一小块的 UI 结构可能就须要尽百行的代码来绘制,这对于应用的可读,后续维护,业务扩展都是极其不利的。
   或许能够参考形如 React 中 JSX 语法,支持如 DartX,经过 XML 和 style 的组合,来简化结构,加强可读性。这一点在社区也有诸多共鸣

相关文章
相关标签/搜索