简介: 近两年Flutter的热度一直晋升,无论在阿里还是内部公司,参加Flutter生态建设的人越来越多。Flutter作为跨端的UI框架,将来也有很大的可能像Rax一样作为团体内营销流动页面搭建的DSL。所以目前学习Flutter,参加Flutter生态建设是一件时尚且有价值的事件。

Flutter是什么

Flutter是谷歌的挪动UI框架,能够疾速在iOS和Android上构建高质量的原生用户界面。Flutter能够与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织应用,并且Flutter是完全免费、开源的。简略来说,Flutter是一款挪动应用程序SDK,蕴含框架、控件和一些工具,能够用一套代码同时构建Android和iOS利用,并且性能能够达到原生利用一样的性能。Flutter简介

配置开发环境

Flutter开发能够在macOS,Linux或Windows上实现。尽管您能够在Flutter工具链中应用任何编辑器,但IntelliJ IDEA,Android Studio和Visual Studio Code的IDE插件能够简化开发工作。

  • 下载flutter SDK。地址
  • 将flutter的bin目录增加到path中。
  • 执行flutter doctor命令,他会装置flutter框架,包含dart,而且提醒你任何其余须要装置的依赖。
  • 装置其余依赖。
  • 在IDE中装置flutter插件。

体验

▐ Android Studio (为Flutter提供残缺的IDE体验)

创立利用

  1. 抉择 File>New Flutter Project
  2. 抉择 Flutter application 作为 project 类型, 而后点击 Next
  3. 输出项目名称 (如 myapp), 而后点击 Next
  4. 点击 Finish
  5. 期待Android Studio装置SDK并创立我的项目. 在我的项目目录中,您应用程序的代码位于 lib/main.dart.

运行应用程序

定位到Android Studio 工具栏:

  1. 在 target selector 中, 抉择一个运行该利用的Android设施. 如果没有列出可用,请抉择 Tools>Android>AVD Manager 并在那里创立一个
  2. 在工具栏中点击 Run图标, 或者调用菜单项 Run > Run.

▐ VS Code(轻量级编辑器,反对Flutter运行和调试)

创立利用

  1. 启动 VS Code.
  2. 调用 View>Command Palette…
  3. 输出 ‘flutter’, 而后抉择 ‘Flutter: New Project’ action
  4. 输出 Project 名称 (如myapp), 而后按回车键
  5. 指定搁置我的项目的地位,而后按蓝色的确定按钮
  6. 期待我的项目创立持续,并显示main.dart文件 在我的项目目录中,您应用程序的代码位于 lib/main.dart.

运行应用程序

  1. 确保在VS Code的右下角抉择了指标设施
  2. 按 F5 键或调用Debug>Start Debugging
  3. 期待应用程序启动

▐ Terminal + 编辑器

创立利用

应用 flutter create 命令创立一个project:

$ flutter create myapp$ cd myapp

运行应用程序

  • 查看Android设施是否在运行。如果没有显示, 请参照 设置。
$ flutter devices

运行 flutter run 命令来运行应用程序:

$ flutter run
如果一切正常, 您应该在您的设施或模拟器上会看到启动的应用程序:

## 我的项目构造

┬└ projectname  ┬  ├ android      - Android局部的工程文件  ├ build        - 我的项目的构建输入目录  ├ ios          - iOS局部的工程文件  ├ lib          - 我的项目中的Dart源文件    ┬    └ src        - 蕴含其余源文件    └ main.dart  - 主动生成的我的项目入口文件,相似RN的index.js文件  ├ test         - 测试相干文件  └ pubspec.yaml - 我的项目依赖配置文件相似于RN的 package.json

如何增加Flutter我的项目所需的依赖?

  • 在Android中,你能够在Gradle文件来增加依赖项;
  • 在 iOS 中,通常把依赖增加到 Podfile 中;
  • 在RN中,通常是由package.json来治理我的项目依赖;

Flutter 应用 Dart 构建零碎和 Pub 包管理器来解决依赖。这些工具将Android 和 iOS native 包装应用程序的构建委派给相应的构建零碎。

dependencies: flutter: sdk: flutter google_sign_in: ^3.0.3

在Flutter中,尽管在Flutter我的项目中的Android文件夹下有Gradle文件,但只有在增加平台相干所需的依赖关系时才应用这些文件。否则,应该应用pubspec.yaml来申明用于Flutter的内部依赖项。

iOS也是一样,如果你的 Flutter 工程中的 iOS 文件夹中有 Podfile,请仅在增加iOS平台相干的依赖时应用它。否则,应该应用pubspec.yaml来申明用于Flutter的内部依赖项。

如何归档图片资源以及如何解决不同分辨率

尽管Android将resources 和 assets 区别对待,但在Flutter中它们都会被作为assets解决, 所有存在于Android上res/drawable- *文件夹中的资源都放在Flutter的assets文件夹中。

与Android相似,iOS 同样将 images 和 assets 作为不同的货色,而 Flutter 中只有 assets。被放到 iOS 中 Images.xcasset 文件夹下的资源在 Flutter 中被放到了 assets 文件夹中。

在Flutter中assets能够是任意类型的文件,而不仅仅是图片。例如,你能够把 json 文件搁置到 my-assets 文件夹中。

my-assets/data.json

记得在 pubspec.yaml 文件中申明 assets:

assets: - my-assets/data.json

而后在代码中咱们能够通过 AssetBundle 来拜访它:

import 'dart:async' show Future;import 'package:flutter/services.dart' show rootBundle;Future<String> loadAsset() async {  return await rootBundle.loadString('my-assets/data.json');}

对于图片,Flutter 像 iOS 一样,遵循了一个简略的基于像素密度的格局。Image assets 可能是 1.0x 2.0x 3.0x 或是其余的任何倍数。这个 devicePixelRatio 示意了物理像素到单个逻辑像素的比率。

Android不同像素密度的图片和Flutter的像素比率的对应关系

ldpi    0.75xmdpi    1.0xhdpi    1.5xxhdpi   2.0xxxhdpi  3.0xxxxhdpi 4.0x

举个例子,要把一个名为 my_icon.png 的图片放到 Flutter 工程中,你可能想要把它放到images文件夹中。把图片(1.0x)搁置到 images 文件夹中,并把其它分辨率的图片放在对应的子文件夹中,并接上适合的比例系数,就像这样:

images/my_icon.png       // Base: 1.0x imageimages/2.0x/my_icon.png  // 2.0x imageimages/3.0x/my_icon.png  // 3.0x image

接下来就能够在pubspec.yaml文件中这样申明这个图片资源:

assets: - images/my_icon.png

当初,咱们就能够借助AssetImage来拜访它了。

return AssetImage("images/a_dot_burr.jpeg");

也可通过 Image widget 间接应用:

@overrideWidget build(BuildContext context) {  return Image.asset("images/my_image.png");}

如何归档strings资源,以及如何解决不同语言?

不像 iOS 领有一个 Localizable.strings 文件,Flutter目前没有专门的字符串资源零碎。目前,最佳做法是将strings资源作为动态字段保留在类中。例如:

class Strings {  static String welcomeMessage = "Welcome To Flutter";}

而后像如下形式来拜访它:

Text(Strings.welcomeMessage)

默认状况下,Flutter 只反对美式英语字符串。如果你要反对其余语言,请引入 flutter_localizations 包。你可能也要引入 intl 包来反对其余的 i10n 机制,比方日期/工夫格式化。

dependencies:  # ... flutter_localizations: sdk: flutter intl: "^0.15.6"

要应用 flutter_localizations 包,还须要在 app widget 中指定 localizationsDelegates 和 supportedLocales。

import'package:flutter_localizations/flutter_localizations.dart';MaterialApp( localizationsDelegates: [   // Add app-specific localization delegate[s] here   GlobalMaterialLocalizations.delegate,   GlobalWidgetsLocalizations.delegate, ], supportedLocales: [    const Locale('en', 'US'), // English    const Locale('he', 'IL'), // Hebrew    // ... other locales the app supports  ],  // ...)

这些代理包含了理论的本地化值,并且 supportedLocales 定义了 App 反对哪些地区。下面的例子应用了一个 MaterialApp ,所以它既有 GlobalWidgetsLocalizations 用于根底 widgets,也有 MaterialWidgetsLocalizations 用于 Material wigets 的本地化。如果你应用 WidgetsApp ,则无需包含后者。留神,这两个代理尽管包含了“默认”值,但如果你想让你的 App 本地化,你仍须要提供一或多个代理作为你的 App 本地化正本。

当初始化时,WidgetsApp 或 MaterialApp 会应用你指定的代理为你创立一个 Localizations widget。Localizations widget 能够随时从以后上下文中拜访设施的地点,或者应用 Window.locale。

要拜访本地化文件,应用 Localizations.of() 办法来拜访提供代理的特定本地化类。如需翻译,应用 intl_translation 包来取出翻译正本到 arb 文件中。把它们引入 App 中,并用 intl 来应用它们。

更多 Flutter 中国际化和本地化的细节,请拜访 internationalization guide ,外面有不应用 intl 包的示例代码。

组件

在 Flutter 中所有皆是 组件,仅仅 Widget 的子类和间接子类就有350多个,如此多的组件到底如果学习,真的须要学习 350 多个组件?经济学中有一个驰名的 二八定律 ,而咱们学习 Flutter 也实用于二八定律,大部分组件是平时很少用到的,因而作为初学者,只需学习那 20% 罕用的组件即可。

RenderObjectWidget及其子类共有89个:

ProxyWidget及其子类共有34个:

StatelessWidget及其子类共有89个:

StatefulWidget的子类最多,高达141个

▐ 组件树

Flutter 创立App的时候,所有的组件最初会生成一个组件树,例如如下代码:

void main() {  runApp(MyApp());}class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    return MaterialApp(      title: 'Flutter Demo',      theme: ThemeData(      ),      home: Scaffold(        body: Text('Hello world!'),      ),    );  }}

main 函数是应用程序开始的中央,运行 MyApp 组件。生成的组件树如下:

让 Text 组件居中,批改如下:

Scaffold(  body: Center(    child: Text('Hello world!'),  ),)

给应用程序增加 AppBar:

Scaffold(  appBar: AppBar(),  body: Center(    child: Text('Hello world!'),  ),)

▐ StatefulWidget vs StatelessWidget

Flutter 中组件分为 无状态组件(StatelessWidget) 和 有状态组件(StatefulWidget)两种。它们惟一的区别就是运行时 从新加载 组件的形式不同,StatelessWidget 组件从新加载时从新创立以后组件的实例,而StatefulWidget组件从新加载时不会从新创立实例,而是从新执行 build 函数。

StatelessWidget 组件创立的形式:

class StatelessWidgetDemo extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Container();  }}

build 函数返回以后组件,此组件一旦创立将不可扭转,build 函数只能执行一次。如果想从新绘制此组件,只能从新创立此组件新的实例。

StatefulWidget 组件创立的形式:

class StatefulWidgetDemo extends StatefulWidget {  @override  _StatefulWidgetDemoState createState() => _StatefulWidgetDemoState();}class _StatefulWidgetDemoState extends State<StatefulWidgetDemo> {  @override  Widget build(BuildContext context) {    return Container();  }}

StatefulWidget 组件的创立形式和 StatelessWidget 不同,State<> 中的 build 函数返回以后组件,有状态的组件能够在其生命周期内多次重绘,即屡次调用 build 函数,而不是创立一个新的实例。

StatefulWidget 组件重绘须要调用 setstate 办法,setstate 会使其本身及其子组件重绘,所以尽量封装 StatefulWidget 组件,防止有效的重建和重绘,影响性能。

疾速书写小技巧:在 Android Studio 和 VS Code 中 输出 stl 而后点击回车,能够疾速创立 StatelessWidget 组件,同理输出 stf 点击回车,能够疾速创立 StatefulWidget 组件,这是编辑器 Live Templates 的性能。

▐ Material vs Cupertino

Flutter 中蕴含两套格调的组件,别离是 Material 和 Cupertino ,Cupertino 是 iOS格调的组件,命名都带 Cupertino 前缀,比方 CupertinoSlider 、 CupertinoDatePicker 等, Material Design 是由 Google 推出,旨在为手机、平板电脑、台式机和“其余平台”提供更统一、更宽泛的“外观和感觉”。

Flutter 应用一套代码在不同的平台上体现统一,它不会依据不同的平台绘制不同的形状,比方应用 AlertDialog 弹出正告框,不论在 Android 上,还是在 iOS上成果是一样。

但有一些性能 Flutter 辨别平台,比方 ListView 滑动到底部时持续滑动,Android 底部会呈现淡蓝色(默认状况下)拱形,而 iOS 上则没有,这是因为 Flutter 在封装此组件时在代码中辨别了平台,所以在查看 Flutter 源码到过程中会常常看到依据不同的平台做不同解决的状况。

总结

Flutter学习老本次要还是在组件的相熟上,能数量罕用组件就能够上手我的项目了,至于其余的控件只需大略浏览一下,做我的项目的时候遇到一些性能可能想起 Flutter 曾经提供了此组件就能够了。

参考
Flutter 中文网
Flutter 老孟