跳至主要內容

新增資源與圖片

Flutter 應用程式可以包含程式碼和資源 (有時稱為資源檔案)。資源是與您的應用程式一起打包和部署的檔案,並且可以在執行時存取。常見的資源類型包括靜態資料 (例如 JSON 檔案)、組態檔、圖示和圖片 (JPEG、WebP、GIF、動畫 WebP/GIF、PNG、BMP 和 WBMP)。

指定資源

#

Flutter 使用位於您專案根目錄的 pubspec.yaml 檔案來識別應用程式所需的資源。

以下是一個範例

yaml
flutter:
  assets:
    - assets/my_icon.png
    - assets/background.png

若要包含目錄下的所有資源,請指定目錄名稱,並在結尾加上 / 字元

yaml
flutter:
  assets:
    - directory/
    - directory/subdirectory/

資源綁定

#

flutter 區段的 assets 子區段指定應包含在應用程式中的檔案。每個資源都由一個明確的路徑 (相對於 pubspec.yaml 檔案) 識別,該路徑是資源檔案所在的位置。宣告資源的順序並不重要。使用的實際目錄名稱 (第一個範例中的 assets 或上述範例中的 directory) 並不重要。

在建置期間,Flutter 會將資源放入一個稱為資源組合的特殊封存檔中,應用程式會在執行時從該封存檔讀取。

在建置時自動轉換資源檔案

#

Flutter 支援使用 Dart 套件在建置應用程式時轉換資源檔案。若要執行此操作,請在您的 pubspec 檔案中指定資源檔案和轉換器套件。若要瞭解如何執行此操作並編寫您自己的資源轉換套件,請參閱在建置時轉換資源

根據應用程式版本條件式綁定資源

#

如果您的專案使用 版本功能,您可以將個別資源配置為僅在應用程式的特定版本中綁定。如需更多資訊,請查看根據版本條件式綁定資源

載入資源

#

您的應用程式可以透過 AssetBundle 物件存取其資源。

資源組合上的兩個主要方法可讓您從組合中載入字串/文字資源 (loadString()) 或圖片/二進位資源 (load()),給定一個邏輯鍵。邏輯鍵會對應到建置時在 pubspec.yaml 檔案中指定的資源路徑。

載入文字資源

#

每個 Flutter 應用程式都有一個 rootBundle 物件,可讓您輕鬆存取主要的資源組合。可以使用 package:flutter/services.dart 中的 rootBundle 全域靜態變數直接載入資源。

但是,建議使用 DefaultAssetBundle 取得目前 BuildContextAssetBundle,而不是使用應用程式建置的預設資源組合;這種方法可讓父 Widget 在執行時替換不同的 AssetBundle,這對於本地化或測試情境很有用。

通常,您會使用 DefaultAssetBundle.of() 間接從應用程式的執行階段 rootBundle 載入資源,例如 JSON 檔案。

Widget 內容之外,或當 AssetBundle 的處理程式不可用時,您可以使用 rootBundle 直接載入此類資源。例如

dart
import 'package:flutter/services.dart' show rootBundle;

Future<String> loadAsset() async {
  return await rootBundle.loadString('assets/config.json');
}

載入圖片

#

若要載入圖片,請在 Widget 的 build() 方法中使用 AssetImage 類別。

例如,您的應用程式可以從先前範例中的資源宣告載入背景圖片

dart
return const Image(image: AssetImage('assets/background.png'));

解析度感知的圖片資源

#

Flutter 可以為目前的 裝置像素比載入適合解析度的圖片。

AssetImage 會將邏輯要求的資源對應到最符合目前 裝置像素比 的資源。

若要使此對應運作,資源應根據特定的目錄結構排列

.../image.png
.../Mx/image.png
.../Nx/image.png
...etc.

其中 MN 是數值識別碼,對應於其中包含的圖片的名義解析度。換句話說,它們指定圖片預期的裝置像素比。

在此範例中,image.png 被視為主要資源,而 Mx/image.pngNx/image.png 被視為變體

假設主要資源對應於 1.0 的解析度。例如,請考慮名為 my_icon.png 的圖片的下列資源配置

.../my_icon.png       (mdpi baseline)
.../1.5x/my_icon.png  (hdpi)
.../2.0x/my_icon.png  (xhdpi)
.../3.0x/my_icon.png  (xxhdpi)
.../4.0x/my_icon.png  (xxxhdpi)

在裝置像素比為 1.8 的裝置上,會選擇資源 .../2.0x/my_icon.png。對於裝置像素比為 2.7 的裝置,會選擇資源 .../3.0x/my_icon.png

如果未在 Image Widget 上指定已轉譯圖片的寬度和高度,則會使用名義解析度來縮放資源,使其佔用的螢幕空間量與主要資源相同,只是具有較高的解析度。也就是說,如果 .../my_icon.png 為 72px x 72px,則 .../3.0x/my_icon.png 應為 216px x 216px;但如果未指定寬度和高度,則它們都會轉譯為 72px x 72px (以邏輯像素為單位)。

綁定解析度感知圖片資源

#

您只需要在 pubspec.yamlassets 區段中指定主要資源或其父目錄。Flutter 會為您綁定變體。每個項目都應對應到一個真實檔案,主要資源項目除外。如果主要資源項目不對應到真實檔案,則會使用解析度最低的資源作為裝置像素比低於該解析度的裝置的回退。但是,該項目仍應包含在 pubspec.yaml 清單中。

使用預設資源組合的任何項目在載入圖片時都會繼承解析度感知功能。(如果您使用某些較低層級的類別,例如 ImageStreamImageCache,您也會注意到與縮放相關的參數。)

套件相依性中的圖片資源

#

若要從 套件 相依性載入圖片,必須將 package 引數提供給 AssetImage

例如,假設您的應用程式依賴於名為 my_icons 的套件,該套件具有下列目錄結構

.../pubspec.yaml
.../icons/heart.png
.../icons/1.5x/heart.png
.../icons/2.0x/heart.png
...etc.

若要載入圖片,請使用

dart
return const AssetImage('icons/heart.png', package: 'my_icons');

套件本身使用的資源也應使用如上所述的 package 引數提取。

綁定套件資源

#

如果在套件的 pubspec.yaml 檔案中指定所需的資源,則會自動與應用程式綁定。特別是,套件本身使用的資源必須在其 pubspec.yaml 中指定。

套件也可以選擇在其 lib/ 資料夾中擁有未在其 pubspec.yaml 檔案中指定的資源。在這種情況下,若要綁定這些圖片,應用程式必須指定要在其 pubspec.yaml 中包含哪些圖片。例如,名為 fancy_backgrounds 的套件可能具有下列檔案

.../lib/backgrounds/background1.png
.../lib/backgrounds/background2.png
.../lib/backgrounds/background3.png

若要包含,例如第一個圖片,應用程式的 pubspec.yaml 應在其 assets 區段中指定它

yaml
flutter:
  assets:
    - packages/fancy_backgrounds/backgrounds/background1.png

lib/ 是隱含的,因此不應包含在資源路徑中。

如果您正在開發套件,若要在套件內載入資源,請在套件的 pubspec.yaml 中指定它

yaml
flutter:
  assets:
    - assets/images/

若要在您的套件內載入圖片,請使用

dart
return const AssetImage('packages/fancy_backgrounds/backgrounds/background1.png');

與底層平台分享資源

#

Flutter 資源可以透過 Android 上的 AssetManager 和 iOS 上的 NSBundle 輕鬆地供平台程式碼使用。

在 Android 中載入 Flutter 資源

#

在 Android 上,資源可以透過 AssetManager API 使用。在例如 openFd 中使用的查閱鍵是從 PluginRegistry.Registrar 上的 lookupKeyForAssetFlutterView 上的 getLookupKeyForAsset 取得的。PluginRegistry.Registrar 在開發外掛程式時可用,而 FlutterView 會是在開發包含平台檢視的應用程式時的選擇。

例如,假設您已在您的 pubspec.yaml 中指定下列內容

yaml
flutter:
  assets:
    - icons/heart.png

這反映了您的 Flutter 應用程式中的下列結構。

.../pubspec.yaml
.../icons/heart.png
...etc.

若要從您的 Java 外掛程式碼存取 icons/heart.png,請執行下列操作

java
AssetManager assetManager = registrar.context().getAssets();
String key = registrar.lookupKeyForAsset("icons/heart.png");
AssetFileDescriptor fd = assetManager.openFd(key);

在 iOS 中載入 Flutter 資源

#

在 iOS 上,資源可以透過 mainBundle 使用。在例如 pathForResource:ofType: 中使用的查閱鍵是從 FlutterPluginRegistrar 上的 lookupKeyForAssetlookupKeyForAsset:fromPackage:,或 FlutterViewController 上的 lookupKeyForAsset:lookupKeyForAsset:fromPackage: 取得的。FlutterPluginRegistrar 在開發外掛程式時可用,而 FlutterViewController 會是在開發包含平台檢視的應用程式時的選擇。

例如,假設您有來自上方的 Flutter 設定。

若要從您的 Objective-C 外掛程式碼存取 icons/heart.png,您會執行下列操作

objc
NSString* key = [registrar lookupKeyForAsset:@"icons/heart.png"];
NSString* path = [[NSBundle mainBundle] pathForResource:key ofType:nil];

若要從您的 Swift 應用程式存取 icons/heart.png,您會執行下列操作

swift
let key = controller.lookupKey(forAsset: "icons/heart.png")
let mainBundle = Bundle.main
let path = mainBundle.path(forResource: key, ofType: nil)

如需更完整的範例,請參閱 pub.dev 上 Flutter video_player 外掛程式的實作。

pub.dev 上的 ios_platform_images 外掛程式將此邏輯包裝在一個方便的類別中。您可以按如下方式提取圖片

Objective-C

objc
[UIImage flutterImageWithName:@"icons/heart.png"];

Swift

swift
UIImage.flutterImageNamed("icons/heart.png")

在 Flutter 中載入 iOS 圖片

#

當您透過將 Flutter 新增至現有的 iOS 應用程式來實作 Flutter 時,您可能會在 iOS 中託管要在 Flutter 中使用的圖片。若要完成此操作,請使用 pub.dev 上提供的 ios_platform_images 外掛程式。

平台資源

#

在平台專案中,還有其他情況需要直接使用資源。以下是兩個常見的案例,在 Flutter 框架載入和執行之前會使用到資源。

更新應用程式圖示

#

更新 Flutter 應用程式的啟動圖示,與更新原生 Android 或 iOS 應用程式的啟動圖示方式相同。

Launch icon

Android

#

在您的 Flutter 專案根目錄中,導覽至 .../android/app/src/main/res。各種點陣圖資源資料夾,例如 mipmap-hdpi,已經包含名為 ic_launcher.png 的佔位符圖片。請將它們替換為您想要的資源,並遵循Android 開發人員指南中指示的每個螢幕密度建議的圖示大小。

Android icon location

iOS

#

在您的 Flutter 專案根目錄中,導覽至 .../ios/RunnerAssets.xcassets/AppIcon.appiconset 目錄已經包含佔位符圖片。請將它們替換為適當大小的圖片,其大小由 Apple 人機介面指南中規定的檔案名稱所指示。請保留原始的檔案名稱。

iOS icon location

更新啟動畫面

#

Launch screen

Flutter 還使用原生平台機制,在 Flutter 框架載入時,將過渡啟動畫面繪製到您的 Flutter 應用程式。此啟動畫面會持續存在,直到 Flutter 渲染您應用程式的第一個影格。

Android

#

要將啟動畫面(也稱為「初始畫面」)新增到您的 Flutter 應用程式,請導覽至 .../android/app/src/main。在 res/drawable/launch_background.xml 中,使用此圖層清單可繪製 XML 來客製化您的啟動畫面的外觀。現有的範本提供了將圖片新增到白色初始畫面中間的範例,其程式碼已註解。您可以取消註解或使用其他可繪製物件來達到預期的效果。

如需更多詳細資訊,請參閱為您的 Android 應用程式新增初始畫面

iOS

#

要將圖片新增到您的「初始畫面」中心,請導覽至 .../ios/Runner。在 Assets.xcassets/LaunchImage.imageset 中,放入名為 LaunchImage.png[email protected][email protected] 的圖片。如果您使用不同的檔案名稱,請更新同一目錄中的 Contents.json 檔案。

您也可以在 Xcode 中開啟 .../ios/Runner.xcworkspace,完全客製化您的啟動畫面情節提要。在專案導覽器中導覽至 Runner/Runner,並透過開啟 Assets.xcassets 或使用 LaunchScreen.storyboard 中的介面建構器進行任何客製化,以放入圖片。

Adding launch icons in Xcode

如需更多詳細資訊,請參閱為您的 iOS 應用程式新增初始畫面