一、前言
本系列文章旨在快速复习并上手Flutter开发,并在适当分享在项目实战过程中遇到的一些比较有价值的知识内容:
- 01-📝Flutter核心知识|了解Flutter【诞生背景、应用简介、页面渲染原理、搭建开发环境、创建Flutter项目的几种方式】
- 02-📝Flutter核心知识|Dart语言快速入门|常规语法【Dart介绍和安装、程序分析、常用数据类型、函数、运算符、逻辑分支】
- 03-📝Flutter核心知识|Dart语言快速入门|面向对象【类和对象、泛型、库的使用、异步模型、异步操作】
- 04-📝Flutter核心知识|了解Widget【Center、MaterialApp、Row、CheckBox、DIY、Column、ListView等】
- 05-📝Flutter核心知识|常用Widget1【StatefulWidget、文本Widget、按钮Widget、图片Widget、表单Widget】
- 06-📝Flutter核心知识|布局与滚动组件【单子布局、多子布局、JSON读取和解析、ListView、GridView、Slivers、监听滚动事件
- 07-📝Flutter核心知识|自定义Widget【StarRating、DashedLine、底部TabBar】
本系列文章内容篇幅如下:
- 一、了解Flutter开发
-
- Flutter的特性与应用场景
-
- Flutter绘制原理
-
- 与Flutter相关的技术原理
-
- 搭建Flutter开发环境
-
- 创建Flutter项目的几种方式
-
- 二、快速入门Flutter开发知识大纲
-
- Dart语言快速入门
-
- Flutter的Widget
-
- 三、常见应用功能模块与开源项目
-
- 常见应用功能模块
-
- 不错的开源项目
-
1. 移动开发的几种方式
移动开发的几种方式
原生开发
跨平台开发
原生开发
原生应用程序
是指某一个移动平台(比如iOS
或安卓
)所特有的应用
- 使用相应平台支持的
开发工具
和语言
,并直接调用系统提供的SDK API
:
- 比如
Android
原生应用就是指使用Java
或Kotlin
语言直接调用Android SDK
开发的应用程序;- 而
iOS
原生应用就是指通过Objective-C
或Swift
语言直接调用iOS SDK
开发的应用程序。- 移动互联网发展初期
- 在移动互联网发展初期,业务场景并不复杂
原生开发
还可以应对产品需求迭代。- 近几年
- 但近几年,随着
物联网时代
到来、移动互联网
高歌猛进,日新月异:- 在很多业务场景中,
传统的纯原生开发已经不能满足日益增长的业务需求
。- 主要表现在:
开发效率
:JIT编译、动态化热重载开发成本
多端统一性
: 用户界面」、热更新- 动态化内容需求增大
- 当需求发生变化时,
纯原生应用
需要通过版本升级来更新内容
- 但应用
上架、审核是需要周期
的
- 这对高速变化的互联网时代来说是很难接受
- 所以,对
应用动态化
(不发版也可以更新应用内容)的需求就变的迫在眉睫。- 业务需求变化快,开发成本变大
- 由于
原生开发
一般都要维护Android
、iOS
两个开发团队- 版本迭代时,无论
人力成本
,还是测试成本
都会变大。总结一下,纯原生开发主要
面临动态化
和开发成本
两个问题,而针对这两个问题,诞生了一些跨平台的动态化框架。
- 主要优势:
- 可
访问平台全部功能
(GPS、摄像头);速度快
、性能高
、可以实现复杂动画及绘制
,整体用户体验好
;- 主要缺点:
- 平台特定,
开发成本高
;不同平台必须维护不同代码
,人力成本随之变大;- 内容固定,
动态化弱
,大多数情况下,有新功能更新时只能发版;跨平台技术简介
针对
原生开发
面临问题,业界一直都在努力寻找好的解决方案,而时至今日,已经有很多移动端跨平台框架
,根据其原理,主要分为三类:
WebView
技术类RN
技术Flutter
技术
2. 快速了解Hybrid技术的特点
几种跨平台方案
的特点
和 不同方案的性能比较
关于大前端技术的
几种跨平台方案
的特点
和 不同方案的性能比较
,若你想深入了解的同学可以参考的这几篇文章:若你想直接看结论,可以直接跳到
小结
部分小结
- 渲染性能比较1:
WebView < 类ReactNative < 原生。 (因为json的复杂度比html+css低)
- 渲染性能比较2:
Flutter ≈ Native
- 渲染性能比较汇总:
原生渲染 ≈ Flutter渲染 > 类RN大前端 > Web
- 但
Flutter
的优势在于:
- 跨平台
- 可以同时运行在
iOS
、Android
两个平台。- 热重载(
Hot Reload
)
- 省去了重新编译代码的时间,极大的提高了开发效率。
- 同时
Flutter又支持跨平台开发
,那么其他领域的技术栈存在的价值会越来越低。- 以及未来谷歌新系统 “Fuchsia” 的发布与加持。如果谷歌未来的新系统 Fuchsia 能应用到移动端,并且领域替代 Android 。
- 由于Fuchsia的上层是
Flutter
编写的,因此Flutter
开发成为了移动端领域的必选项
3.Flutter的诞生
每一个技术的诞生都是
为了解决一些现有的问题
我们回顾一下,在前面提及了,为了解决原生开发
的一些痛点(如开发成本
、动态化
等),至今为止,先后出现了不少跨平台技术方案;
- 根据其原理,大概出现过三种:
- ①、WebApp
- ②、类RN技术
- ③、Flutter技术
Flutter
技术的出现解决了
- 开发效率:
- 支持JIT即时编译,写完即时渲染;
- 编写一份代码,编译后多端运行
- 渲染
效率
- 不存在
JavaScriptCore
VM
的解释器过程- 结果|
多端一致性
:
自带渲染框架Skia
,不同渠道的渲染结果 相近- ......
二、Flutter概述
1. Flutter的特性与应用场景
1.1 Flutter是什么?
对上面的话进行总结:
Flutter
是Google
推出并开源的移动应用UI开发框架
,主打跨平台
、高保真
、高性能
- 开发者可以通过
Dart
语言开发 App,一套代码同时运行在iOS
和Android平台
Flutter
提供了丰富的组件
、接口
,开发者可以很快地为 Flutter 添加Native 扩展
- Flutter是一个
UI SDK
(Software Development Kit) - 可以进行移动端(
iOS
、Android
),Web端(Beta),桌面(technical preview),跨平台解决方案 - 移动端目前已经很多公司在用,Google、阿里、腾讯
- 特别是阿里的闲鱼团队,为
Flutter
做了非常多的贡献 Flutter
它是有一统大前端的野心的,并且它正在侵蚀iOS
、Android
这些原生开发
1.2.Flutter开发
1.3.Flutter的特点
Google公司在国内做过很多宣讲,其中多次提到Flutter的几个特点:美观
、快速
、高效
、跨平台
、开放
;
1.) 美观:
- 使用
Flutter
内置美丽的Material Design
和Cupertino widget
(什么是widget,不着急) - 丰富的
motion API
- 平滑而自然的滑动效果和平台感知,为您的用户带来全新体验
2.) 快速&&高效:
- 快速:
Flutter
的 UI 渲染性能很好- 在生产环境下,
Flutter
将代码编译成机器码执行 - 并充分利用
GPU
的图形加速能力,因此使用Flutter
开发的移动应用即使在低配手机上也能实现每秒 60 帧的 UI 渲染速度。 Flutter
引擎使用C++
编写- 包括高效的
Skia 2D
渲染引擎 Dart
运行时和文本渲染库
- 包括高效的
- 高效:
- 基于
JIT
的快速开发周期:Flutter 在开发阶段采用,采用 JIT 模式,这样就避免了每次改动都要进行编译,极大的节省了开发时间;Hot Reload
(热重载),在前端已经不是什么新鲜的东西,但在移动端之前一直是没有的
- 基于
AOT
的发布包: Flutter 在发布时可以通过 AOT 生成高效的机器码以保证应用性能。而 JavaScript 则不具有这个能力
- 基于
3.) 跨平台自绘引擎
Flutter
与用于构建移动应用程序的其它大多数框架不同Flutter
既不使用 WebView- 也不使用操作系统的原生控件
- 相反,
Flutter
使用自己的高性能渲染引擎来绘制Widget(组件)
- 这样不仅可以保证在
Android
和iOS
上UI
的一致性 - 也可以避免对原生控件依赖而带来的限制及高昂的维护成本
- 这样不仅可以保证在
Flutter
底层使用Skia
作为其2D 渲染引擎
Skia
是 Google的一个 2D 图形处理函数库- 包含
字型
、坐标转换
,以及点阵图
,它们都有高效能且简洁的表现
- 包含
Skia
是跨平台的,并提供了非常友好的 API,目前Google Chrome
浏览器和Android
均采用Skia
作为其2D 绘图引擎
- 目前
Flutter
已经支持iOS
、Android
、Web
、Windows
、macOS
、Linux
、Fuchsia
(Google新的自研操作系统)等众多平台
4.) 高性能
Flutter
旨在提供流畅、高保真的的 UI 体验。为了实现这一点,Flutter 中需要能够在每个动画帧中运行大量的代码- 这意味着需要一种既能提供高性能的语言,而不会出现会丢帧的周期性暂停,而
Dart
支持AOT
,在这一点上可以做的比JavaScript
更好 Flutter
使用自己的渲染引擎来绘制 UI ,布局数据
等由Dart
语言直接控制- 所以
Flutter
在布局过程中 不需要像 RN 那样要在 JavaScript 和 Native之间通信 - 这在一些滑动和拖动的场景下具有明显优势,因为在滑动和拖动过程往往都会引起布局发生变化,所以 JavaScript 需要和 Native 之间不停的同步布局信息
- 这和在浏览器中JavaScript 频繁操作 DOM 所带来的问题是类似的,都会导致比较可观的性能开销
- 所以
5.) 开放:
Flutter
是开放的,它是一个完全开源
的项目
6.) 快速内存分配:
Flutter
框架使用函数式流
,这使得它在很大程度上依赖于底层的内存分配器
- 因此,拥有一个能够有效地处理琐碎任务的内存分配器将显得十分重要,在缺乏此功能的语言中,
Flutter
将无法有效地工作 - 当然
Chrome V8
的JavaScript引擎
在内存分配上也已经做的很好- 事实上
Dart
开发团队的很多成员都是来自Chrome
团队的 - 所以在内存分配上
Dart
并不能作为超越JavaScript
的优势,而对于Flutter
来说,它需要这样的特性,而 Dart 也正好满足而已。
- 事实上
7.) 采用Dart语言开发:
Flutter
为什么选择了 Dart
而不是 JavaScript
?
我们先来了解一下之前提到过的两个概念:JIT
和 AOT
- 程序主要有两种运行方式:
静态编译
与动态解释
- 静态编译的程序在执行前程序会被提前编译为机器码(或中间字节码),通常将这种类型称为AOT (Ahead of time)即 “
提前编译
” - 而解释执行则是在运行时将源码实时翻译为机器码来执行,通常将这种类型称为JIT(Just-in-time)即“
即时编译
” - 同学们若是想了解一下 编译相关的知识,可以参考我的这篇文章:计算机编译原理-概述
- 类型安全和空安全
- 由于 Dart 是类型安全的语言
- 且 2.12 版本后也支持了空安全特性,所以
Dart
支持静态类型检测,可以在编译前发现一些类型的错误,并排除潜在问题 - 这一点对于前端开发者来说可能会更具有吸引力
- 且 2.12 版本后也支持了空安全特性,所以
- 与之不同的,
JavaScript
是一个弱类型语言- 也因此前端社区出现了很多给
JavaScript
代码添加静态类型检测的扩展语言和工具,如: - 微软的
TypeScript
以及Facebook 的Flow
- 相比之下,
Dart
本身就支持静态类型,这是它的一个重要优势
- 也因此前端社区出现了很多给
- 由于 Dart 是类型安全的语言
Dart
团队就在你身边-闲鱼- 看似不起眼,实则举足轻重
- 由于有
Dart
团队的积极投入,Flutter
团队可以获得更多、更方便的支持 - 正如
Flutter
官网所述我们正与Dart
社区进行密切合作,以改进Dart
在Flutter
中的使用 - 例如
- 当我们最初采用
Dart
时,该语言并没有提供生成原生二进制文件的工具链(这对于实现可预测的高性能具有很大的帮助),但是现在它实现了 - 因为
Dart
团队专门为Flutter
构建了它 - 同样,
Dart VM
之前已经针对吞吐量进行了优化,但团队现在正在优化VM
的延迟时间,这对于Flutter
的工作负载更为重要
- 当我们最初采用
2. Flutter绘制原理
快速了解Flutter的绘制原理
- 图像是如何显示的?
- 为什么看到的不是一幅幅图像?
- 帧率和刷新率的关系
- 双重缓存(Double Buffer)
- 双重缓存存在的问题
- 了解三重缓存(Triple Buffer)
- Flutter绘制原理图
- 渲染引擎skia
如果你感兴趣,想更深入了解Flutter的绘制原理,可以参考我的这篇文章: Flutter页面渲染原理
三、了解移动大前端的其它技术方案页面渲染原理
1. 计算机图形渲染原理
2. iOS图层渲染原理
- 03-iOS底层原理|iOS的各个渲染框架以及iOS图层渲染原理
- 04-iOS底层原理|iOS动画渲染原理
- 05-iOS底层原理|iOS OffScreen Rendering 离屏渲染原理
- 06-iOS底层原理|因CPU、GPU资源消耗导致卡顿的原因和解决方案
3. Web技术相关专题
4. Android图层渲染原理
四、搭建Flutter开发环境
1. 操作系统选择
2. 在 macOS
上搭建 Flutter
开发环境
- 注意:随着
Flutter
的升级可能会发生变化,如果下面介绍的内容在您安装Flutter
时已失效,请访问Flutter
官网,按照官网最新的安装教程安装 - 由于
Flutter
会同时构建Android
和iOS
两个平台的发布包,所以Flutter
同时依赖Android SDK
和iOS SDK
,在安装Flutter
时也需要安装相应平台的构建工具和SDK
1.) 安装Flutter SDK
-
- 去Fluttr官网下载其最新可用的安装包,官网地址:docs.flutter.dev/development…
- 2.解压安装包到我们自己想安装的目录,如:
cd ~/development unzip ~/Downloads/flutter_macos_v0.5.1-beta.zip
- 3.添加
flutter
相关工具到path
中:export PATH=`pwd`/flutter/bin:$PATH
- 此代码只能暂时针对当前命令行窗口设置
PATH
环境变量,要想永久将Flutter
添加到PATH
中请参考下面更新环境变量 部分
2.) 配置镜像:
- 由于在国内访问
Flutter
有时可能会受到限制,Flutter
官方为中国开发者搭建了临时镜像,大家可以将如下环境变量加入到用户环境变量中:export PUB_HOSTED_URL=https://pub.flutter-io.cn export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
- 此镜像为临时镜像,并不能保证一直可用,读者可以参考flutter.dev/community/c… 以获得有关镜像服务器的最新动态
- 在masOS下可以同时进行Android和iOS设备的测试
- 系统要求
- 要安装并运行Flutter,开发环境必须满足以下最低要求: 操作系统:
macOS (64-bit)
- 磁盘空间:
700 MB
(不包括Xcode
或Android Studio
的磁盘空间). - 工具:
Flutter
依赖下面这些命令行工具
bash
、mkdir
、rm
、git
、curl
、unzip
、which
- 要安装并运行Flutter,开发环境必须满足以下最低要求: 操作系统:
3. 检查Flutter环境安装情况
flutter doctor
- 该命令检查你的电脑环境并在终端窗口中显示报告。
Dart SDK
已经在捆绑在Flutter
里了,没有必要单独安装Dart
。- 仔细检查命令行输出以获取可能需要安装的其他软件或进一步需要执行的任务(以粗体显示)
- 一般的错误会是
xcode
或Android Studio
版本太低、或者没有ANDROID_HOME
环境变量等,请按照提示解决。下图是我自己用命令检测的结果,打钩的就是没有问题的,打叉的就是缺少或者是版本有问题的- Flutter doctor报错
Checking Android licenses is taking an unexpectedly long time...
解决方法:
- 打开工具菜单,SDK管理器
- 选择安卓SDK栏目,顶部选择SDK Tools,选中'Android SDK Command-line Tools'选项,点击OK进行安装
- 终端输入下面命令,出现提示全部输入y即可
flutter doctor --android-licenses
- Flutter doctor报错
- 此时再输入
flutter doctor
,依然报了一个警告:[!] Proxy Configuration ! NO_PROXY is not set
- 解决方法:在终端输入:
export NO_PROXY=localhost,127.0.0.1,::1
开启模块
- flutter config --enable-web
- flutter config --enable-macos-desktop
- flutter config --enable-windows-desktop
关闭模块
- flutter config --no-enable-web
- flutter config --no-enable-macos-desktop
- flutter config --no-enable-windows-desktop
4. 配置iOS
环境
5. 配置Android
环境
6. 开发工具选择
7. Android Studio
8. 在Windows上搭建Flutter开发环境
我没有Windows电脑,需要搭建Windows系统的Flutter环境,需要按照官网的指引文件来操作:docs.flutter.dev/get-started…
五、创建Flutter
项目
1. 创建项目
有两种方式创建Flutter应用:
- 通过终端命令行
- 通过编辑器(
VS Code
)/IDE(Android Studio
)
1.1 命令行 创建项目
这里我先选择通过终端(Windows和macOS都是一样的命令
检查本地Flutter环境
在flutter
新建项目之前,我们先检查一下自己的flutter
环境是否有问题:
flutter doctor
从命令的运行来看,是没有任何的错误❌,说明flutter
的环境是 OK 的
创建项目
flutter create 项目名
# 示例:
# flutter create hello_flutter
# 注意:后面的名称不能由特殊符号,也不能由大写
我们尝试用flutter create helloFlutter
命令来新建一个项目工程吧!
从报错信息来看,是我们的项目名称
出了问题,
合法项目名称
helloFlutter" 不是有效的 Dart 包名称
why ?
大大的问号,这个名称没有问题啊,为什么就不支持呢?因为我们习惯了驼峰命名
但是 Dart
是不支持驼峰命名
的!既然不支持驼峰命名,那么就换个名称(helloflutter)吧!
新建项目成功
那么就按照提示,cd helloFlutter
打开项目目录,flutter run
把项目跑起来看看吧!
1.2 运行flutter 项目open
第一次运行有点慢,会对环境进行一下检查,之后运行就会快很多了。
- 第一次运行完成之后,会有如下提示:有一下运行的时候,还有一些快捷键的使用!
- 在模拟器中运行的界面如下:
flutter
工程文件结构如下:
目录里面安卓
和 iOS
工程都有,一份代码,多端使用👍🏻!
运行效果
1.3 xcode 打开 flutter 工程
因为 flutter
是跨平台的,里面包含了安卓
和 iOS
工程,我们双击打开iOS
工程就可以了,默认生成的是 Swift
的工程。
打开 iOS
工程如下所示:
Xcode
运行iOS
工程如下所示:
默认
ios
是Swift
的工程,安卓
是kotlin
,我们也是可以去修改创建的工程语言的,使用flutter create --help
命令就可以查看
那么现在就去创建一个 OC
的工程吧,使用flutter create -i objc flutter_objcdemo
命令。
提示
:我们都是使用
Xcode
去签名/真机调试,不会使用Xcode
去写flutter
,它也不支持dart
语言啊!
1.2 Android Studio 新建项目
Android Studio
新建项目
Android Studio
新建flutter
项目
点击➕
创建 flutter
项目,进入如下界面
填写项目名称,项目的语言,支持的平台等!(这里我就不新建了,我就直接打开之前的项目了!)
目录结果和文件夹中的是一样的,顺序几乎都是一样的,我们在 lib
文件夹下面写 dart
代码。
可以下拉选择模拟器运行项目
在终端中也是打开模拟器open -a Simulatoer
,如果有多个模拟器会提示选择一个来运行项目,如下图所示:
选择其中一个模拟器来运行 flutter
项目
1.3 VS Code 新建项目
打开VS Code命令面板
Cmd + shift + p(或者View>Command Palette ...)
输入 Flutter: New project
选择并输入项目名称回车,选择存放路径
便初始化了一个flutter demo工程。
2. 项目跑在模拟器
通过一个你喜欢的开发工具打开(我这里暂时选择Android Studio)
选择你要启动的设备,点击 运行 按钮:
我把项目运行在了两个模拟器上
3. 体验Flutter热重载
对于我们开发测试阶段,如果每次修改代码都需要重新编译整个项目再加载的话,那每次可能都需要花费10秒左右甚至是几分钟的时间(电脑太慢的话),这样的开发效率是非常低的。
现在前端开发都支持热重载(Hot Reload),可以大大加快我们的开发效率。
- 热重载可以在无需重新编译代码、重新启动应用程序的情况下,看到修改后界面的效果
Flutter在开发阶段使用JIT编译模式(后面我会讲解什么是JIT模式),所以可以做到热重载来提高我们的开发效率
下面我们体会一下热重载,后面有时间我们来分析热重载是如何实现的 将下面红框中的内容改成Hello Flutter,保存一下应用程序
- 你会发现在不到1秒钟内,界面直接发生了刷新
- 并且没有应用程序没有进行任何的重新,效率非常高
如果热重载不起作用,我们也可以点击右上角的 Hot Restart,并不需要重新运行项目
4. 工程目录分析
Flutter工程创建完毕会感觉比较复杂,我们来看下图:
目录包含哪些东西呢?
- 其中包含Flutter开发和测试需要的lib、test,在开发过程中,我们主要使用的就是lib目录
- 另外一些是管理项目的配置文件信息等,当然也包括一些Git相关的文件
- 除此之外,还包括一个Android子工程和iOS子工程
为什么包含Android子工程和iOS子工程呢?
-
这是因为作为一个跨平台的开发方案,最终还是要嵌入到Android工程或者iOS工程中来运行的
-
并且在开发过程中也需要调用原生的一些功能