Text, Icons & Images
The Visual Vocabulary of Flutter
Open interactive version (quiz + challenge)Real-world analogy
What is it?
Text, Icons, and Images are the three most fundamental presentation widgets in Flutter. Text renders strings with customizable typography. Icon displays vector symbols from icon fonts. Image loads and displays raster graphics from local assets or remote URLs. These widgets are the visual building blocks that make your app communicate with users. They are lightweight, highly customizable, and designed to work seamlessly with Flutter's theming system.
Real-world relevance
In team_mvp_kit, every screen uses these widgets. Text displays user names, labels, prices, error messages, and descriptions. Icons serve as visual shortcuts in navigation bars, buttons, and status indicators. Images display user avatars, product photos, and branding assets. The project uses Theme.of(context).textTheme for consistent text styling and CircleAvatar for all user profile pictures. Network images are loaded with error handling to gracefully show placeholders when the connection fails.
Key points
- Text Widget Basics — The Text widget displays a string of text with a single style. It is the most fundamental way to show words on screen. By default, it uses the nearest DefaultTextStyle from the widget tree.
- TextStyle: Full Control — TextStyle gives you control over font size, weight, color, letter spacing, decoration, shadows, and more. Use Theme.of(context).textTheme for consistent styles rather than hardcoding values.
- Rich Text with TextSpan — Use RichText or Text.rich to display text with mixed styles in a single widget. Each TextSpan can have its own style and even tap handlers via recognizer.
- Text Overflow & Wrapping — Control what happens when text is too long: ellipsis cuts with dots, fade fades the edge, clip hard-clips. Use maxLines to limit line count. By default, Text wraps to multiple lines.
- Icon Widget — The Icon widget displays a Material Design icon from the Icons class. Over 2,000 icons are built into Flutter. Icons scale with the app's text scale factor and respond to theme colors.
- Icon Buttons — IconButton wraps an Icon with a tap target and optional splash effect. Use it in AppBars, toolbars, and anywhere you need a tappable icon. Material 3 adds filled, outlined, and tonal variants.
- Image.asset: Local Images — Load images bundled with your app from the assets folder. Declare assets in pubspec.yaml first. Flutter supports PNG, JPEG, GIF, WebP, and BMP. Use resolution-aware assets (2x, 3x) for crisp display.
- Image.network: Remote Images — Load images from a URL. Always handle loading and error states. Use the loadingBuilder and errorBuilder parameters. For production apps, use cached_network_image package for caching.
- CircleAvatar for Profile Pictures — CircleAvatar is a convenient widget for displaying user avatars. It handles circular clipping, fallback text, and background colors automatically. Used extensively in team_mvp_kit for user profiles.
Code example
import 'package:flutter/material.dart';
class UserProfileHeader extends StatelessWidget {
final String name;
final String email;
final String? avatarUrl;
final bool isVerified;
const UserProfileHeader({
super.key,
required this.name,
required this.email,
this.avatarUrl,
this.isVerified = false,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final colorScheme = theme.colorScheme;
return Padding(
padding: const EdgeInsets.all(24),
child: Column(
children: [
Stack(
children: [
CircleAvatar(
radius: 48,
backgroundColor: colorScheme.primaryContainer,
backgroundImage: avatarUrl != null
? NetworkImage(avatarUrl!)
: null,
child: avatarUrl == null
? Text(
name[0].toUpperCase(),
style: theme.textTheme.headlineMedium?.copyWith(
color: colorScheme.onPrimaryContainer,
),
)
: null,
),
if (isVerified)
Positioned(
right: 0,
bottom: 0,
child: Container(
padding: const EdgeInsets.all(2),
decoration: BoxDecoration(
color: colorScheme.surface,
shape: BoxShape.circle,
),
child: Icon(
Icons.verified,
size: 24,
color: colorScheme.primary,
),
),
),
],
),
const SizedBox(height: 16),
Text(
name,
style: theme.textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
email,
style: theme.textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurfaceVariant,
),
),
],
),
);
}
}Line-by-line walkthrough
- 1. Import Flutter material library
- 2. Define UserProfileHeader as a StatelessWidget
- 3. Declare required name and email, optional avatarUrl, and isVerified flag
- 4. Const constructor with named parameters
- 5. In build, get theme and colorScheme for consistent styling
- 6. Return Padding with 24px on all sides for outer spacing
- 7. Column to stack avatar, name, and email vertically
- 8. Stack widget to overlay the verified badge on top of the avatar
- 9. CircleAvatar with radius 48 for a prominent profile picture
- 10. Set backgroundColor to primaryContainer for a themed fallback color
- 11. If avatarUrl exists, load it as a NetworkImage for backgroundImage
- 12. If no avatar URL, show the first letter of the name as fallback text
- 13. Style the fallback letter with headlineMedium in onPrimaryContainer color
- 14. Conditionally add verified badge only if isVerified is true
- 15. Position the badge at bottom-right of the avatar using Positioned
- 16. Wrap the badge icon in a Container with surface-colored circle background
- 17. Show the verified icon in primary color at size 24
- 18. SizedBox height 16 for spacing between avatar and name
- 19. Text widget for name using titleLarge style with bold weight
- 20. SizedBox height 4 for tight spacing between name and email
- 21. Text widget for email using bodyMedium in a muted variant color
Spot the bug
Image.network(
'https://example.com/photo.jpg',
width: 200,
height: 200,
)
Image.asset(
'assets/logo.png',
width: 100,
)Need a hint?
Show answer
Explain like I'm 5
Fun fact
Hands-on challenge
More resources
- Text Widget (api.flutter.dev)
- Image Widget (api.flutter.dev)
- Icon Widget (api.flutter.dev)