Flutter试玩
安装依赖(Android Studio)
flutter依赖Android Studio解决Android平台支持, 即使你使用其他编辑器编写flutter程序,一样要装Android Studio。
64位Ubuntu上,Android Studio依赖一些32位库:
sudo apt install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386
安装KVM(Android Studio依赖KVM实现虚拟机加速):
sudo apt install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils
至Android Studio官网下载zip包,解压至钟意的目录(比如/opt
)。
访问android-studio/bin/
,执行studio.sh
。
初次运行会自行下载安装Android SDK,如遇到网络问题,会弹出代理设置对话框。
安装Flutter
由于网络原因,CN内需要使用镜像:
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
从GitHub代码仓库安装:
git clone -b dev https://github.com/flutter/flutter.gitexport PATH="$PWD/flutter/bin:$PATH" >> $HOME/.bash_profile
source $HOME/.bash_profile
cd ./flutter
关闭报告:
flutter config --no-analytics
运行flutter doctor
检查依赖:
flutter doctor
配置开发环境
flutter官方推荐的开发环境是Android Studio和Visual Studio Code. 作为全家桶受害者,我选择Android Studio.
其实没什么需要配置的,只需安装一个Flutter
插件。
还有就是Android开发常规的配置虚拟机:
- 确保机器开了VM加速(如果机器不是太老的话,一般都开了)
- Android Studio > Tools > Android > AVD Manager: 选择Create Virtual Device
- 选择你钟意的机型(屏幕尺寸和Android版本),注意选择
x86
或x86_64
版本,否则会很慢。如果你之前没使用过这个“机型”的话,需要下载镜像,请耐心等待。 - 点Next继续配置,Emulated Performance选择Hardware - GLES 2.0开启硬件加速。
- 点Finish创建。之后试着运行下,看看有没有问题。
然后跑一下自带的示例,看看能不能跑通。
- File > New Flutter Project: 项目类型选Flutter application
- 右上方工具栏选择刚才创建的虚拟机(如果之前测试的时候开了虚拟机,但没关闭的话,需要先关掉再进行这一步)。
- 工具栏点击运行(初次编译需要初始化环境,请耐心等待)。
flutter支持hot-reload。修改代码后ctrl+s
(save all)或点击工具栏的闪电图标,即可在虚拟机上实时看到效果。
当然,也可以在真机上调试。设备开启Developer options和USB debugging,然后连接计算机即可。
Hello, World!
好了,总算把环境搭好了。下面开始写代码啰。
我打算做一个显示PM 2.5的应用。在lib/main.dart
内写入:
// Material应用
import 'package:flutter/material.dart';
// 入口函数(函数体只有一行时,可以用`=>`代替{ ... })
void main() => runApp(new MyApp());
// 继承StatelessWidget(Stateless意味着不需要mutable状态)
// 使MyApp本身也成为一个Widget.
// 在Flutter下,几乎一切都是Widget.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
: 'PM 2.5',
title: new Scaffold(
home: new AppBar(
appBar: new Text('未知城市'),
title
),: new Center(
body: new Text('-1'),
child
),
),
);
}
}
效果是这样的:
使用Flutter包
上面我们的应用显示PM 2.5值为-1
,表示没有数据。
下面,让我们的应用从后端获取数据。
我们通过HTTP协议获取数据,这需要用到Flutter包http
。
首先,我们声明依赖,在pubspec.yaml
中加入http
:
dependencies:
flutter:
sdk: flutter
http: ^0.11.0
在Android Studio中点击Packages get
拉取http
包。
接着在lib/main.dart
内引入:
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
除了http
之外,我们还引入了dart:async
(异步获取结果,避免网络请求阻塞UI响应)和dart:convert
(转换JSON)。
编写异步函数,访问网络,解码JSON:
// 异步函数(`async`和`await`为关键字)
Future<AQI> fetchAQI() async {
// Android模拟器可以通过10.0.2.2访问主机。
String url = "http://10.0.2.2:8000/aqis.json";
final response = await http.get(url);
final responseJson = json.decode(response.body);
return new AQI.fromJson(responseJson);
}
// Flutter用不了dartson(dart下的gson)之类的需要运行时反射的库,
// 所以简单的json结构手工解析,复杂的json结构通过生成代码解析。
class AQI {
final int pm2_5;
AQI({this.pm2_5});
// json.decode返回Map<String, dynamic>
// 这意味着,直到运行时才能确定具体类型
factory AQI.fromJson(Map<String, dynamic> json) {
return new AQI(
: json['pm2_5'],
pm2_5
);
}
}
界面代码,只需改动body
部分:
: new Center(
body: new FutureBuilder<AQI>(
child: fetchAQI(),
future: (context, snapshot) { // 匿名函数
builderif (snapshot.hasData) {
return new Text("${snapshot.data.pm2_5}");
else if (snapshot.hasError) {
} return new Text("${snapshot.error}");
else {
} return new CircularProgressIndicator();
}
},
)
),
完整代码
好了,到此为止,我们已经有了一个可以显示当前PM 2.5值的应用了。 我们也大概知道Flutter应用是什么样子的了。
完整代码如下:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<AQI> fetchAQI() async {
String url = "http://10.0.2.2:8000/aqis.json";
final response = await http.get(url);
final responseJson = json.decode(response.body);
return new AQI.fromJson(responseJson);
}
class AQI {
final int pm2_5;
AQI({this.pm2_5});
factory AQI.fromJson(Map<String, dynamic> json) {
return new AQI(
: json['pm2_5'],
pm2_5
);
}
}
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
: 'PM 2.5',
title: new Scaffold(
home: new AppBar(
appBar: new Text('PM 2.5'),
title
),: new Center(
body: new FutureBuilder<AQI>(
child: fetchAQI(),
future: (context, snapshot) {
builderif (snapshot.hasData) {
return new Text("${snapshot.data.pm2_5}");
else if (snapshot.hasError) {
} return new Text("${snapshot.error}");
else {
} return new CircularProgressIndicator();
}
},
)
),
),
);
}
}
注意,PM 2.5数据从后端得到,实际项目中,后端将是一个提供数据的REST API服务。
最简单的“模拟”后端的方法就是在本地放一个json文件aqis.json
,内容如下:
{"pm2_5": 37
}
然后在aqis.json
所在目录开一个http服务,比如通过python
python2 -m SimpleHTTPServer
练习
- 把字号调大。
- 根据污染程度显示不同的颜色。
- 根据污染程度提供健康建议。
- 显示城市、监测点信息。
- 选择城市、监测点。
- 默认根据当前位置自动选择城市、监测点。
提示 PM 2.5数据可从以下途径获得: