The Flutter APP installation package will contain two parts: code and assets. Assets are packaged in the program installation package and can be accessed at runtime. Common types of assets include static data (such as JSON files), configuration files, icons and pictures (JPEG, WebP, GIF, animated WebP/GIF, PNG, BMP and WBMP), etc.
Like package management, Flutter also uses pubspec.yamlfiles to manage the resources required by the application, for example:
flutter:
assets:
- assets/my_icon.png
- assets/background.png
assetsSpecify the files that should be included in the application. Each asset pubspec.yamlidentifies its path relative to the file system path where the file is located. The order of asset declaration is irrelevant. The actual directory of the asset can be any folder (in this example, the asset folder).
During the build, Flutter places assets in special archives called asset bundles , and the application can read them (but not modify them) at runtime.
The build process supports the concept of "asset variants": different versions of assets may be displayed in different contexts. When pubspec.yamlthe asset path is specified in the assets section, during the build process, any file with the same name will be searched in adjacent subdirectories. These files will then be included in the asset bundle along with the specified asset.
For example, if the following files are in the application directory:
- … / Pubspec.yaml
- …/graphics/my_icon.png
- …/graphics/background.png
- …/graphics/dark/background.png
- …etc.
Then the pubspec.yamlfile only needs to include:
flutter:
assets:
- graphics/background.png
Then these two graphics/background.pngand graphics/dark/background.pngwill be included in your asset bundle. The former is considered a main asset , and the latter is considered a variant.
When selecting images that match the current device resolution, Flutter will use asset variants (see below). In the future, Flutter may extend this mechanism to localization, reading prompts, etc.
Your app can AssetBundleaccess its assets through objects. There are two main ways to allow loading of strings or image (binary) files from the Asset bundle.
rootBundleLoad via object: Every Flutter application has anrootBundleobject, through which you can easily access the main resource package, and directly usepackage:flutter/services.dartthe global staticrootBundleobject to load the asset.- By
DefaultAssetBundleloading: It is recommendedDefaultAssetBundleto get the current BuildContext of AssetBundle. This method is not to use the default asset bundle built by the application, but to make the parent widget dynamically replace a different AssetBundle at runtime, which is useful for localization or testing scenarios.
Generally, you can DefaultAssetBundle.of()load assets (such as JSON files) indirectly while the application is running, and AssetBundleyou can rootBundleload these assets directly outside of the widget context or when other handles are not available , for example:
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/config.json');
}
Similar to native development, Flutter can also load images suitable for the current device's resolution.
AssetImageThe asset request logic can be mapped to the asset closest to the current device pixel ratio (dpi). In order for this mapping to work, assets must be saved according to a specific directory structure:
- …/image.png
- …/Mx/image.png
- …/Nx/image.png
- …etc.
Where M and N are numeric identifiers, corresponding to the resolution of the image contained therein, that is, they specify pictures of different device pixel ratios.
The main resource corresponds to 1.0 times the resolution picture by default. Look at an example:
- …/my_icon.png
- …/2.0x/my_icon.png
- …/3.0x/my_icon.png
It .../2.0x/my_icon.pngwill be selected on a device with a device pixel ratio of 1.8 . For a device pixel ratio of 2.7, it .../3.0x/my_icon.pngwill be selected.
If Imagethe width and height of the rendered image are not specified on the widget, the Imagewidget will occupy the same screen space as the main resource. In other words, if it .../my_icon.pngis 72px by 72px, then it .../3.0x/my_icon.pngshould be 216px by 216px; but if the width and height are not specified, they will all be rendered as 72 pixels × 72 pixels (in logical pixels).
pubspec.yamlEach item in the asset section should correspond to the actual file, except for the main resource item. When the main resource lacks a certain resource, it will be selected in the order of resolution from low to high, that is to say, if it is not in 1x, it will be found in 2x, and if it is not in 2x, it will be found in 3x.
To load pictures, you can use AssetImagethe class. For example, we can load the background image from the asset declaration above:
Widget build(BuildContext context) {
return new DecoratedBox(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('graphics/background.png'),
),
),
);
}
Note that it AssetImageis not a widget, it is actually one ImageProvider. Sometimes you may expect to get a widget that displays pictures directly, then you can use Image.asset()methods such as:
Widget build(BuildContext context) {
return Image.asset('graphics/background.png');
}
When using the default asset bundle to load resources, the resolution is automatically processed internally, which is imperceptible to developers. (If you use some of the lower-level classes, such as ImageStreamor ImageCacheyou will notice that there are associated with the scaling parameter)
To load the image in the dependent package, you must AssetImageprovide packageparameters.
For example, suppose your application depends on a package named "my_icons", which has the following directory structure:
- … / Pubspec.yaml
- …/icons/heart.png
- …/icons/1.5x/heart.png
- …/icons/2.0x/heart.png
- …etc.
Then load the image, use:
new AssetImage('icons/heart.png', package: 'my_icons')
or
new Image.asset('icons/heart.png', package: 'my_icons')
Note: The package should also be obtained by adding packageparameters when using its own resources .
If pubspec.yamlthe desired resource is declared in the file, it will be packaged into the corresponding package. In particular, the resources used by the package itself must be pubspec.yamlspecified in.
Packages can also choose lib/to include pubspec.yamlresources in their folders that are not declared in their files. In this case, for the pictures to be packaged, the application must pubspec.yamlspecify which images to include. For example, a package named "fancy_backgrounds" may contain the following files:
- …/lib/backgrounds/background1.png
- …/lib/backgrounds/background2.png
- …/lib/backgrounds/background3.png
To include the first image, it must be pubspec.yamldeclared in the assets section:
flutter:
assets:
- packages/fancy_backgrounds/backgrounds/background1.png
lib/Is implicit, so it should not be included in the asset path.
The above resources are all in the flutter application. These resources can only be used after the Flutter framework is running. If we want to set an APP icon or add a launch image to our application, then we must use the assets of a specific platform.
The way to update the startup icon of the Flutter application is the same as that of updating the startup icon in the native Android or iOS application.
- Android
In the root directory of the Flutter project, navigate to the .../android/app/src/main/resdirectory, which contains various resource folders (for example, the mipmap-hdpiplaceholder image "ic_launcher.png" is already included, see Figure 2-8). Just follow the instructions in the Android Developer Guide , replace it with the required resources, and follow the recommended icon size standards for each screen density (dpi).
Note: If you rename a .png file, you must also at your
AndroidManifest.xml's label update name attribute.<application>``android:icon
- iOS
In the root directory of the Flutter project, navigate to .../ios/Runner. The directory Assets.xcassets/AppIcon.appiconsetalready contains placeholder pictures (see Figure 2-9), just replace them with pictures of appropriate size and keep the original file name.
When the Flutter framework is loaded, Flutter will use the local platform mechanism to draw the startup page. This launch page will last until the first frame of Flutter rendering the application.
Note: This means that if you do not
main()call the runApp function in the application method (or more specifically, if you do not callwindow.renderto respondwindow.onDrawFrame), the splash screen will always be displayed.
To add a splash screen to your Flutter application, navigate to .../android/app/src/main. Now res/drawable/launch_background.xml, through the custom drawable to achieve a custom start interface (you can also directly change a picture).
To add a picture to the center of the splash screen, navigate to .../ios/Runner. In Assets.xcassets/LaunchImage.imageset, dragged into the picture and name LaunchImage.png, LaunchImage@2x.png, LaunchImage@3x.png. If you use a different file name, you must also update the Contents.jsonfile in the same directory. The specific size of the picture can be found in Apple's official standard.
You can also fully customize the storyboard by opening Xcode. Navigate to the Project Navigator Runner/Runnerand Assets.xcassetsdrag in the picture by opening it , or customize it by using Interface Builder in LaunchScreen.storyboard, as shown in Figure 2-11.



