一,介绍
1.1,Dart
Dart 是一种 易于学习、 易于扩展、并且可以部署到 任何地方 的 应用 编程 语言。并且同时借鉴了Java和JavaScript。Dart在静态语法方面和Java非常相似,如类型定义、函数声明、泛型等,而在动态特性方面又和JavaScript很像,如函数式特性、异步支持等。
1.2,Flutter
Flutter 是 Google推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart语言开发 App,一套代码同时运行在 iOS 和 Android平台。 Flutter提供了丰富的组件、接口,开发者可以很快地为 Flutter添加 native扩展。同时 Flutter还使用 Native引擎渲染视图。
二,开发环境配置
2.1,安装Flutter
第一步:配置镜像
由于在国内访问Flutter有时可能会受到限制,Flutter官方为中国开发者搭建了临时镜像,大家可以将如下环境变量加入到用户环境变量中:
1 export PUB_HOSTED_URL=https://pub.flutter-io.cn
2 export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
如下图所示:
第二步:获取Flutter SDK
去flutter官网下载其最新可用的安装包,下载地址:https://flutter.dev/docs/development/tools/sdk/releases ,打开后如图所示:
1、将安装包zip解压到你想安装Flutter SDK的路径(如:D:flutter;注意,不要将flutter安装到需要一些高权限的路径如C:Program Files)。
2、在Flutter安装目录的flutter文件下找到flutter_console.bat,双击运行并启动flutter命令行,接下来,你就可以在Flutter命令行运行flutter命令了。
第三步:配置环境变量
如果不配置环境变量,在全局环境中是无法使用flutter命令的,转到 “控制面板>用户帐户>用户帐户>更改我的环境变量”,在Path下添加D:flutterbin条目,保存即可。
第四步:运行 flutter doctor命令
在Flutter命令行运行如下命令来查看是否还需要安装其它依赖,如果需要,安装它们:
1 flutter doctor
该命令检查你的环境并在命令行窗口中显示报告。Dart SDK已经在打包在Flutter SDK里了,没有必要单独安装Dart。安装完成后再运行flutter doctor命令来验证是否安装成功。
2.2,windows与mac本配置(模拟器)
windows下sdk与jdk配置:https://help.aliyun.com/knowledge_detail/40814.html
mac本下sdk与jdk配置:https://yq.aliyun.com/articles/250951
2.3,编辑器配置
常用编辑器是VS Code,故此这儿主要介绍VS Code的配置,VS Code支持Flutter运行和调试。
安装flutter插件
- 启动 VS Code。
- 调用 View>Command Palette…。
- 输入 ‘install’, 然后选择 Extensions: Install Extension action。
- 在搜索框输入 flutter ,在搜索结果列表中选择 ‘Flutter’, 然后点击 Install。
- 选择 ‘OK’ 重新启动 VS Code。
- 验证配置
- 调用 View>Command Palette…
- 输入 ‘doctor’, 然后选择 ‘Flutter: Run Flutter Doctor’ action。
- 查看“OUTPUT”窗口中的输出是否有问题
创建Flutter应用
- 启动 VS Code
- 调用 View>Command Palette…
- 输入 ‘flutter’, 然后选择 ‘Flutter: New Project’ action
- 输入 Project 名称 (如myapp), 然后按回车键
- 指定放置项目的位置,然后按蓝色的确定按钮
- 等待项目创建继续,并显示main.dart文件
VS Code格式化dart代码的快捷方式是shift+alt+f
三,项目搭建
第一步:创建Flutter应用
1 flutter create yingqi_flutter
第二步:底部tab
Flutter中的路由管理和原生开发类似,无论是Android还是iOS,导航管理都会维护一个路由栈,路由入栈(push)操作对应打开一个新页面,路由出栈(pop)操作对应页面关闭操作,而路由管理主要是指如何来管理路由栈。
1 final result =
2 await Navigator.of(context).push(MaterialPageRoute(builder: (context) {
3 return LoginPage();
4 }));
1 Navigator.pop(context, "refresh");
1 class AppHomeState extends State<AppHome> {
2 final appBarTitles = ['首页', '资讯', '产品', '我的'];
3
4 ...
5
6 int _tabIndex = 0;
7
8 var tabImages;
9 var _body;
10 var pages;
11
12 Image getTabImage(path) {
13 return Image.asset(path, width: 20.0, height: 20.0);
14 }
15
16 @override
17 void initState() {
18 super.initState();
19
20 ...
21
22 });
23 pages = <Widget>[HomePage(), NewsPage(), ProductPage(), MyPage()];
24 if (tabImages == null) {
25 tabImages = [
26 [
27 getTabImage('images/ic_nav_news_normal.png'),
28 getTabImage('images/ic_nav_news_actived.png')
29 ],
30 [
31 getTabImage('images/ic_nav_tweet_normal.png'),
32 getTabImage('images/ic_nav_tweet_actived.png')
33 ],
34 [
35 getTabImage('images/ic_nav_discover_normal.png'),
36 getTabImage('images/ic_nav_discover_actived.png')
37 ],
38 [
39 getTabImage('images/ic_nav_my_normal.png'),
40 getTabImage('images/ic_nav_my_pressed.png')
41 ]
42 ];
43 }
44 }
45
46 TextStyle getTabTextStyle(int curIndex) {
47 if (curIndex == _tabIndex) {
48 return tabTextStyleSelected;
49 }
50 return tabTextStyleNormal;
51 }
52
53 Image getTabIcon(int curIndex) {
54 if (curIndex == _tabIndex) {
55 return tabImages[curIndex][1];
56 }
57 return tabImages[curIndex][0];
58 }
59
60 Text getTabTitle(int curIndex) {
61 return Text(appBarTitles[curIndex], style: getTabTextStyle(curIndex));
62 }
63
64 @override
65 Widget build(BuildContext context) {
66 _body = IndexedStack(
67 children: pages,
68 index: _tabIndex,
69 );
70 return MaterialApp( 74 home: Scaffold( 80 body: _body,
81 bottomNavigationBar: CupertinoTabBar(
82 items: <BottomNavigationBarItem>[
83 BottomNavigationBarItem(
84 icon: getTabIcon(0),
85 title: getTabTitle(0)),
86 BottomNavigationBarItem(
87 icon: getTabIcon(1),
88 title: getTabTitle(1)),
89 BottomNavigationBarItem(
90 icon: getTabIcon(2),
91 title: getTabTitle(2)),
92 BottomNavigationBarItem(
93 icon: getTabIcon(3),
94 title: getTabTitle(3)),
95 ],
96 currentIndex: _tabIndex,
97 onTap: (index) {
98 setState((){
99 _tabIndex = index;
100 });
101 },
102 ),
103 ),
104 );
105 }
106 }
第三步:包管理与资源配置
Flutter项目默认的配置文件是pubspec.yaml,包与资源配置,均修改此文件
包配置如下图所示:
- dependencies:应用或包依赖的其它包或插件。
- flutter:flutter相关的配置选项。
http: ^0.12.0就是项目中需要使用外部包配置,使用如下命令即可下载:
1 flutter packages get
资源配置如下图所示:
需要使用什么资源,以图片中的格式在assets下继续添加即可。
第四步:数据缓存
1,在pubspec.yaml文件中,添加如下包:
1 shared_preferences: ^0.4.3
2,数据记录类
1 import 'package:shared_preferences/shared_preferences.dart';
2 import 'dart:async';
3
4 class DataUtils {
5
6 ...
7
8 }
3,用户登录信息操作
1 static const String SP_USER_NAME = "name";
2 static const String SP_USER_ID = "userId";
3 static const String SP_IS_LOGIN = "isLogin";
4
5 // 保存用户登录信息,data中包含了token等信息
6 static saveLoginInfo(Map data) async {
7 if (data != null) {
8 SharedPreferences sp = await SharedPreferences.getInstance();
9 String userId = data['UserId'];
10 await sp.setString(SP_USER_ID, userId);
11 String name = data['Name'];
12 await sp.setString(SP_USER_NAME, name);
13 await sp.setBool(SP_IS_LOGIN, true);
14 }
15 }
16
17 // 清除登录信息
18 static clearLoginInfo() async {
19 SharedPreferences sp = await SharedPreferences.getInstance();
20 await sp.setString(SP_USER_ID, "");
21 await sp.setString(SP_USER_NAME, "");
22 await sp.setBool(SP_IS_LOGIN, false);
23 }
24
25 // 获取用户登录信息
26 static Future<LoginInfo> getLoginInfo() async {
27 SharedPreferences sp = await SharedPreferences.getInstance();
28 bool isLogin = sp.getBool(SP_IS_LOGIN);
29 if (isLogin == null || !isLogin) {
30 return null;
31 }
32 LoginInfo loginInfo = LoginInfo();
33 loginInfo.userId = sp.getString(SP_USER_ID);
34 loginInfo.name = sp.getString(SP_USER_NAME);
35 return loginInfo;
36 }
如需搭建Flutter之环境配置与项目,可采购阿里云服务器,