环境介绍以及参考文献
本示例是在 Linux 16.04.1-Ubuntu 搭配 VS Code 使用。
官方手顺
新建第一个项目:
- 启动 VS Code
- 调用 View>Command Palette…
- 输入 ‘flutter’, 然后选择 ‘Flutter: New Project’ action
- 输入 Project 名称 (如 first_flutter_app), 然后按回车键
- 指定放置项目的位置,然后按蓝色的确定按钮
- 等待项目创建继续,并显示main.dart文件
通过 flutter devices 可以查看当前连接的设备。
问题记录
记录一个大坑
原因:
因为 Flutter 用的 adb 是 Android SDK 里面的 adb, 所以如果你的机器已经安装过 adb ,直接使用 adb 会产生冲突,即每次 adb connect 设备之后再调用 flutter 就会导致 adb “adb server is out of date, killing”。
复现手顺:
- 终端 adb connect ip:port
- 终端 adb devices (可以看到已连接的设备)
- 终端 flutter devices (是看不到上面连接的设备)
- 终端 adb devices (出现 adb server is out of date, killing )
解决办法:
找到 Android SDK 目录下面的 platform-tools 文件夹,使用该目录下面的 adb
- Android SDK/platform-tools/adb connect ip:port
- Android SDK/platform-tools/adb devices
- 终端 flutter devices (可以看到上面连接的设备)
- Android SDK/platform-tools/adb devices (正常)
Gradle threw an error while downloading artifacts from the network. Retrying to download…
原因:
因为墙的原因,导致下载会巨慢,所以需要自己准备一个 gradle 压缩包。
解决办法:
直接下载 zip,修改 android/gradle/wrapper/gradle-wrapper.properties 的 distributionUrl=file://zip包地址。
体验热重载
之前的开发比如在体验第一行代码的时候,修改代码后必须得要重新安装且重启才能看到效果。
而 Flutter 可以通过热重载,也就是你在更改代码后不需要重新安装重启应用就可以看到修改后的效果。
可以修改相应的字符串或者简单的逻辑,然后利用 VS Code 的快捷键 Ctrl+F5 进行热重载,就可以看到修改的内容。
解析 main.dart 文件
知其然也要知其所以然。
不能因为看到界面然后改一下参数逻辑就代表掌握了,下面去更加深层次的去探究这个文件是怎么生成了这个应用了的。
因为这个示例的代码不长,所以就从上往下一行行代码看下去
// 这个包导入了 Material UI 组件库,除了 Material 还有 Cupertino UI 组件库。
import 'package:flutter/material.dart';
// main 函数,和 C/C++ 一样,是程序的入口。调用了 runApp 方法,该方法接受一个 Widget 参数,用来启动 Flutter 应用。
// 下面三行代码也可以简写为 void main() => runApp(MyApp());
void main() {
runApp(MyApp());
}
// MyApp 代表 Flutter 应用,继承 StatelessWidget 类
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo', //多任务管理栏拉起来时显示的名称
theme: ThemeData(
primarySwatch: Colors.blue, //应用主题
),
home: MyHomePage(title: 'Flutter Demo Home Page'), //应用首页路由,路由即是页面
);
}
}
// MyHomePage 是该应用的首页,继承 StatefulWidget 类,表示是有状态的组件。
// Stateful widget 可以拥有状态,这些状态在 widget 生命周期中是可以变的,而 Stateless widget 是不可变的。
// Stateful widget 至少由两个类组成:
// 一个 StatefulWidget 类。
// 一个 State 类; StatefulWidget 类本身是不变的,但是 State 类中持有的状态在 widget 生命周期中可能会发生变化。
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key); //StatefulWidget 构造函数
final String title; //该页面的标题
@override
_MyHomePageState createState() => _MyHomePageState(); //State 构造函数
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0; //用于记录按钮点击的总次数
void _incrementCounter() {
// setState 方法的作用是通知 Flutter 框架,有状态发生了改变,Flutter 框架收到通知后,会执行 build 方法来根据新的状态重新构建界面
// Flutter 对此方法做了优化,使重新执行变的很快,所以你可以重新构建任何需要更新的东西,而无需分别去修改各个 widget。
setState(() {
_counter++;
});
}
// 当 setState 方法调用时就会执行该方法
@override
Widget build(BuildContext context) {
// Scaffold 是 Material 库中提供的页面脚手架,它提供了默认的导航栏、标题和包含主屏幕 widget 树(后同“组件树”或“部件树”)的body属性
// 有点 Android layout 的感觉
return Scaffold(
appBar: AppBar(
title: Text(widget.title), //设置顶部导航的标题
),
body: Center( //Center 可以将其子组件树对齐到屏幕中心
child: Column( //Center 的作用是将其所有子组件沿屏幕垂直方向依次排列
mainAxisAlignment: MainAxisAlignment.center, //垂直居中 children 的组件
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4, //设置字体
),
],
),
),
// floatingActionButton 是页面右下角的带“+”的悬浮按钮,它的 onPressed 属性接受一个回调函数
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter, //点击回调函数
tooltip: 'Increment', //图标描述
child: Icon(Icons.add), //图标样式
),
);
}
}