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 為當前的 BuildContext 獲取 AssetBundle,而不是使用隨應用構建的預設資產包;這種方法允許父 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.yaml 檔案的 assets 部分指定主資產或其父目錄。Flutter 會為您捆綁變體。每個條目都應對應一個真實檔案,主資產條目除外。如果主資產條目不對應真實檔案,則解析度最低的資產將用作裝置畫素比率低於該解析度的裝置的備用。但是,該條目仍應包含在 pubspec.yaml 清單中。

任何使用預設資產包的元件在載入圖片時都會繼承解析度感知。(如果您使用一些較低級別的類,例如 ImageStreamImageCache,您還會注意到與比例相關的引數。)

包依賴中的圖片資產

#

要從 依賴項載入圖片,必須向 AssetImage 提供 package 引數。

例如,假設您的應用程式依賴於一個名為 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 外掛 的實現。

在 Flutter 中載入 iOS 圖片

#

透過將 Flutter 新增到現有的 iOS 應用來實施 Flutter 時,您可能希望在 Flutter 中使用 iOS 中託管的圖片。為此,請使用平臺通道將圖片資料作為 FlutterStandardTypedData 傳遞給 Dart。

平臺資產

#

還有其他情況下需要直接在平臺專案中處理資產。以下是在 Flutter 框架載入和執行之前使用資產的兩種常見情況。

更新應用圖示

#

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

Launch icon

Android

#

在您的 Flutter 專案的根目錄中,導航到 .../android/app/src/main/res。各種點陣圖資原始檔夾(如 mipmap-hdpi)已包含名為 ic_launcher.png 的佔位符圖片。根據 Android Developer Guide 的建議,按照螢幕密度替換為推薦圖示大小的所需資產。

Android icon location

iOS

#

在您的 Flutter 專案的根目錄中,導航到 .../ios/RunnerAssets.xcassets/AppIcon.appiconset 目錄已包含佔位符圖片。按照 Apple Human Interface Guidelines 的要求,將其替換為檔名指示的適當大小的圖片。保留原始檔名。

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.pngLaunchImage@2x.pngLaunchImage@3x.png 的圖片。如果您使用不同的檔名,請更新同一目錄中的 Contents.json 檔案。

您還可以透過開啟 .../ios/Runner.xcworkspace 在 Xcode 中完全自定義您的啟動螢幕 storyboard。在專案導航器中導航到 Runner/Runner,然後透過開啟 Assets.xcassets 放入圖片,或者使用 LaunchScreen.storyboard 中的介面構建器進行任何自定義。

Adding launch icons in Xcode

有關更多詳細資訊,請參閱為您的 iOS 應用新增閃屏