Stack in Flutter
What is Stack?
The Stack widget in Flutter is a powerful layout widget that allows you to overlay multiple widgets on top of each other. It positions its children relative to the edges of its box, making it ideal for creating complex layouts with overlapping elements.
Key Characteristics
- Overlapping: Widgets can overlap each other
- Z-index: Later children are drawn on top of earlier children
- Positioning: Flexible positioning using alignment and Positioned widgets
- Size: Can be constrained or unconstrained based on usage
Simple Stack Example
Dart Code:
import ‘package:flutter/material.dart’;
class BasicStackExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(‘Basic Stack Example’)),
body: Center(
child: Stack(
children: [
Container(
width: 200,
height: 200,
color: Colors.blue,
),
Container(
width: 150,
height: 150,
color: Colors.green,
),
Container(
width: 100,
height: 100,
color: Colors.red,
),
],
),
),
);
}
}
Stack with Text Overlay
dart
class StackWithTextOverlay extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(‘Stack with Text Overlay’)),
body: Center(
child: Stack(
children: [
Container(
width: 300,
height: 300,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(‘https://picsum.photos/300'),
fit: BoxFit.cover,
),
),
),
Positioned(
bottom: 20,
left: 20,
child: Text(
‘Beautiful Image’,
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold,
shadows: [
Shadow(
blurRadius: 10.0,
color: Colors.black,
offset: Offset(2.0, 2.0),
),
],
),
),
),
],
),
),
);
}
}
Positioned Widget
class PositionedExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(‘Positioned Widget’)),
body: Center(
child: Container(
width: 300,
height: 300,
color: Colors.grey[200],
child: Stack(
children: [
// Top Left
Positioned(
top: 20,
left: 20,
child: _buildPositionedBox(Colors.red, ‘Top\nLeft’),
),
// Top Right
Positioned(
top: 20,
right: 20,
child: _buildPositionedBox(Colors.green, ‘Top\nRight’),
),
// Bottom Left
Positioned(
bottom: 20,
left: 20,
child: _buildPositionedBox(Colors.blue, ‘Bottom\nLeft’),
),
// Bottom Right
Positioned(
bottom: 20,
right: 20,
child: _buildPositionedBox(Colors.orange, ‘Bottom\nRight’),
),
// Center
Positioned(
top: 125,
left: 125,
child: _buildPositionedBox(Colors.purple, ‘Center’),
),
],
Get Hassan Sardar’s stories in your inbox
Join Medium for free to get updates from this writer.
),
),
),
);
}
Widget _buildPositionedBox(Color color, String text) {
return Container(
width: 60,
height: 60,
color: color,
child: Center(
child: Text(
text,
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 10),
),
),
);
}
}
Badge Notification
Dart Code:
class BadgeNotification extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(‘Badge Notification’)),
body: Center(
child: Stack(
children: [
Icon(Icons.shopping_cart, size: 100, color: Colors.grey),
Positioned(
top: 0,
right: 0,
child: Container(
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: Text(
‘5’,
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
);
}
}
Animated Stack
dart
class AnimatedStackExample extends StatefulWidget {
@override
_AnimatedStackExampleState createState() => _AnimatedStackExampleState();
}
class _AnimatedStackExampleState extends State<AnimatedStackExample> {
int _currentIndex = 0;
final List<Color> _colors = [
Colors.red,
Colors.green,
Colors.blue,
Colors.orange,
];
void _nextCard() {
setState(() {
_currentIndex = (_currentIndex + 1) % _colors.length;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(‘Animated Stack’)),
body: Center(
child: GestureDetector(
onTap: _nextCard,
child: Container(
width: 300,
height: 400,
child: Stack(
children: [
for (int i = 0; i < _colors.length; i++)
AnimatedPositioned(
duration: Duration(milliseconds: 500),
curve: Curves.easeInOut,
top: i == _currentIndex ? 0 : 20,
left: i == _currentIndex ? 0 : 10,
right: i == _currentIndex ? 0 : 10,
bottom: i == _currentIndex ? 0 : 20,
child: AnimatedContainer(
duration: Duration(milliseconds: 500),
decoration: BoxDecoration(
color: _colors[i],
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 10,
offset: Offset(0, 4),
),
],
),
child: Center(
child: Text(
‘Card ${i + 1}’,
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
),
),
),
),
);
}
}









