Common Widgets

Layout widgets give your screen structure, but they're empty boxes without actual content inside them. This lesson covers the small set of widgets you'll reach for constantly to fill that structure: displaying text, images, and icons, giving users buttons to tap, and wrapping content in a nicely elevated Card. By the end, you'll have everything needed to build a real, complete piece of UI — which is exactly what the worked example at the end does.

1. Text

Text is how you display a string of text on screen. On its own it just renders using the surrounding theme's default style, but you'll almost always want to customize it with a TextStyle:

Example: Styled Text

Text(
  'Flutter Widgets',
  style: TextStyle(
    fontSize: 22,
    fontWeight: FontWeight.bold,
    color: Colors.deepPurple,
  ),
)

The three properties above — fontSize, fontWeight, and color — cover the majority of everyday text styling. TextStyle also supports letter spacing, line height, decoration (underline/strikethrough), and custom font families, all through the same constructor.

2. Image

Flutter's Image widget has several named constructors depending on where the image data is coming from. Picking the right one matters — they're not interchangeable:

ConstructorUse for
Image.asset()An image bundled inside your app (declared in pubspec.yaml) — the most common choice for logos, icons, and static illustrations
Image.network()An image loaded from a URL over the internet
Image.file()An image stored on the device's filesystem, e.g. one the user just picked from their camera or gallery
Image.memory()An image already loaded into memory as raw bytes

Example: The Two Most Common Cases

Image.asset('assets/images/logo.png', width: 120)

Image.network(
  'https://example.com/avatar.jpg',
  width: 64,
  height: 64,
  fit: BoxFit.cover,
)

Setting up bundled assets correctly (declaring them in pubspec.yaml, organizing an assets/ folder, handling different pixel densities) is its own topic — it's covered in full detail in flutter-images-assets.php.

3. Icon

Flutter ships with the entire Material Icons set built in, accessible through the Icons class. Wrap any of them in an Icon widget to display it:

Example: Icons With Custom Size and Color

Icon(Icons.favorite, color: Colors.red, size: 28)
Icon(Icons.settings)
Icon(Icons.arrow_forward_ios, size: 16)

4. The Button Family

Flutter deliberately gives you several distinct button widgets rather than one configurable button, because Material Design defines different levels of visual emphasis for different kinds of actions. Picking the right one communicates importance to the user without you needing to hand-roll custom styling:

WidgetEmphasisTypical use
ElevatedButtonHigh — filled background, shadowThe single primary action on a screen ("Submit", "Continue")
OutlinedButtonMedium — bordered, no fillA secondary action alongside a primary one ("Cancel" next to "Save")
TextButtonLow — no fill, no borderMinor or dismissive actions ("Skip", "Learn more")
IconButtonN/A — icon onlyCompact, icon-only actions, often in an AppBar (back, search, more)

Example: All Four Button Types

ElevatedButton(onPressed: () {}, child: Text('Save'))
OutlinedButton(onPressed: () {}, child: Text('Cancel'))
TextButton(onPressed: () {}, child: Text('Skip'))
IconButton(onPressed: () {}, icon: Icon(Icons.share))

All four share the same core idea: an onPressed callback that runs when tapped (setting it to null automatically disables the button and greys it out — a handy, built-in way to represent "not available yet" without extra logic).

5. Card

Card is a simple container with rounded corners and a subtle drop shadow (elevation), matching Material Design's visual language for grouping related content. It's extremely common for list items, dashboard tiles, and content blocks — anywhere you want a piece of UI to visually read as "one unit."

Example: A Basic Card

Card(
  elevation: 3,
  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
  child: Padding(
    padding: EdgeInsets.all(16),
    child: Text('Card content goes here'),
  ),
)

6. Worked Example: A Simple Profile Card

Here's everything from this lesson combined into one realistic, self-contained widget — an avatar, name and subtitle text, and an action button, all grouped inside a Card:

Example: ProfileCard Widget

class ProfileCard extends StatelessWidget {
  final String name;
  final String subtitle;

  const ProfileCard({super.key, required this.name, required this.subtitle});

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 4,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
      child: Padding(
        padding: EdgeInsets.all(20),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            // Avatar: a circular clipped Image, with an Icon fallback style
            CircleAvatar(
              radius: 40,
              backgroundImage: NetworkImage('https://example.com/avatar.jpg'),
              child: Icon(Icons.person, size: 32),
            ),
            SizedBox(height: 12),
            Text(name, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
            Text(subtitle, style: TextStyle(fontSize: 14, color: Colors.grey)),
            SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {},
              child: Text('View Profile'),
            ),
          ],
        ),
      ),
    );
  }
}

// Using it:
const ProfileCard(name: 'Sonu Kumar Pandit', subtitle: 'Flutter Developer')

Notice how naturally the widgets from this lesson and the previous layout lesson slot together: Card for the container, Padding for inner spacing, Column to stack content vertically, SizedBox for gaps between sections, and Text/ ElevatedButton for the actual content. This kind of composition — small, well-understood widgets combined together — is how essentially all real Flutter UI gets built.

Next up: You now have the vocabulary to build real screens. Head to State Management: setState to make widgets like this one actually respond to taps and other user interaction.