I'm trying to define some assets for my Flutter app.
This is my directory structure:
- lib
- assets
- images
└ bg_login.png <-- this one is 400x800px
└ 2.0x
└ bg_login.png <-- this one is 800x1600px.
- test
- ios
- android
- build
- pubspec.yaml
This is my pubspec file (indented with 2 whitespaces):
name: my_app
description: My App
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
assets:
- assets/images/bg_login.png
I load the image like that:
new Positioned(
top: 0.0,
width: MediaQuery.of(context).size.width,
child: Image.asset(
"assets/images/bg_login.png",
fit: BoxFit.fitWidth,
)
)
Sometimes the image loads, sometimes it fails with this error:
Launching lib\main.dart on Android SDK built for x86 in debug mode...
Initializing gradle...
Resolving dependencies...
Running 'gradlew assembleDebug'...
Built build\app\outputs\apk\debug\app-debug.apk.
Installing build\app\outputs\apk\app.apk...
Syncing files to device Android SDK built for x86...
D/ ( 3460): HostConnection::get() New Host Connection established 0xb099df40, tid 3479
D/EGL_emulation( 3460): eglMakeCurrent: 0xa325a620: ver 2 0 (tinfo 0xb0983620)
I/flutter ( 3460): ══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞════════════════════════════════════════════════════
I/flutter ( 3460): The following assertion was thrown resolving an image codec:
I/flutter ( 3460): Unable to load asset: assets/images/bg_login.png
I/flutter ( 3460):
I/flutter ( 3460): When the exception was thrown, this was the stack:
I/flutter ( 3460): #0 PlatformAssetBundle.load (package:flutter/src/services/asset_bundle.dart:221:7)
I/flutter ( 3460): <asynchronous suspension>
I/flutter ( 3460): #1 AssetBundleImageProvider._loadAsync (package:flutter/src/painting/image_provider.dart:427:44)
I/flutter ( 3460): <asynchronous suspension>
I/flutter ( 3460): #2 AssetBundleImageProvider.load (package:flutter/src/painting/image_provider.dart:412:14)
I/flutter ( 3460): #3 ImageProvider.resolve.<anonymous closure>.<anonymous closure> (package:flutter/src/painting/image_provider.dart:266:86)
I/flutter ( 3460): #4 ImageCache.putIfAbsent (package:flutter/src/painting/image_cache.dart:143:20)
I/flutter ( 3460): #5 ImageProvider.resolve.<anonymous closure> (package:flutter/src/painting/image_provider.dart:266:63)
I/flutter ( 3460): (elided 8 frames from package dart:async)
I/flutter ( 3460):
I/flutter ( 3460): Image provider: AssetImage(bundle: PlatformAssetBundle#267c3(), name: "assets/images/bg_login.png")
I/flutter ( 3460): Image key: AssetBundleImageKey(bundle: PlatformAssetBundle#267c3(), name: "assets/images/bg_login.png",
I/flutter ( 3460): scale: 1.0)
I/flutter ( 3460): ════════════════════════════════════════════════════════════════════════════════════════════════════
It really happens randomly, sometimes it works, most of the time it throws that error. I also tried with ImageAsset
, I got the same error.
What's going on? Am I missing something on how to properly declare and load images?
Well, there is a slight difference between Image.asset and AssetImage.
Image.Asset is a Widget while AssetImage is an ImageProvider.
AssetImage is the image provider which fetches the data(image) from the assets bundle. While, Image.asset is a widget to render on the screen which also in backend uses AssetImage to load image from asset bundle.
For ex :
Container requires child widget so you can provide the Image.asset but, you cannot provide AssetImage child. Also, for DecorationImage requires image property so you can assign the AssetImage while you cannot assign the Image.asset widget.
You can also find which Widget requires child widget or ImageProvider while declaring the widgets in IDE's smart suggestions.
I hope this point is clear.
In your pubspec.yaml
you can declare
flutter:
assets:
- assets/images
and still use your assets directory structure.
Flutter uses asset variants when choosing resolution appropriate images.
So it will assumes that you bg_login.png
in the images folder will be at the normal scale and for different scale's type you can have a structure ike this:
.../image.png
.../Mx/image.png
.../Nx/image.png
...etc.
where M and N are numeric identifiers that correspond to the nominal resolution of the images contained within, in other words, they specify the device pixel ratio that the images are intended for.
You can still call from the code Image.asset("assets/images/bg_login.png")
.
For reference Assets and image from Flutter.io
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With