开发初体验
vscode:
打开 View > Command Palette。
输入「flutter」,选择 Flutter: New Project。
选择 Application。
新建或选择新项目将存放的上层目录。
输入项目名称,例如 my_app,并点击 Enter。
等待项目创建完成,并且 main.dart 文件展现在编辑器中。
该命令会创建一个名为 myapp,里面包含一个简单的示例程序,里面用到了 Material 组件。
目录结构
lib/main.dart
: 整个应用的入口文件,其中的 main 函数是整个 Flutter 应用的启动起始函数- android、ios 目录: 包含 flutter 应用对应的 Android、iOS 应用实体
- test 目录: 存放项目的测试代码
- pubspec.yaml 文件: Flutter 应用的包管理文件,引入第三方包时需要在此文件中管理
Run the app
打开 Android Studio -> More Actions -> Virtual Device Manager -> 打开测试 device(例如 device 名为 flutter test)
定位到 VS Code 的状态栏(窗口底部的蓝色栏):
选择 Flutter:3.3.4 flutter test(android-x86 emulator)
点击 vscode 左上角 运行 -> 启动调试(或者按下 F5)
等待应用启动——启动进度会在 Debug Console 中展示。
当应用编译完成后,就可以在设备上运行这个起步应用了。
尝试热重载 (hot reload)
Flutter 通过 热重载 提供快速开发周期,该功能支持应用程序在运行状态下重载代码,无需重新启动应用程序或者丢失程序运行状态。
修改一下代码,然后告诉 IDE 或者命令行工具你需要热重载,然后看一下模拟器或者设备上应用的变化。
打开 lib/main.dart。
修改字符串
1 |
|
改为
1 |
|
保存修改: invoke Save All, or click Hot Reload
你会发现修改后的字符串几乎马上出现在正在运行的应用程序上。
构建模式
https://flutter.cn/docs/testing/build-modes
构建简单应用第1部分
https://flutter.cn/docs/get-started/codelab
你将完成一个简单的应用,功能是:为一个创业公司生成建议的公司名称。用户可以选择和取消选择的名称、保存喜欢的名称。
该代码一次生成十个名称,当用户滚动时,会生成新一批名称。
做完之后的应用效果图:
第一步:创建初始化工程
打开 View > Command Palette。
输入「flutter」,选择 Flutter: New Project。
选择 Application。
新建或选择新项目将存放的上层目录。
输入项目名称,例如 startup_namer,并点击 Enter。
等待项目创建完成,并且 main.dart 文件展现在编辑器中。
在这个示例中,你将主要编辑 Dart 代码所在的 lib/main.dart
文件,
删除 lib/main.dart 中的所有代码,然后替换为下面的代码,它将在屏幕的中心显示「Hello World」。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
本示例创建了一个具有 Material Design 风格的应用, Material 是一种移动端和网页端通用的视觉设计语言, Flutter 提供了丰富的 Material 风格的 widgets。在 pubspec.yaml 文件的 flutter 部分选择加入 uses-material-design: true 会是一个明智之举,通过这个可以让您使用更多 Material 的特性,比如其预定义好的 图标 集。
该应用程序继承了 StatelessWidget,这将会使应用本身也成为一个 widget。
在 Flutter 中,几乎所有都是 widget,包括对齐 (alignment)、填充 (padding) 和布局 (layout)。
Scaffold 是 Material 库中提供的一个 widget,它提供了默认的导航栏、标题和包含主屏幕 widget 树的 body 属性。 widget 树可以很复杂。
一个 widget 的主要工作是提供一个 build() 方法来描述如何根据其他较低级别的 widgets 来显示自己。
本示例中的 body 的 widget 树中包含了一个 Center widget, Center widget 又包含一个 Text 子 widget, Center widget 可以将其子 widget 树对齐到屏幕中心。
第二步:使用外部 package
在这一步中,你将开始使用一个名为 english_words(https://pub.flutter-io.cn/packages/english_words) 的开源软件包,其中包含数千个最常用的英文单词以及一些实用功能。
你可以在 pub.dev(https://pub.flutter-io.cn/) 上找到 english_words package 以及其他许多开源的 package。
pubspec.yaml 文件管理着 Flutter 工程中的所有资源和依赖。
通过下面的方式将 english_words 这个 package 加入你的工程里:
在你的 IDE 中,将 english_words: ^4.0.0 加到 cupertino_icons 1.0.4 后面,然后保存文件。
文件保存后就会触发依赖的获取,这等同于执行下面的命令:
1 |
|
输出的结果会类似下面这些:
1 2 3 4 5 6 |
|
依赖关系的获取也会自动生成 pubspec.lock 文件,这个文件包含所有加入项目的 package 和版本号信息。
pubspec.yaml 文件管理着 Flutter 工程中的所有资源和依赖
在 lib/main.dart 中引入,如下所示:
1 |
|
在你输入时,Android Studio会为你提供有关库导入的建议。然后它将呈现灰色的导入字符串,让你知道导入的库截至目前尚未被使用。
接下来,我们使用 English words 包生成文本来替换字符串”Hello World”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
第三步:添加一个 Stateful widget
无 状态的 widgets 是不可变的,这意味着它们的属性不能改变 —— 所有的值都是 final。
有 状态的 widgets 也是不可变的,但其持有的状态可能在 widget 生命周期中发生变化,实现一个有状态的 widget 至少需要两个类:
1)一个 StatefulWidget 类;
2)一个 State 类,StatefulWidget 类本身是不变的,但是 State 类在 widget 生命周期中始终存在。
在这一步,你将添加一个有状态的 widget —— RandomWords,它会创建自己的状态类 —— _RandomWordsState,然后你需要将 RandomWords 内嵌到已有的无状态的 MyApp widget。
-
创建有状态 widget 的样板代码。
在 lib/main.dart 中,将光标置于所有代码之后,输入 回车 几次另起新行。
在 IDE 中,输入 stful,编辑器就会提示您是否要创建一个 Stateful widget。
按回车键表示接受建议,随后就会出现两个类的样板代码,光标也会被定位在输入有状态 widget 的名称处。 -
输入 RandomWords 作为有状态 widget 的名称。
RandomWords widget 的主要作用就是创建其对应的 State 类。
输入 RandomWords 作为有有状态 widget 的名称后, IDE 会自动更新其对应的 State 类,并将其命名为 _RandomWordsState。默认情况下,State 类的名称带有下划线前缀。
Dart 语言中,给标识符加上下划线前缀可以 增强隐私性,并且这也是针对 State 对象推荐的最佳实践写法。
IDE 也会自动将状态类继承自 State<RandomWords>
,这表示专门用于 RandomWords 的通用 State 类。
该应用程序的大多数逻辑都位于此处—它维护 RandomWords widget 的状态。
该类会保存生成的单词对的列表,该列表随用户滚动而无限增长,在第 2 部分中,用户可以通过点击心形图标,添加或删除列表中收藏的单词对。
这两个类现在都如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
- 更新 _RandomWordsState 中的 build() 方法:
1 2 3 4 5 6 7 |
|
- 通过以下差异所示的更改,删除 MyApp 中单词生成的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
- 重启应用。应用应该像之前一样运行,每次热重载或保存应用程序时都会显示一个单词对。
第四步:创建一个无限滚动的 ListView
在该步骤中,您会拓展 _RandomWordsState 以生成并显示单词对列表。
随着用户滚动,列表(显示在 ListView widget 中)将无限增长。
ListView 的 builder 工厂构造函数使您可以按需延迟构建列表视图。
- 向 _RandomWordsState 类中添加一个 _suggestions 列表以保存建议的单词对,同时,添加一个 _biggerFont 变量来增大字体大小。
1 2 3 4 5 |
|
- 接下来,我们将向 _RandomWordsState 类添加一个 _buildSuggestions() 方法,此方法构建显示建议单词对的 ListView。
ListView 类提供了一个名为 itemBuilder 的 builder 属性,这是一个工厂匿名回调函数,接受两个参数 BuildContext 和行迭代器 i。
迭代器从 0 开始,每调用一次该函数 i 就会自增,每次建议的单词对都会让其递增两次,一次是 ListTile,另一次是 Divider。
它用于创建一个在用户滚动时候无限增长的列表。
- 使用 ListView.builder 构造函数,从 _RandomWordsState 类的 build 方法中返回一个 ListView widget。
1 2 3 4 5 6 7 8 9 10 11 12 |
|
/*1*/
对于每个建议的单词对都会调用一次 itemBuilder,然后将单词对添加到 ListTile 行中。在偶数行,该函数会为单词对添加一个 ListTile row,在奇数行,该函数会添加一个分割线的 widget,来分隔相邻的词对。注意,在小屏幕上,分割线可能较难辨别。
/*2*/
在 ListView 里的每一行之前,添加一个 1 像素高的分隔线 widget。
/*3*/
语法 i ~/ 2 表示 i 除以 2,但返回值是整型(向下取整),比如 i 为:1, 2, 3, 4, 5 时,结果为 0, 1, 1, 2, 2,这个可以计算出 ListView 中减去分隔线后的实际单词对数量。
/*4*/
如果是建议列表中最后一个单词对,接着再生成 10 个单词对,然后添加到建议列表。
ListView.builder 的构造函数会为每个单词对创建并显示一个 Text widget,下一步里,你将可以为每个单词对返回一个 ListTile widget,这可以让每一行的显示更漂亮。
- 在 _RandomWordsState 类的 ListView.builder 里的 itemBuilder 属性体里,将 Text 替换为 ListTile widget:
1 2 3 4 5 6 |
|
ListTile 是包含了文本以及前后位图标 widget 的一行。
- 更新 _RandomWordsState 的 build() 方法以使用 _buildSuggestions(),而不是直接调用单词生成库,代码更改后如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
- 更新 MyApp 的 build() 方法,修改 title 的值来改变标题,修改 home 的值为 RandomWords widget。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
|
- 重新启动你的项目工程应用,你应该看到一个单词对列表。尽可能地向下滚动,你将继续看到新的单词对。
构建简单应用第2部分
https://codelabs.flutter-io.cn/codelabs/first-flutter-app-pt2/#0