2025 iThome鐵人賽
「 Flutter :30天打造念佛App,跨平台從Mobile到VR,讓極樂世界在眼前實現! 」
Day 9
「 Flutter Flavor — 出門闖蕩 安全第一,打造多環境的專屬練功副本! 」
前幾天的文章,我們已經認識Git神裝與操作方式!
在踏上 Coding 世界大冒險前,讓我們先來認識 「多環境隔離與配置」 。
有了不同環境的隔離與配置,我們就能在需要進行開發與測試時,
隨時切換到所需的環境與對應配置,不僅開發上更便捷,
還能大膽實驗、用力測試都沒關係!
Day9 文章目錄:
一、Flavor
二、flutter_flavorizr
三、flavor icon
Flavors 的功能是在同一套程式碼中,建立多個「環境版本」的機制。
例如:開發 dev、預發布 staging、正式 prod。
每個 flavor 可以有不同的 App 名稱、圖示、Bundle ID / applicationId、
API baseUrl 等,方便我們進行開發、測試與上架管理。
- 降低風險:避免把測試設定、假資料意外推上正式版。
- 提升效率:一份程式碼快速切換環境,不用維護多個專案。
- 方便自動化:搭配 CI/CD,可以自動針對不同 Flavor 打包。
我們可以透過flutter_flavorizr快速為專案進行flavor設置
1. 修改專案中的 pubspec.yaml
dev_dependencies:
flutter_flavorizr: 2.4.1
flavorizr:
app:
android:
flavorDimensions: "app"
ios:
buildConfiguration: "Release"
flavors:
dev:
app:
name: "念佛app Dev" #自行命名
android:
applicationId: "com.example.amitabha.dev"
ios:
bundleId: "com.example.amitabha.dev"
staging:
app:
name: "念佛app Staging" #自行命名
android:
applicationId: "com.example.amitabha.staging"
ios:
bundleId: "com.example.amitabha.staging"
prod:
app:
name: "念佛app" #自行命名
android:
applicationId: "com.example.amitabha"
ios:
bundleId: "com.example.amitabha"
2.終端機執行
dart run flutter_flavorizr
✓ [assets:download] Completed (1.0s)
✓ [assets:extract] Completed (18ms)
✓ [android:androidManifest] Completed (43ms)
✓ [android:flavorizrGradle] Completed (3ms)
✓ [android:buildGradle] Completed (2ms)
✓ [android:dummyAssets] Completed (16ms)
✓ [android:icons] Completed (0ms)
✓ [flutter:flavors] Completed (1ms)
✓ [flutter:app] Completed (0ms)
✓ [flutter:pages] Completed (0ms)
✓ [flutter:main] Completed (0ms)
✓ [ios:podfile] Completed (0ms)
✓ [ios:xcconfig] Completed (1.4s)
✓ [ios:buildTargets] Completed (1.1s)
✓ [ios:schema] Completed (0.5s)
✓ [ios:dummyAssets] Completed (22ms)
✓ [ios:icons] Completed (0ms)
✓ [ios:plist] Completed (4ms)
✓ [ios:launchScreen] Completed (0.4s)
✓ [google:firebase] Completed (0ms)
✓ [huawei:agconnect] Completed (0ms)
✓ [assets:clean] Completed (4ms)
✓ [ide:config] Completed (0ms)
Flavorization process finished
iOS
Android
產生 Flavor 與共用入口
Android: build.gradle.kts 掛入外部 flavorizr.gradle.kts,定義 productFlavors 內容
iOS: 自動建立 Schemes 與 Configurations
(1)修改 Build Settings 的 Primary App Icon Set Name
打開flutter專案中iOS資料夾內的Runner.xcworkspace,
修改 Build Settings 的 Primary App Icon Set Name
Primary App Icon Set Name | Icon Set |
---|---|
Debug | AppIcon-prod |
Debug-dev | AppIcon-dev |
Debug-prod | AppIcon-prod |
Debug-staging | AppIcon-staging |
Profile | AppIcon-prod |
Profile-dev | AppIcon-dev |
Profile-prod | AppIcon-prod |
Profile-staging | AppIcon-staging |
Release | AppIcon-prod |
Release-dev | AppIcon-dev |
Release-prod | AppIcon-prod |
Release-staging | AppIcon-staging |
(2)添加iOS App Icon
打開Assets,點選下方加號+,添加 iOS APP Icon
注意,不要使用Image Set添加
Icon尺寸需要是1024x1024pt
(3)終端機執行
flutter run -d "模擬器名稱" --flavor dev -t lib/main.dart
flutter run -d "模擬器名稱" --flavor staging -t lib/main.dart
flutter run -d "模擬器名稱" --flavor prod -t lib/main.dart
接著我們來為Android的三種環境設置不同的AppIcon!
Adaptive Icon 簡介
App 圖示拆成 前景(foreground) 與 背景(background) 兩層,
再由系統或廠牌的Launcher套用不同遮罩與動化效果。
優點:同一 Icon 在不同手機都能保持一致美觀,不會被奇怪地裁切或鋸齒。
Adaptive Icon 組成:
- 前景圖(通常為透明 PNG)
- 背景(可用純色或背景圖)
- 一個 XML 指定「前景/背景」各是誰:
(1) 建立資料夾(每個 flavor 一套)
#先從根目錄移動位置到android/app
cd android/app
# 為 dev / staging / prod 建立需要的資料夾
for f in dev staging prod; do
mkdir -p "src/$f/res/mipmap-anydpi-v26" \
"src/$f/res/mipmap-xxxhdpi" \
"src/$f/res/values"
done
(2) 放置素材
a. 三張透明PNG都命名為ic_launcher_foreground.png
分別放到dev / staging / prod 的 mipmap-xxxhdpi資料夾
b. 三份colors.xml
分別放到dev / staging / prod 的 values資料夾
#建立clors.xml範例
# dev:綠色,顏色可自訂
cat > src/dev/res/values/colors.xml <<'XML'
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#27AE60</color>
</resources>
XML
# staging:橘色,顏色可自訂
cat > src/staging/res/values/colors.xml <<'XML'
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#F2994A</color>
</resources>
XML
# prod:藍色,顏色可自訂
cat > src/prod/res/values/colors.xml <<'XML'
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#2D9CDB</color>
</resources>
XML
c. 三份ic_launcher.xml
分別放到dev / staging / prod 的 mipmap-anydpi-v26/資料夾
#建立ic_launcher.xml範例
for f in dev staging prod; do
cat > "src/$f/res/mipmap-anydpi-v26/ic_launcher.xml" <<'XML'
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
XML
done
(3)終端機執行
flutter clean
flutter pub get
flutter run -d <模擬器ID> --flavor dev -t lib/main.dart
flutter run -d <模擬器ID> --flavor staging -t lib/main.dart
flutter run -d <模擬器ID> --flavor prod -t lib/main.dart
重點 | 內容 |
---|---|
Flavor | 設置 開發、預發布、正式 的專用環境 |
flutter_flavorizr | 快速創建flavor |
flavor icon | 設置不同環境的App icon |