--- tags: Flutter --- # Flutter 入門 ## 建立環境 ### macOS 建立 flutter 環境 1. 進入[Flutter 官方網站](https://flutter.dev/),點擊右上角『Get started』 2. 選擇你的作業系統(以下用 macOS 為例) 3. 確認是否有安裝 Xcode 與 git,如果有安裝 Xcode 默認就會已安裝 git,如果只有 git 沒有 Xcode 則可開啟 App store 直接搜尋 Xcode 並安裝 4. 針對系統選擇其中一個 zip 下載(比如用 M1 就選擇下載 arm64 的 zip) 5. 將下載的 zip 進行解壓縮 6. 開啟 Finder 然後直接在使用者的資料夾中建立一個『`development`』,進入『`development`』資料夾中,再建立一個『`flutter`』資料夾 7. 開啟剛才解壓縮後的 zip 資料夾,按下 『`shift + command + .`』來顯示所有隱藏的檔案,將所有檔案全部拷貝下來,貼到上一步建立好的『`flutter`』資料夾中 8. 回到使用者的資料夾中,一樣通過按下 『`shift + command + .`』來顯示所有隱藏的檔案,找到『`.zshrc`』檔案 9. 開啟『`.zshrc`』檔案後,在最上面新增一行『`export PATH="$PATH:${flutter 資料夾的路徑}/bin"`』(假設前面步驟都與我相同,新增的這行就是『`export PATH="$PATH:/Users/${你的使用者名稱}/development/flutter/bin"`』,假設 flutter 放置路徑與上方步驟不同,則可以直接從 Finder 中找到 flutter 資料夾,並用右鍵點選查看資訊,將位置從『使用者』開始複製下來使用) > 若要升級 flutter 需 cd 到 `/development/flutter` 後,執行命令 `flutter upgrade` > 若要升級 Xcode 可執行命令 `xcodebuild -downloadPlatform iOS` ### 開啟 iPhone 模擬器 1. 用 command + space 快速搜尋並開啟 Xcode,然後點選 Agree 同意條款 2. 回到[官網文件](https://docs.flutter.dev/get-started/install/macos#ios-setup)中,將 `Install Xcode` 的兩行命令拷貝起來,接著開啟終端機,貼上那兩行命令執行(會叫你輸入密碼) 3. 接著在終端機中輸入 `sudo xcodebuild -license` 一直按空白鍵到底部輸入 agree 同意條款 4. 最後即可在終端機中輸入 `open -a Simulator` 開啟一個 iPhone 模擬器(這邊要等幾分鐘模擬器才會開機並顯示內容唷) ### 開啟 Android 模擬器 1. 進入[Android Studio 官方網站](https://developer.android.com/studio),點擊首頁的『`Download Android Studio Flamingo`』按鈕,接著勾選同意條款後,根據電腦系統選擇點擊下載安裝『`Mac with Intel chip`』或『`Mac with Apple chip`』 2. 將 `Android Studio` 複製到電腦的應用程式資料夾中 3. 接著開啟 `Android Studio` 會進入安裝的視窗,過程中主要需確保有勾選 SDK 以及 API 的 components、將所有條款設為 Accept,其他步驟都可以直接點擊 Next 跳過 4. 安裝完成後會自動開啟 `Android Studio` 應用程式,請點擊 More Actions -> SDK Manager 5. 接著在 SDK Platforms 中勾選 Android 13.0 (Tiramisu) 6. 然後在 SDK Tools 中勾選 Android SDK Build-Tools 34 、 Android SDK Command-Line tools (latest) 、 Android Emulator 、 Android SDK Platform-Tools 並點擊右下角OK,勾選同意條款後等待安裝完成即可 7. 最後請點擊 More Actions -> Virtual Device Manager,然後點選左上角的 Creat device 建立模擬器 8. 選擇 Pixel 6 點下一步,點選 Tiramisu 安裝後進入下一步,最後將 Graphics 選項改為 Hardware - GLES 2.0 即可點擊 finish 9. 完成後會看到模擬器列表出現剛才建立的模擬器,點擊右側播放鍵即可開啟安卓模擬器 ### 檢查環境是否安裝完畢 1. 開啟終端機,執行命令 `flutter doctor`,這會顯示目前有什麼存在的問題以及該如何解決 2. 如果看見『`✗ Unable to find bundled Java version.`』這邊可以通過開啟 Finder 然後找到 `Android Studio` 右鍵,顯示套件內容,建立一個資料夾『jre』,然後將『jbr』的內容全副拷貝貼上至『jre』([解決方法參考](https://github.com/flutter/flutter/issues/118502#issuecomment-1420165305)) 3. 如果看見『`Android licenses status unknow`』,執行命令『`flutter doctor --android-licenses`』會顯示條款,不斷地按下 y 來同意,最後再重新執行一次『`flutter doctor`』即可看到 `Android toolchain` 變成通過的狀態了 4. 如果看見『`✗ CocoaPods not installed.`』,則根據提示進入[該頁](https://guides.cocoapods.org/using/getting-started.html#installation),執行 `$sudo gem install cocoapods` 即可更新 5. 將所有錯誤按照提示都解決後再次執行命令 `flutter doctor`,看見所有項目都呈現通過且最後一行顯示 `• No issues found!` 則表示環境安裝完成 ## 運行第一個 Flutter APP 首先開啟 VS Code 進入『延伸模組』區域,搜尋 `Flutter` 點擊安裝 安裝後會發現它順帶也為你安裝了 `Dart` 的模組 接著我們用終端機 cd 到任意一個你想生成 flutter 的位置 執行 `flutter create ${project name}` (假設我的 project name 叫 myapp,則執行 `flutter create myapp`) >這邊要注意,項目名稱不能包含任何的 `.` 、 `-` 或 空格,也不得使用英文大寫 >另外,假設需要命名為多個單字,則建議使用 `_` 來取代 `-` 下一步, 我們需要先開啟一個任意系統的手機模擬器(Android 或 IOS 都可) 接著開啟終端機,cd 到 myapp 資料夾 執行 `flutter run`(初次執行需要打包編譯所以會花上幾分鐘時間) 直到終端機中出現『r Hot reload. 🔥🔥🔥』就完成了 回到剛才開啟的模擬器,畫面中就會出現 Flutter Demo Home Page 的畫面 點擊右下角的+號可增加畫面中央的數字 原始碼的部分可以透過 VS Code 找到 `myapp/lib/main.dart` 檔案 每次更新程式碼後,可回到剛才執行 `flutter run` 的終端機中,輸入 `r` 進行熱加載 (即不需關閉再重新執行,而是直接重新執行,與 nodemon 相似) 另外除了通過終端機執行 `flutter run` 啟動 flutter 之外 **這邊更推薦的作法則是直接使用 VS Code 選單列中的『執行>執行但不進行偵錯』來開啟服務** (快捷鍵是 `control` + `F5`,初次會詢問要用什麼來開啟,選擇『Dart&Flutter』即可) 該動作一樣會使用電腦目前開啟的手機模擬器顯示出 Flutter Demo Home Page 的畫面 且每次更新程式碼不需再輸入 `r` 而是會自動的執行熱加載,可以直接在模擬器中看見最新的狀態 下次開啟 VS Code 後,可以直接在 VS Code 右下方的選單列中切換設備, 點擊下圖中的 `macOS(drawin)` 即可選擇要使用哪個模擬器 ![](https://i.imgur.com/Dzror61.png) 選擇好模擬器後再使用快捷鍵 `control` + `F5` 啟動 flutter 即可 > 如果下載別人的 flutter 專案,要啟動前須先安裝所有依賴 > 類似於 `npm install`,於終端機中執行 `flutter pub get` 即可安裝 flutter 專案的依賴 ## 初步概念 - 必須精確定義每個東西的型別,常見的型別如下: ```dart= // int 整數 int age; int currentYear = 2023; // double 浮點數 double weight; double bodyWeight = 58.7; // num 數字(包含整數與浮點數) num width; num height = 200; num bodyHeight = 170.3; // print 類似 console.log 將東西打印出來 print(name); // void 聲明一個函數的返回類型為空 void main() {...}; // String 字串,可用雙引號也可用單引號(需確保使用時引號頭尾相同) String name; String roomName = "worlds"; // var 宣告一個擁有值的變量, Dart 會自動判斷 `=` 後面的資料型態 var name = "Max"; var size = 11; // class 創建對象,唯一需要用大小英文開頭命名的 class Person { var name = "Max"; var age = 30; } ``` - 在 Flutter 專案中,主要的編程都會集中於 `/lib/main.dart` 檔案中,該檔案是 flutter 的入口文件 - 在 dart 中預設會優先執行 main 函數,且該 main 函數的類型為 void - 在 flutter 中, main 函數會直接調用 Flutter 提供的 runApp(),在 runApp() 則傳入一個主要的小部件以啟動整個應用程序,像這樣 `void main()=>runApp(MyApp)` - 在 .dart 的檔案中,我們可以通過 import 來引入第三方包或是其他的 .dart 檔案來使用,比如引入第三方包 material 寫作 `import 'package:flutter/material.dart';` - 在 flutter 中所有的東西都是由小部件堆疊而成,所有小部件都是在畫面上所看到的 UI 元件,比如 navbar、image、list 等等,且這些小部件底下可能還包含了另外的小部件,比如 list 小部件可能就包含每個項目的 list 的 item 小部件 - `extends` 表示繼承。我們可以建立一個 `class` ,並讓該 `class` 繼承其他 `class` 的方法及變數,以進行程式碼復用,舉例來說 `StatelessWidget` 是 material 提供的一個 `class`,我們可以建立一個新的 `class` 來繼承 `StatelessWidget` 的方法及變數: ```dart= class App extends StatelessWidget { // 建立 class App 繼承 material 提供的 StatelessWidget Widget build(BuildContext context) { // 調用 build 方法 return MaterialApp( home: Text('Hello!') ); // 回傳可被實際渲染的小部件 } } ``` - 在 dart 中,我們可以引入其他的 dart 文件,並使用其函數或變量,但當有某個函數或變量不想遭到別的 dart 文件訪問,則可以於定義該函數或變量時,於該函數或變量名稱的最前方加入一個下底線,以告知 dart 此物件不得被別的文件訪問,僅能在當前 dart 文件中使用