Images, icons and assets

Flutter · Essentials · 8 min

Logos, illustrations and avatars appear on almost every screen, and misconfigured assets are a common first bug.

Files bundled with the app — images, JSON, fonts — are assets, declared in pubspec.yaml:

flutter:
  assets:
    - assets/images/
    - assets/data/countries.json

Listing a directory includes its files (not subdirectories). After editing pubspec.yaml, do a full restart; hot reload doesn't pick up new assets.

Showing images:

  • Image.asset('assets/images/logo.png', width: 120).
  • Image.network(url, fit: BoxFit.cover, loadingBuilder: ..., errorBuilder: ...) — always provide an errorBuilder for network images. The cached_network_image package adds disk caching.
  • fit controls scaling (cover, contain, fill...), like CSS object-fit.
  • CircleAvatar(backgroundImage: NetworkImage(url)) for avatars.

Resolution variants: put 2.0x/logo.png and 3.0x/logo.png next to logo.png, and Flutter picks the right one for the device pixel ratio.

Icons: Icon(Icons.home) uses the bundled Material Icons font; cupertino_icons provides iOS-style ones. SVGs need the flutter_svg package.

Read text assets with await rootBundle.loadString('assets/data/countries.json') (from package:flutter/services.dart).

Decoding big images costs memory: pass cacheWidth/cacheHeight to decode at display size for thumbnails.

Example

import 'package:flutter/material.dart';

// pubspec.yaml:
// flutter:
//   assets:
//     - assets/images/        (logo.png, 2.0x/logo.png, 3.0x/logo.png)

class Header extends StatelessWidget {
  const Header({super.key, required this.avatarUrl});
  final String avatarUrl;

  @override
  Widget build(BuildContext context) => Row(spacing: 12, children: [
        Image.asset('assets/images/logo.png', height: 40),
        const Icon(Icons.verified, color: Colors.blue),
        const Spacer(),
        ClipOval(
          child: Image.network(avatarUrl,
              width: 40, height: 40, fit: BoxFit.cover,
              cacheWidth: 120,                             // decode small
              errorBuilder: (context, error, stack) => const Icon(Icons.person)),
        ),
      ]);
}

Remember

  • Declare assets in pubspec.yaml, then hot restart
  • Always give network images an errorBuilder
  • Use 2.0x/3.0x variants and cacheWidth for crisp, memory-friendly images

Watch out for

  • Forgetting to list the asset folder in pubspec.yaml, causing "Unable to load asset".

Check yourself

  1. You added assets/images/ to pubspec.yaml, but files in assets/images/icons/ aren't found. Why?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.flutter.dev/ui/assets/assets-and-images

Builds on

Unlocks

Nothing builds on this yet.