在2018年8月,Flutter成为Stack Overflow上最受欢迎的跨平台技术。

在我们的博客上,来自Google认证的代理机构Surf的 Artem Zaitsev和Evgeny Saturov将解释其发生原因和发生方式:
长期以来,跨平台解决方案吸引了那些想要在多个平台上同时快速廉价地发布MVP产品的人们。 原因很简单-单一代码库。 易于维护:工件是集中的,每个平台都没有重复的逻辑和对相同bug的编辑。 人们需要更少的支持和创建它-无需维护两个本地开发人员。
由于技术实施的细微差别,现有的框架要么很复杂,要么效率不高,或者存在很多错误。 在他们的帮助下,人们努力快速获得最低限度的功能,最终注定要长期重写项目。
很快,Google的新移动开发框架Flutter的最终版本有望成为Stack Overflow上最需要的跨平台技术。 我强调它是专门为移动应用程序设计的,涵盖两个平台:Android和iOS。 目前, 发布了Release Preview 2版本。 Flutter上的新项目属于一个特殊的集合 ,其目的是展示框架的功能。 现在,借助开发人员社区(例如Redux的实现),使用组件和体系结构附件积极地更新了框架。

为什么您需要相信Flutter?
进行快速开发的绝佳调整
您不必离开通常的Android Studio。 使用该插件,它可以完美适应Flutter应用程序的开发。
热重装是一项杀手级功能,可让您立即将所有更改从代码转移到正在运行的仿真器或连接的设备上。

布局的简洁性和表现力
如果您曾经开发过适用于Android的应用程序,那么我敢肯定您不会喜欢布局。
颤振是不同的。 首先,没有带有排版的XML文件-窗口小部件是直接在代码中创建和配置的(有点让人想起Anko Layouts)。 代替视图,使用窗口小部件。
new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Padding( padding: EdgeInsets.all(16.0), child: Text( '$_name', ), ), //...
这就是Flutter项目代码的外观。 刚开始,大量的括号吓到了,但是这样的“树”是很漂亮的。 Flutter促进了构图:通过现成的小部件,您可以像设计师一样制作新的小部件。 几乎每个组件都有一个child或children属性,分别接受另一个元素或元素数组。 一切都简单明了。 您可以足够快地创建漂亮的用户界面。
其次,从一开始,平台的创建者就为开发人员提供了现成的小部件目录 。 它包含两组元素,即“材料组件”和“库比蒂诺”,它们看起来对每个平台都是原生的。 跨平台的小部件也可用。 它们的外观和行为在iOS和Android设备上相同。

反应框架
您不仅可以使用大量现成的小部件,还可以使用必须使用的语言来在短时间内创建一个美丽而令人愉悦的UI。 Dart远程类似于Java,JavaScript,C#。 它表现力十足,并且完全适合框架的需求,尽管在Kotlin之后,某些艺术语法上的过分会变成轻巧的木马。
Flutter被编译为每个平台的本机代码。 “深入了解”,他将Skia用作图形引擎。

系统体系结构的关键功能是所有小部件以及负责在画布上渲染小部件的组件都是应用程序的一部分,而不是平台的一部分。 无需上下文切换和使用“桥”就可以提高性能,这有助于在呈现UI时实现60 FPS的珍贵数字。
该平台的全部功能仍在您手中
为什么要放弃在移动社区使用了十年的大量有用代码? 本机SDK应用程序和平台API中可用的所有库均可用于Flutter应用程序。

环境设定
Flutter入门很容易。
在开发过程中,官方文档建议使用带有适当插件的Android Studio,IntelliJ或VSCode,但任何文本编辑器都可以。
第一步
从适用于您的操作系统的官方网站上的Flutter SDK下载档案。 解压缩到所需目录并运行flutter doctor
命令。 此命令将检查是否已安装所有必需的组件,以及已安装的IDE的插件是否存在(例如,在安装Android Studio时,该实用程序将为其检查插件)。
第二步
如果一切顺利,则可以开始创建第一个项目。 如果发现错误,医生会告诉您如何解决。
第三步
要在Android Studio中使用Flutter ,您需要安装两个插件: Flutter和Dart 。 您可以通过打开设置并在搜索中选择必要的插件,以标准方式安装它们。
有关设置环境的详细信息,请参见官方文档 。
飞镖
import 'package:flutter/material.dart'; void main() => runApp(MyApp());
在Flutter应用程序上引起您注意的第一件事是一个不寻常的代码。 在Android开发领域中,使用Java,最近使用Kotlin。
现在符合他们的是Dart 。 Google凭借强大的输入,高性能和灵活性将其定位为JavaScript的替代品。
Dart语法很容易学习,尽管不如Kotlin的漂亮。 也许这是一个品味和习惯问题。
项目创建
您可以通过在控制台中运行flutter create name命令或使用IDE(在Android Studio-> New Flutter Project中)来创建项目。
应用结构
创建项目后,您将看到以下结构。 应用程序的根目录中有四个软件包-lib,ios,android和test。

第一个是框架目录。 所有dart文件和主要应用程序代码都位于此处。 尽管Flutter已编译为本机代码,但对于每个平台,都必须编写一些本机交互。 此外, Flutter可以集成到现有应用程序中。 有两个用于本机代码的软件包-ios / android,可以使用特定平台熟悉的语言进行编写-Obj-C / Swift或Java / Kotlin。 您将在测试包中找到测试。
根目录中有一个pubspec.yaml配置文件-库连接在那里,等等。 如果我们谈论类比,那么对于Flutter而言,它就像build.gradle(它也已经存在,但已经在Android本机部分中了)。
lib包可以分为其他包-使用和使用一种或另一种体系结构已经成为一种品味和渴望。 顺便说一下,要在Flutter上创建应用程序,将使用各种技巧,可以在此处查看。
您的项目将立即具有一个main.dart文件,其中包含带有示例的代码。 该应用程序具有单个入口点-main方法。 他负责创建根窗口小部件。
一切都是小部件
您在屏幕上看到(或看不到)的所有内容,与之交互以及应用程序本身的所有内容都是小部件。 任何用户界面实体都是小部件。 文本框,缩进或手势检测器-小部件。 应用程序是从它们作为构造函数构建的。
根据官方网站的说法,“每个小部件都是用户界面一部分的不变描述”。
例如,让我们用此屏幕构建一个应用程序:


此处提供以下小部件:
其中一些是在框架中实现的,有些则必须由成品本身组成。
窗口小部件有两种类型: Stateless
和Stateful
。 前者是静态的(例如,文本),后者支持状态更改(例如,屏幕)。
无状态
应用程序中此类小部件的示例是MyApp。 这是应用程序的根。 在内部,我们将使用build方法放置渲染所需的所有内容。
class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter Demo', theme: new ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( appBar: new AppBar( title: new Text("Flutter Random Name"), ), body: new MyHomePage(), ), ); } }
任何静态窗口小部件都是StatelessWidget
类的继承者。 您只需要覆盖build方法,并在其中收集必要的元素。 颤振促进成分。 要创建新项目,请勿展开现有项目。
在示例中,此小部件是从MaterialApp
(基于MaterialDesign组件的应用程序的根目录)构建的,其内部位于Scaffold
这是屏幕。
MyHomePage
还是一个小部件,可绘制屏幕的主体,但不包括AppBar
。 在这种情况下,它具有状态。 我们将在下面谈论他。
接口的构造是通过将类构造函数与参数的初始化传递给相应的字段而发生的。 Dart支持可选的方法参数,这提供了创建UI的灵活性。
注意:Dart中的new
(从第二个版本开始)是可选的。
通过这样的小部件布局,您可以得到一个静态的应用程序屏幕。 此外,开发人员的想象力是无限的。
有状态
状态小部件支持在状态更改时重绘( State
)。 要制作这样的小部件,必须从StatefullWidget
继承并创建一个继承类State<T>
,该类是小部件的状态,并负责用户在智能手机屏幕上看到的内容。
通过调用setState() {}
方法来setState() {}
窗口小部件的状态。 在内部,例如,您可以为按钮设置不同的背景色,框架本身将确定UI的最低必要重绘。
就我而言, MyHomePage
主页将是一个状态小部件。 它存储_name
(将在文本块中显示的名称)和_isLoading
下载_isLoading
(负责内部LoadingButton
小部件的呈现方式;通过父级进行状态控制的示例)。
class _MyHomePageState extends State<MyHomePage> { String _name = ""; bool _isLoading = false; @override Widget build(BuildContext context) => Center( child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Padding( padding: EdgeInsets.all(16.0), child: Text( '$_name', ), ), LoadingButton( isLoading: _isLoading, action: _generateName, ) ], ), ); }
该按钮具有一个回调action
,在该回调中提供_generateName()
方法。 请注意,Dart中没有访问修饰符,例如private
和public
。 但是,如果要在模块内部私有化,则名称应以前缀“ _”开头。
_generateName
方法_generateName
异步的。 他负责加载名称,更改isLoading
标志并将值设置为name
,从而导致重新绘制按钮和文本。
final snack = SnackBar(content: Text("Handle error!")); _generateName() async { toggleLoading(); try { // await // Json setName(map["name"]); toggleLoading(); } catch (e) { setName("oops!"); Scaffold.of(context).showSnackBar(snack); toggleLoading(); } } void toggleLoading() { setState(() { _isLoading = !_isLoading; }); }
要更改状态,必须调用setState() {}
。 没有此调用,小部件将不会被重绘。
装入程序的实现非常简单。 在重画时,文本或指示符将替换为按钮。

实现只需要几行
_buildButtonChild() { if (isLoading) { return Transform.scale( scale: 0.5, child: CircularProgressIndicator(), ); } else { return Text("Click for name"); } }
需要Transform.scale
来减小大小。
Flutter和Dart中的异步交互都基于async-await
。 可以在这里 , 这里和这里找到更多详细信息。
从哪里开始?
如今,当几乎每天都有新的Flutter内容发布时,可以帮助您结识这项技术的人并不缺乏优秀的课程。
关于Flutter基本课程的一个很好的例子是Udacity课程。 这些课程分为两章,每章的仔细思考需要3-4个小时。
如果课程不是您的选择,请通过研究现有项目的来源来开始研究技术。 扑朔迷离的存储库包含许多此类项目,并且还拥有大量现成的库,解决方案,示例以及其他材料供您学习和启发。
结论
根据前者的怀疑,深入探讨该主题的结果,我们没有发现任何痕迹。 Flutter并不像实验,而是显示了未来几年移动开发行业很大一部分将朝着哪个方向发展。 Flutter背后的一些大胆概念为开发带来了新的想法和机会。 快速,几乎直观的用户界面创建使原型设计和UX实验比以往任何时候都容易,并且每个人都可以访问。 Flutter将在哪个领域找到其应用程序-时间会证明一切。