Flutter之環境配置與專案搭建
Flutter之環境配置與專案搭建
一,介紹
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 ,開啟後如圖所示:
-
將安裝包zip解壓到你想安裝Flutter SDK的路徑(如:D
:\flutter
;注意,不要將flutter安裝到需要一些高許可權的路徑如C:\Program Files\
)。 -
在Flutter安裝目錄的
flutter
檔案下找到flutter_console.bat
,雙擊執行並啟動flutter命令列,接下來,你就可以在Flutter命令列執行flutter命令了。
-
第三步:配置環境變數
如果不配置環境變數,在全域性環境中是無法使用flutter命令的,轉到 “控制面板>使用者帳戶>使用者帳戶>更改我的環境變數”,在Path下新增D:\flutter\bin條目,儲存即可。
第四步:執行 flutter doctor命令
在Flutter命令列執行如下命令來檢視是否還需要安裝其它依賴,如果需要,安裝它們:
1 flutter doctor
該命令檢查你的環境並在命令列視窗中顯示報告。Dart SDK已經在打包在Flutter SDK裡了,沒有必要單獨安裝Dart。安裝完成後再執行flutter doctor
命令來驗證是否安裝成功。
2.2,windows與mac本配置(模擬器)
windows下sdk與jdk配置,可參考React-Native windows環境搭建記錄
mac本下sdk與jdk配置,可參考React Naive之macOs環境配置記錄(iOS Android)
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相關的配置選項。
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 }