Flutter apps can include both code and assets (sometimes called resources). Common types of assets include:
- static data (JSON files)
- configuration files
- icons and images (JPEG, WebP, GIF, animated WebP/GIF, PNG, BMP, and WBMP)
The pubspec.yaml file is used to identify the required assets.
To include all assets under a directory, specify the directory name with the /
character at the end:
flutter:
assets:
- assets/my_icon.png
- directory/
- directory/subdirectory/
Access its assets through an AssetBundle object.
The two main methods on an asset bundle allow you to load out of the bundle, given a logical key maps to the path to the asset specified in the pubspec.yaml
file:
- a string/text asset (
loadString()
) - an image/binary asset (
load()
)
Each app has a rootBundle object for easy access to the main asset bundle from package:flutter/services.dart
.
It's recommended to obtain the AssetBundle
for the current BuildContext
using DefaultAssetBundle, rather than the default asset bundle that was built with the app (e.g., Use DefaultAssetBundle.of()
to indirectly load an asset, for example a JSON file, from the app's runtime rootBundle
) → enables a parent widget to substitute a different AssetBundle
at run time, which can be useful for localization or testing scenarios.
Outside of a Widget
context, or when a handle to an AssetBundle
is not available, you can use rootBundle to directly load such assets. For example:
import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/config.json');
}
To load an image, use the AssetImage class in a widget's build()
method.
return const Image(image: AssetImage('assets/background.png'));
AssetImage
will map a logical requested asset onto one that most closely matches the current device pixel ratio. For this to work, assets should be arranged according to a particular directory structure. For example:
.../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.5
in 1.5x
are numeric identifiers that correspond to the nominal resolution of the images contained within. It specifies the device pixel ratio that the images are intended for. On devices with a device pixel ratio of 1.8
, the asset .../2.0x/my_icon.png
is chosen.
Device pixel ratio depends on MediaQueryData.size, which requires having either MaterialApp
or CupertinoApp
as an ancestor of your AssetImage
.
Only need to specify the main asset or its parent directory in the assets section of pubspec.yaml
. Flutter will bundle the variants.
To load an image from a package dependency, the package
argument must be provided to AssetImage
:
return const AssetImage('icons/heart.png', package: 'my_icons');
Assets used by the package itself must be specified in its pubspec.yaml
.
A package can also choose to have assets in its lib/
folder that are not specified in its pubspec.yaml
file. In this case,the application has to specify which ones to include in its pubspec.yaml
(The lib/
is implied, so it should not be included in the asset path). For example:
flutter:
assets:
- packages/fancy_backgrounds/backgrounds/background1.png
Flutter assets are readily available to platform code using the AssetManager
on Android and NSBundle
on iOS
The assets are available through the AssetManager API.
AssetManager assetManager = registrar.context().getAssets();
String key = registrar.lookupKeyForAsset("icons/heart.png");
AssetFileDescriptor fd = assetManager.openFd(key);
The assets are available through the mainBundle.
let key = controller.lookupKey(forAsset: "icons/heart.png")
let mainBundle = Bundle.main
let path = mainBundle.path(forResource: key, ofType: nil)
Use the ios_platform_images plugin available on pub.dev.
Below are two common cases where assets are used before the Flutter framework is loaded and running:
Navigate to .../android/app/src/main/res
and replace images named ic_launcher.png
with your desired assets respecting the recommended icon size per screen density.
Navigate to .../ios/Runner
and replace the Assets.xcassets/AppIcon.appiconset
directory that already contains placeholder images with the appropriately sized images.
If you you don't call runApp()
in the main()
function of your app, the launch screen persists forever.
Navigate to .../android/app/src/main
. In res/drawable/launch_background.xml
, use this layer list drawable XML to customize the look of your launch screen.
Ref: Adding a splash screen to your Android app.
Navigate to .../ios/Runner
. In ssets.xcassets/LaunchImage.imageset
, update the images named LaunchImage.png
, [email protected]
, [email protected]
.