Widgets Basic
Essential Flutter widgets with practical code examples — Text styling, Container decoration, layout with Row/Column, images, icons, and buttons.
1. Text Widget & Styling
The Text widget renders a string. Use TextStyle to control font size, weight, color, letter spacing, and decoration. Use RichText for mixed styles in one line.
// Basic text
Text("Hello, Flutter!")
// Styled text
Text(
"Welcome Back",
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.indigo,
letterSpacing: 1.5,
height: 1.4, // Line height multiplier
decoration: TextDecoration.underline,
),
textAlign: TextAlign.center,
maxLines: 2,
overflow: TextOverflow.ellipsis,
)
// RichText – mixed styles in one widget
RichText(
text: TextSpan(
text: "Hello ",
style: const TextStyle(color: Colors.black, fontSize: 16),
children: [
TextSpan(
text: "Flutter",
style: const TextStyle(
color: Colors.indigo,
fontWeight: FontWeight.bold,
),
),
TextSpan(text: "!"),
],
),
)
2. Container with BoxDecoration
Container is the most versatile layout widget. Use BoxDecoration to add borders, border radius, gradients, shadows, and background colors.
// Basic container
Container(
width: 200,
height: 100,
color: Colors.blue,
child: const Text("Basic"),
)
// Container with full decoration
Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.grey.shade300, width: 1),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.08),
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
child: const Text("Decorated Card"),
)
// Gradient container
Container(
height: 150,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
gradient: LinearGradient(
colors: [Color(0xFF6C63FF), Color(0xFF3B82F6)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
)
3. Column, Row, and Alignment
Column arranges children vertically; Row arranges them horizontally. Use mainAxisAlignment and crossAxisAlignment to control spacing and alignment.
// Column – vertical layout
Column(
mainAxisAlignment: MainAxisAlignment.center, // Vertical axis
crossAxisAlignment: CrossAxisAlignment.start, // Horizontal axis
children: [
const Text("Item 1"),
const SizedBox(height: 8),
const Text("Item 2"),
const SizedBox(height: 8),
const Text("Item 3"),
],
)
// Row – horizontal layout
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(Icons.person, size: 32),
const Text("John Doe"),
ElevatedButton(onPressed: () {}, child: const Text("Follow")),
],
)
// Expanded – fill remaining space in Row/Column
Row(
children: [
const Icon(Icons.star, color: Colors.amber),
const SizedBox(width: 8),
const Expanded( // Takes remaining width
child: Text("This text fills the rest of the row"),
),
const Text("4.9"),
],
)
// Flexible – flexible proportional sizing
Row(
children: [
Flexible(flex: 2, child: Container(color: Colors.red, height: 40)),
Flexible(flex: 1, child: Container(color: Colors.blue, height: 40)),
],
)
4. SizedBox & Padding
SizedBox is used for fixed-size spacing or constraining a child widget. Padding wraps a widget and adds space inside. Both are preferred over empty Container for readability.
// SizedBox as spacer
const SizedBox(height: 16) // Vertical gap
const SizedBox(width: 8) // Horizontal gap
// SizedBox to constrain a child
SizedBox(
width: 200,
height: 50,
child: ElevatedButton(
onPressed: () {},
child: const Text("Fixed Size Button"),
),
)
// SizedBox.expand – fills parent
SizedBox.expand(
child: Container(color: Colors.grey.shade100),
)
// Padding widget
Padding(
padding: const EdgeInsets.all(16), // All sides
child: const Text("Padded text"),
)
Padding(
padding: const EdgeInsets.symmetric( // H & V
horizontal: 24,
vertical: 12,
),
child: const Text("Symmetric padding"),
)
Padding(
padding: const EdgeInsets.only( // Specific sides
left: 16,
top: 8,
),
child: const Text("Only left & top"),
)
5. Image.network & Image.asset
Load images from the internet with Image.network or from your assets folder with Image.asset. Use ClipRRect to clip images with rounded corners.
// Image from URL
Image.network(
"https://picsum.photos/200/300",
width: 200,
height: 200,
fit: BoxFit.cover,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return const Center(child: CircularProgressIndicator());
},
errorBuilder: (context, error, stackTrace) {
return const Icon(Icons.broken_image, size: 48);
},
)
// Image from assets (declare in pubspec.yaml first)
Image.asset(
"assets/images/logo.png",
width: 120,
fit: BoxFit.contain,
)
// Circular image with ClipRRect
ClipRRect(
borderRadius: BorderRadius.circular(50),
child: Image.network(
"https://picsum.photos/100",
width: 100,
height: 100,
fit: BoxFit.cover,
),
)
// CircleAvatar shorthand
CircleAvatar(
radius: 30,
backgroundImage: NetworkImage("https://picsum.photos/60"),
backgroundColor: Colors.grey,
)
6. Icon Widget
Flutter ships with Material Icons. Access them via Icons.icon_name. Customize size and color with properties on the Icon widget.
// Basic icon
const Icon(Icons.home)
// Styled icon
const Icon(
Icons.favorite,
color: Colors.red,
size: 32,
)
// Icon inside a colored circle
Container(
padding: const EdgeInsets.all(10),
decoration: const BoxDecoration(
color: Colors.indigo,
shape: BoxShape.circle,
),
child: const Icon(Icons.bolt, color: Colors.white, size: 24),
)
// Common icons reference
// Icons.home, Icons.search, Icons.person, Icons.settings
// Icons.favorite, Icons.star, Icons.share, Icons.delete
// Icons.add, Icons.edit, Icons.close, Icons.check
// Icons.arrow_back, Icons.arrow_forward, Icons.menu
// Icons.notifications, Icons.lock, Icons.visibility
7. ElevatedButton & TextButton
ElevatedButton has a filled background with elevation. TextButton is flat with no background. Both accept an onPressed callback and a child widget.
// ElevatedButton – filled button
ElevatedButton(
onPressed: () {
print("Button pressed");
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.indigo,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 4,
),
child: const Text("Get Started", style: TextStyle(fontSize: 16)),
)
// ElevatedButton with icon
ElevatedButton.icon(
onPressed: () {},
icon: const Icon(Icons.login),
label: const Text("Login"),
)
// TextButton – flat button
TextButton(
onPressed: () {},
child: const Text("Forgot Password?"),
)
// OutlinedButton – border only
OutlinedButton(
onPressed: () {},
style: OutlinedButton.styleFrom(
side: const BorderSide(color: Colors.indigo, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: const Text("Sign Up"),
)
// Disabled button (onPressed: null)
ElevatedButton(
onPressed: null, // Disables the button
child: const Text("Disabled"),
)