Images and Assets
Bundling local images as assets and loading images from the network, plus handling load states.
2 min de lectura
Apps need images — icons, illustrations, photos from an API. Flutter distinguishes between assets (files bundled into your app at build time) and network images (fetched at runtime), and handles each a little differently.
Declaring assets
Local images live in your project (commonly under an assets/ folder) and must be declared in pubspec.yaml before Flutter will bundle them:
flutter:
uses-material-design: true
assets:
- assets/images/logo.png
- assets/images/Listing a specific file bundles just that file; listing a folder (with a trailing slash) bundles everything in it. After editing pubspec.yaml, run flutter pub get (or restart flutter run) for the change to take effect — asset declarations aren't picked up by hot reload.
Displaying a local image
Image.asset(
'assets/images/logo.png',
width: 120,
fit: BoxFit.contain,
)fit controls how the image is scaled to fill the box defined by width/height. BoxFit.cover fills the space and crops overflow (common for banner photos), BoxFit.contain scales down to fit without cropping (common for logos), and BoxFit.fitWidth/fitHeight match one dimension exactly.
Displaying a network image
Image.network(
'https://example.com/photo.jpg',
width: double.infinity,
height: 200,
fit: BoxFit.cover,
loadingBuilder: (context, child, progress) {
if (progress == null) return child;
return const Center(child: CircularProgressIndicator());
},
errorBuilder: (context, error, stackTrace) {
return const Icon(Icons.broken_image, color: Colors.grey);
},
)Unlike a bundled asset, a network image has to be downloaded first, which means it can be slow or fail. loadingBuilder lets you show a spinner while bytes are still arriving, and errorBuilder lets you show a fallback instead of a broken-image crash if the URL 404s or the device is offline. Skipping these two callbacks is a common source of janky-looking apps — always plan for both the loading and failure states of a network image, not just the happy path.
Resolution-aware assets
Screens have different pixel densities, and Flutter can serve higher-resolution images automatically if you provide them. Alongside assets/images/logo.png, add 2.0x and 3.0x variants in matching subfolders:
assets/images/logo.png
assets/images/2.0x/logo.png
assets/images/3.0x/logo.png
Referencing assets/images/logo.png in code is unchanged — Flutter picks the right variant for the device's pixel ratio automatically, so you don't need separate code paths per density.
Rounding and clipping
Images are rectangular by default. To round corners or clip to a shape, wrap the image rather than looking for a "borderRadius" property on Image itself:
ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.network(
'https://example.com/avatar.jpg',
width: 64,
height: 64,
fit: BoxFit.cover,
),
)This mirrors a theme you've seen before in this course: individual widgets stay narrow in purpose, and you compose a wrapper (ClipRRect) around them to add behavior they don't have natively.