Flutter Lesson 12 of 83 3 min read
Images and Icons in Flutter
Show images in Flutter from assets and the network, control fit and shape, handle loading and errors, and use Material icons.
On this page
Icons #
Flutter ships with the Material icon set.
const Icon(Icons.favorite, color: Colors.red, size: 32)
const Icon(Icons.star_outline)
Many icons come in _outlined, _rounded and _sharp variants. For iOS-style icons, import package:flutter/cupertino.dart and use CupertinoIcons.
Images from the network #
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: Center(
child: Image.network(
'https://picsum.photos/400/300',
width: 300,
height: 200,
fit: BoxFit.cover,
loadingBuilder: (context, child, progress) {
if (progress == null) return child;
return const SizedBox(
width: 300,
height: 200,
child: Center(child: CircularProgressIndicator()),
);
},
errorBuilder: (context, error, stackTrace) {
return const SizedBox(
width: 300,
height: 200,
child: Center(child: Icon(Icons.broken_image, size: 48)),
);
},
),
),
),
),
);
}
Always give a network image a size, a loading state and an error state. Networks fail.
For real apps, the cached_network_image package stores downloaded images on the device so they load instantly next time.
Images from your project #
- Put the file in a folder, for example
assets/images/logo.png. - Declare it in
pubspec.yaml:
flutter:
assets:
- assets/images/
- Use it:
Image.asset('assets/images/logo.png', width: 120)
After editing pubspec.yaml, stop and run the app again. If the image does not appear, check the indentation in the YAML and the spelling of the path.
Sharp images on every screen #
Provide higher-resolution versions in 2.0x and 3.0x folders. Flutter picks the right one for the device.
assets/images/logo.png (100 x 100)
assets/images/2.0x/logo.png (200 x 200)
assets/images/3.0x/logo.png (300 x 300)
BoxFit: how the image fills its box #
fit | Behaviour |
|---|---|
BoxFit.cover | Fills the box, cropping if needed. The usual choice for photos |
BoxFit.contain | Shows the whole image, leaving empty space if needed. Good for logos |
BoxFit.fill | Stretches to fill. Distorts |
BoxFit.fitWidth / fitHeight | Matches one dimension |
BoxFit.scaleDown | Like contain, but never enlarges |
Rounded corners and circles #
ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network('https://picsum.photos/300', width: 150, height: 150, fit: BoxFit.cover),
)
const CircleAvatar(
radius: 32,
backgroundImage: NetworkImage('https://picsum.photos/200'),
)
const CircleAvatar(radius: 32, child: Text('AR')) // initials as a fallback
Keep a steady shape while loading #
AspectRatio reserves the right amount of space, so the layout does not jump when the image arrives.
AspectRatio(
aspectRatio: 16 / 9,
child: Image.network(url, fit: BoxFit.cover),
)
An image as a background #
Container(
height: 200,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/banner.jpg'),
fit: BoxFit.cover,
),
),
alignment: Alignment.bottomLeft,
padding: const EdgeInsets.all(16),
child: const Text('Summer sale', style: TextStyle(color: Colors.white, fontSize: 24)),
)
SVG and other formats #
Image supports PNG, JPEG, GIF, WebP and BMP. For SVG files, add the flutter_svg package and use SvgPicture.asset(...).
Performance tips #
- Do not load a 4000-pixel photo to show it at 100 pixels. Ask the server for a smaller size, or pass
cacheWidthso Flutter decodes a smaller version. - Use
ListView.builderfor lists of images, so only visible ones are loaded. - Prefer WebP or compressed JPEG for photos, and PNG or SVG for logos and icons.
Try it yourself #
Build a profile header: a circular photo from the network with initials as the fallback, a name, and a row of three icons with labels (posts, followers, following).