前端 Flutter 劝退指南:不是谁都可以学~

2019-09-1809:29:42APP与小程序开发Comments5,950 views字数 10988阅读模式

作者:陈微语文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

什么是 Flutter

首先,什么是 Flutter?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

官网解释:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Flutter是一款 Google 开源的 SDK,可跨平台地为移动端,Web 端,桌面端构建高性能的应用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

当然,当然,虽说是Web端桌面端都能开发,但是我们更多地会着重于 flutter 的移动端跨平台开发功能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

那么,在 flutter之前,其实就有很多跨平台开发的框架了,知名的有 C# 的 Xamarin, 用 js 的有 nativescript ,阿里的 weex 以及大家都比较熟悉的 react native,那么名气不大的就更多了文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

前端 Flutter 劝退指南:不是谁都可以学~

所以,flutter 在一堆跨平台开发框架中凭什么脱颖而出呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

为什么用 Flutter ?

前端 Flutter 劝退指南:不是谁都可以学~
  1. 低投入高产出
    一套代码,直接产出 Android + iOS 两个平台的应用。 这是跨平台开发框架的共同优势,不再多说。
  2. 高效率开发
    通过 Flutter 的 JIT(Just In Time)即时编译功能,能提供 Hot Reload 功能,快速开发应用。有没有 Hot Reload 的开发效率高低,这点前端同学应该是深有体会了。
  3. 丰富优雅的UI
    框架本身提供 Material Design 以及 Cupertino 的两种画风的 UI 组件,不局限于系统本身 OEM 的限制。
  4. 高性能应用
    和原生一样的性能。Flutter 的 AOT 将代码编译成 ARM 二进制,用自身的 自绘引擎(Skia),没有 Bridge 依赖,可直接访问系统底层服务。这些能让 Flutter 性能毫不逊色于 原生应用。

前面的这些都是其次,最关键的是什么呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Flutter 有个好“爹”!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

大家琢磨一下,当下的主流的三大前端框架,react、react native 是 facebook 的,angular 又是 google 的,只有 vue 是没有大公司背景。事实上社区的很多开源框架,其实都是大企业内部孵化出来的。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

有个好爹,背靠 Google 爸爸,含着金钥匙出生,一看就前途不可估量。框架的稳定性和成长性就能得到一定保证,给开源社区信心。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

这就是,拼爹一时爽,一直拼一直爽。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

言归正传,这里提到 flutter 能不局限于系统 OEM,以及相比其他跨平台框架提供更优秀的性能,那么凭啥就 flutter 那么秀呢?我们可以从 flutter 框架结构上去探索一下。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Flutter 框架结构

flutter 的框架结构图如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

前端 Flutter 劝退指南:不是谁都可以学~

好了,相信大家不只一次看到这一张图了。 懂的可能已经了然于胸,不懂的可能还是一脸懵逼。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

这里还是简单说下文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

从上往下看, 首先是 Framework,Framework 是用 dart 语言写的,从上往下, 1. 有封装好的 UI 组件 Material 和 Cupertino 【相当于前端的 Ant-Design / Element / iview 等 UI 框架】 2. 封装好的 UI 组件 Material 和 Cupertino 由更基础的 Widget 组件拼装而成。 【这里的 Widget 相当于 前端的 HTML div, h1, span 等标签元素】 3. 继续往下, Widget 层是由 Animation(动画), Painting(绘制), Gesture(手势) 共同通过 Rendering 构成的 对象。【这里和前端稍稍有点区别,前端 UI 的结构(html),样式(CSS),事件交互(JS 是分开的,而在 Flutter ,都是 Widget】文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Framework 往下是 Engine, Framework 中的 UI 交互都是有 Engine 来进行绘制渲染的。Engine 层内部会通过 Skia 图形引擎画出 UI 组件,Skia 是 Google 开源的 2D 图形引擎,适用于多个平台系统,这也是 flutter 能跨平台的核心元素之一。这也是为什么前面说 flutter 能不局限系统 OEM 组件的限制。 也就是说,如果你想要自己封装一个 ant-design 画风的 flutter UI 框架,你可以直接通过基础的 Widget 搭建出自己的 UI 框架。如果底层基础 UI 满足不了你的需求。你可以直接用 dart 调用 Skia 图像引擎的 API,画出自己的 UI,没有任何的限制。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

最后是 embedded,嵌入层,这一块是处理平台差异性的事情,从而能够把 flutter 应用嵌入到各个系统平台。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

可以看到 Flutter 没有用原生系统上的 OEM,而是用 2D 渲染引擎 skia 直接渲染绘制 UI, 这使得其平台相关层很低,平台只是提供一个画布,剩余的所有渲染相关的逻辑都在Flutter内部,这就使得它具有了很好的跨端一致性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

以上就是 flutter 跨平台开发的结构了, 那么这样设计的优越性在哪呢?我们可以对比下其他应用开发的架构。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

跨平台架构对比

Native

首先我们来看下原生APP开发的架构设计,一般一个 App,会分为两大块,分别是 UI 渲染和系统服务调用,我们常说的跨平台开发,其实就是跨的这两块。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

前端 Flutter 劝退指南:不是谁都可以学~

原生 App 的 UI ,会通过平台提供的原生 OEM 控件实现,文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

而系统服务调用,如相机,蓝牙等传感器的使用,也会通过平台系统提供的 API 来实现文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

那么这就会粗线一个问题,不同平台的 OEM 控件和 系统服务调用规范,以及编程语言不统一,Android 使用 Java / Kotlin,而 iOS 使用 Objective-C / Swift,这就产生了平台差异性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

一个 app 要开发几套代码,UI 效果还不一定能保持一致,费时费力。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

于是,就产生了跨平台开发的需求。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

我们来看下常见的跨平台架构文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Webview

前端 Flutter 劝退指南:不是谁都可以学~

首先最常见的跨平台方案,是直接用 webview ,这其实就是我们常说的 hybrid app 了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

虽说不同平台的 webview 内核不一定一样,但是总归会遵循 w3c 规范, 那么我们的前端的代码可以运行在平台的 Webview 上,实现 UI 上的跨平台开发文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

而系统服务调用这一块呢,就通过 bridge 来通过协议来调用原生的方法。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

那么 hybrid app 的方案缺点也是很明显的, webview 性能比不上原生文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

为了解决这个 webview 的性能问题,社区又推出了另外一种方案文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

React Native / Weex

前端 Flutter 劝退指南:不是谁都可以学~

如图所示,React native ,Weex 等框架,是用前端语言描述系统 OEM 之类 实现跨平台,简单的来说,是通过写 js 配置页面布局,然后通过 react native 解析成原生的控件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

这样的做法,就明显提高了性能,因为实质上渲染出来的,还是原生的控件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

但是,即便性能提高了,但是依然达不到原生的层次,因为 RN 是通过 Jscore 解析 jsbunder 文件布局,和原生直接布局还是有那么一丁点差距的。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

另外,使用 react native 并不能避免写原生的代码,如果遇到一些平台相关的复杂问题,还是不得不深入到原生库中进行必要的调整。去年 Airbnb 就因为类似的原因放弃了 rn。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

那么,用 flutter 就能避免这个问题了么?我们来看下 flutter 的架构文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Flutter

前端 Flutter 劝退指南:不是谁都可以学~

前面其实也说过了,flutter 的 UI 渲染是基于 skia 图像引擎完成的,不依赖任何一个系统平台,平台仅仅提供一个画布,让 图像渲染在画布上。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

那么直接越过原生的渲染机制,从自身的渲染引擎去渲染视图,这就和原生一模一样,没有了中间商赚差价。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

两者的渲染性能也提升为了 两者的渲染引擎之间的比较。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

至此,我们比较了几种跨平台架构的 UI 渲染实现,文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

那么关于系统服务的调用呢?Flutter 并没有消除 跨平台 系统服务调用的问题,因为硬件设计层面以及编程语言的差异性是客观存在的,基本无法避免。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

但是不同于之前几种用 bridge 的方式来调用系统服务,flutter 用 Platform channel 的形式去调用系统服务,这里先跳过,下面的章节会详细讲一下这里的通信机制文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Web VS Flutter

开发语言

前端 Flutter 劝退指南:不是谁都可以学~

不同于 Web 把页面分成了 HTML,CSS,JS, 在 Flutter 中,所有东西都是 widgets 具体 widgets 类型分为:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

  • - 元素 widget。 如 button,menu,list
  • - 样式 widget。如 font,color
  • - 布局 widget。 如 padding,margin
  • - ...

所有的 widget 嵌套组合在一起,就构成了一个 flutter app。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

UI 语法

基本样式

关于样式语法,前端的代码我们很熟悉了,用 HTML 和CSS 能快速实现一个简单的 UI。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

我们来看看一个最基本的盒子模型:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

<div class="greybox">
    Lorem ipsum
</div>
<style>
.greybox {
  background-color: #e0e0e0; /* grey 300 */
  width: 320px;
  height: 240px;
  font: 900 24px Georgia;
}
</style>
var container = Container( // grey box
  child: Text(
    "Lorem ipsum",
    style: TextStyle(
      fontSize: 24.0,
      fontWeight: FontWeight.w900,
      fontFamily: "Georgia",
    ),
  ),
  width: 320.0,
  height: 240.0,
  color: Colors.grey[300],
);

在 flutter ,由于 Flutter 没有标记语言,我们需要嵌套一个个 Widget 类来实现我们的 UI,这里的 Container Widget类,其实就相当于 div 标签。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

那么看到这个代码风格,如果有写过 非 jsx 的 react 的话,你会发现代码风格有点像是 React.createElement 的画风。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

React.createElement("div", {
    class: "test-c",
    style: "width: 10px;"
}, "Hello", React.createElement("span", null, "world!"));

布局

实现一个 UI ,第二个比较重要的点是布局, 在 Web 前端,实现布局的核心要点是 CSS 的属性:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

<div class="greybox">
  <div class="redbox">
    Lorem ipsum
  </div>
</div>
<style>
.greybox {
  background-color: #e0e0e0; /* grey 300 */
  width: 320px;
  height: 240px;
  font: 900 24px Roboto;
  display: flex;
  align-items: center;
  justify-content: center;
}
.redbox {
  background-color: #ef5350; /* red 400 */
  padding: 16px;
  color: #ffffff;
}
</style>

而在 flutter,则需要一些官方提供的样式类来实现,例如这里的 BoxDecoration 类来修饰整个盒子,Alignment 确定文本对齐方式等等文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

var container = Container( // gray box
  child: Center(
    child:  Container( // red box
      child: Text(
          "Lorem ipsum",
          style: bold24Roboto,
          textAlign: TextAlign.center,
        ),
        decoration: BoxDecoration(
          color: Colors.red[400],
        ),
        padding: EdgeInsets.all(16.0),
      ),
      alignment: Alignment.center,
  ),
  width: 320.0,
  height: 240.0,
  color: Colors.grey[300],
);

交互

Web:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

<input name="account" />
<div onclick="handleSubmit()">Submit</div>

最后一点是交互,类似于大部分的前端 UI 框架,每个组件其实都会暴露出一些事件钩子,文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

通过这些钩子,我们就可以捕获到用户的行为,从而实现对应的逻辑,文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

这里的 demo 就简单实现了 输入校验, 按钮的点击提交等基本的交互。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Flutter:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

// ...
children: <Widget>[
  TextFormField(
    decoration: InputDecoration(
        hintText: 'Email/Name/Telephone',
        labelText: 'Account *',
      ),
      onSaved: (String value) {
        loginForm.account = value;
      },
      validator: (String value) {
        if (value.isEmpty) return 'Name is required.';
      }
  ),
  RaisedButton(
    child: Text(
      'Login'
    ),
    onPressed: () {
      // print('提交操作');
      // dosomething with loginForm
      handleSubmit()
    },
  ),
]

其余的还有 路由,动画,手势等交互,这里不再多说,基本上能用 Web 技术实现的,大都能够在 flutter 实现文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

可以看到,flutter 的 UI 部分除了没有 jsx 之外,其余部分的设计思想与 react 大同小异。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

那么简单介绍完语法,我们来实际操作看看,怎么写一个 APP文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

开始一个 Flutter App

首先怎么安装 flutter 开发环境这个就不多说了,官网教程教程已经很完善了文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

目录结构

简单说下目录结构,通过 flutter 创建出一个工程后,会自动生成这样的目录结构,文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

.
├── android         # Android 平台配置,flutter 自动生成
├── ios             # iOS 平台配置,flutter 自动生成
├── assets          # 静态资源目录
├── build           # 存放构建出的 release 相关文件
├── lib             # 业务代码
├──  └── main.dart  # app 入口
└── pubspec.yaml    # 包管理文件

Hello World

上手一个框架,当然要来一个经典的 Hello World。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

要实现一个 flutter app, 我们需要 加载 flutter 的基本组件 import 'package:flutter/widgets.dart';, 然后执行基本的 runApp , 那么一个基本的 hello world 就完成了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

// main.dart 文件
import 'package:flutter/widgets.dart';

void main() {
  runApp(
    Center(
      child: Text(
        'Hello, world!'
      ),
    ),
  );
}

效果如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

前端 Flutter 劝退指南:不是谁都可以学~

可以看到,如果没有样式的话,应用就是一坨黑....文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

就像在前端开发时我们喜欢使用的 ant design 或者 iview 之类的 UI 框架,开发 flutter 一般也会用 UI 框架文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Material App

Flutter 内置两套 UI 组件,分别是 Material UI 和 Cupertino UI,文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

现在简单看下一个 material 风格的APP是怎么实现的, 首先 import material 组件文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

new 一个 MaterialApp 组件,配置 title, app bar 等信息,就简单地生成了个 material 画风的 app 了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

import 'package:flutter/material.dart';
void main() {
  runApp(
    MaterialApp(
     title: 'Hello App',
     home: Scaffold(
       appBar: AppBar(
         title: Text('Hello'),
       ),
       body: Center(
         child: Text(
           'Hello Flutter',
           style: TextStyle(
             fontSize: 30
           ),
         )
       ),
     ),
   )
  );
}
前端 Flutter 劝退指南:不是谁都可以学~

更复杂的还可以在这里配置路由相关信息,这里就不再多说。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

通过这些我们知道怎么实现一个 flutter app,那么看到所有有实体的元素,都是称为 Widgets, 这里为了方便理解,我们统称为组件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Widgets

前端 Flutter 劝退指南:不是谁都可以学~

而组件又细分为 Stateless Widget 和 Stateful Widget,这里可以很容易联想到 react 的 无状态组件和 有状态组件文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

事实上 flutter 的这两种组件确实和 react 的差不多文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

我们首先看下 无状态组件(StatelessWidget)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

无状态组件 StatelessWidget

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Hello App',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Hello'),
        ),
        body: Center(
            child: Text(
          'Hello Flutter',
          style: TextStyle(fontSize: 30),
        )),
      ),
    );
  }
}
  • StatelessWidget 对应 react 的函数组件 Functional Component
  • 此处的 build 方法对应 react 的 render 方法

再来看看 状态组件(StatefulWidget)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

状态组件 StatefulWidget

Flutter 的状态由两个类组成: 分别是 StatefulWidget 和 State 类。 写法虽然不同,但是概念都大同小异:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

  • StatefulWidget 对应 React.Component
  • StatefulWidget 类管理父组件传递的 Prop
  • State 类中管理自身的 State
  • 通过 setState 更新状态
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Counter App',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Counter'),
        ),
        body: Center(
            child: Counter(10) ),
      ),
    );
  }
}


class Counter extends StatefulWidget {
  // 这个类是 state 的配置,可以在此定义父组件传递下来的 prop
  final int increaseNum;
  // 构造函数
  Counter(this.increaseNum);

  @override
  _CounterState createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int _counter = 0;

  void _increment() {
    print('count: $_counter');

    setState(() {
      // setState 的回调告诉 flutter 去变更 当前 State, 并且 setState() 的调用会触发 build() 从而更新视图
      _counter += widget.increaseNum;
    });
  }

  @override
  Widget build(BuildContext context) {
    // 每次调用 setState 都会触发 build 方法,同时,类似于 react 的 render 方法,
    // flutter 框架为了让 重新 build 更加快,也已经对此做了优化
    return Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.center,

      children: <Widget>[
        RaisedButton(
          onPressed: _increment,
          child: Text('Increment'),
        ),
        Text('Count: $_counter'),
      ],
    );
  }
}

学过 React 的同学,是不是对此有种似曾相识的感觉呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

生命周期

组件出来了,生命周期还远么?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

类似 React ,Flutter 也有自己的组件生命周期:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

  • - initState: 初始化状态
  • - didChangeDependencies: state依赖关系变更
  • - build: 构建视图
  • - didUpdateWidget: 状态变更,重新渲染视图
  • - deactivate: ui 组件被暂时移除(如切换页面)
  • - dispose: ui 被永久销毁
前端 Flutter 劝退指南:不是谁都可以学~

到此我们的 UI 组件部分就告一段落。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

跨平台开发,“跨” 的除了平台 UI 部分外,还有跨了前面提到的平台系统服务调用文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Native 服务调用

不管是哪一个跨平台开发的解决方案,基本上都是在UI层面去完成跨平台,一次开发运行多处,但是当你需要完成特定的功能时,比如:打开相册获取照片,这在这一层面上就无法撼动了,你依然需要使用 Native 的方式来完成。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

例如 h5 本身是无法调用系统底层 API 的,在 h5 我们就会用到 jsbridge 来给 native 发送命令,从而让 native 调用系统 API。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

而在 flutter, 官方提供了一些插件(plugins packages)来实现常用的功能,例如:本地图片选择,相机功能等,让我们能够简单直接地使用到不同平台的系统接口。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

这里也提供了一个唤起相机的 demo :文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

import 'package:image_picker/image_picker.dart';

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  File _image;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Picker Example'),
      ),
      body: Center(
        child: _image == null
            ? Text('No image selected.')
            : Image.file(_image),
      ),
      // 点击按钮进行拍照
      floatingActionButton: FloatingActionButton(
        onPressed: getImage,
        tooltip: 'Pick Image',
        child: Icon(Icons.add_a_photo),
      ),
    );
  }


  Future getImage() async {
    // 打开相机拍摄,并获得图片资源
    var image = await ImagePicker.pickImage(source: ImageSource.camera);

    setState(() {
      _image = image;
    });
  }

}

那么 插件是怎么调用 系统服务的呢?这里就需要用到 flutter 的 methodchannel / platform channel 通信机制。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Native 服务调用-实现自己的 Flutter Plugin

前端 Flutter 劝退指南:不是谁都可以学~

如图所示,flutter 通过 methodchannel 机制来调用不同平台 native 层的 api。由于代码最终会被编译成机器码,所以这个调用过程基本上和原生调用差不多,都是无损的,不像通过 bridge 方式调用,需要协议转化。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

要自己实现一个 底层服务调用的 FlutterPlugin,可以参考官方文档,简单来说步骤如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

  1. 定义 plugin package 的 API
  2. 实现不同的底层逻辑
    1. - Android 平台的功能实现 (Java / Kotlin)
    2. - iOS 平台的功能实现 (Object-C / Swift)
  3. 在 dart 使用 method channel 调用原生 api

劝退

看了那么多,是不是感觉这不像劝退,而是一篇 Flutter 吹文?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

别急,这就劝退了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

Flutter 虽然看起来很强大,但是实际上深入琢磨一下,其实也有不少局限性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

国内环境复杂,小程序横行

大家都知道,国内的流量几乎都被几个大公司垄断, 而 App 的推广下载成本也很高。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

所以各大公司才推出了五花八门的小程序,到目前为止,已知的有:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

微信/百度/支付宝/字节跳动/ QQ 小程序以及快应用等......文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

为了快速引流,考虑投入产出比,小公司更愿意会用 小程序/快应用/H5 方案,而不是用获客成本更高的 App 方案。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

例如京东的 taro 框架或类似的跨端小程序开发框架,就比 Flutter 更加符合中国特色。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

taro 是一个多端统一开发框架,支持用 React 的开发方式编写一次代码,生成能运行在微信/百度/支付宝/字节跳动/ QQ 小程序、快应用、H5、React Native 等的应用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

放弃了 Web 生态

大家可以看到,整篇下来,除了 react-style 的设计思想之外,flutter 和前端其实关系不大文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

江湖传言道:一切能用js实现的应用,都将用js实现。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

但是很可惜的是,基于各方面的考虑,google 选择了 dart 这门并不算热门的语言作为 flutter 的开发语言,而不是 JavaScript / Typescript。给前端开发接触 flutter 设置了一定的门槛。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

但是,flutter 也不是只给我们前端用的,站在前端角度,我们当然希望用 js/ts咯。 但这对于 Android/ios 等终端开发来说,其实也是同样需要一定的成本,可以算是一视同仁了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

社区活跃度欠缺

那么又由于 dart 语言这两年才被 flutter 带起来的缘故,之前一直火不起来,直到 flutter 出来后才强行续命。至此 dart 的社区生态,开源库等等都比较欠缺,不像前端社区,有丰富的 npm 包。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

那么,大家可以想下,在 flutter 之前,你有听过 dart 语言么?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

google 为什么用 dart 作为 flutter 的开发语言呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

其实是因为…… dart 也有个好爹 Orz,他的爹也是Google。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

看到没有,有个好爹多么重要,三线语言 dart 这不就被捧得大红大紫了么[滑稽]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

纯前端的局限性

flutter 用自绘引擎彻底解决了 UI 层面的平台差异性,但是前面也提到了,系统硬件服务(如相机蓝牙等服务)的差异性是无可避免的。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

作为一个纯前端来说,理想情况下,用 flutter 可以完成所有原生能实现的功能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

但现实往往是不理想的,跨端开发往往会遇到一些平台相关的问题,如 flutter plugin的相机拍照 ,在某个型号的安卓设备上有点小bug。如果你是个纯前端,运气好的话能在开源社区找到解决方案,运气不好,只能向终端(iOS/Android)开发寻求技术支持。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

那么,还需要 iOS/Android 开发来兜底的跨端开发框架,还是一个跨端开发框架么?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

要开发一个成熟的 App,你敢放心交给纯前端用 flutter 负责么?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

当然,这并非是 flutter 弊端,而是所有跨平台方案共同的问题。要是没这问题,react native 早就一统江湖了,airbnb 也不至于弃坑 react native了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

只要跨平台框架还存在需要程序员自行解决的平台差异bug,那么 纯前端程序员全盘负责移动端开发 就是个伪命题。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

前端 Flutter 劝退指南:不是谁都可以学~

那么,是不是 flutter 就与前端绝缘了呢? 也并非如此。 如果你要开发一个重 UI 展示 ,调用系统服务比较少的简单应用,那么 flutter 是个不错的选择。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

总结

事实上,可以看出,最适合用 flutter 的是哪些程序员呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

既会 iOS 开发,又懂一些 Android 开发,这不需要太精通, 能搜索解决常见终端问题即可的程序员。那么学 flutter 就是如虎添翼了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

如果真的有前端有志于做一名 flutter 开发工程师,那么不妨简单学习下 Android 和 iOS 开发。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

互联网寒冬什么人才最吃香?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

多面手,综合性人才,爆栈工程师...文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

劝退完毕。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html

文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16521.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/xcx/16521.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定