Flutter Modifiers
Layout Modifiers
Padding & Margin
// Padding
Padding(
padding: EdgeInsets.all(16.0),
child: Text('Padded text'),
)
// Specific padding
Padding(
padding: EdgeInsets.only(
left: 8.0,
top: 16.0,
right: 8.0,
bottom: 16.0,
),
child: Text('Custom padding'),
)
// Symmetric padding
Padding(
padding: EdgeInsets.symmetric(
horizontal: 16.0,
vertical: 8.0,
),
child: Text('Symmetric padding'),
)
// Margin using Container
Container(
margin: EdgeInsets.all(8.0),
child: Text('With margin'),
)
Size Constraints
// Fixed size
SizedBox(
width: 100,
height: 100,
child: Container(color: Colors.blue),
)
// Width only
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {},
child: Text('Full width button'),
),
)
// Height only
SizedBox(
height: 50,
child: Text('Fixed height text'),
)
// ConstrainedBox for min/max constraints
ConstrainedBox(
constraints: BoxConstraints(
minWidth: 100,
maxWidth: 300,
minHeight: 50,
maxHeight: 200,
),
child: Container(color: Colors.green),
)
Position & Alignment
// Center widget
Center(
child: Text('Centered text'),
)
// Align widget
Align(
alignment: Alignment.topRight,
child: Text('Top right aligned'),
)
// Positioned in Stack
Stack(
children: [
Container(color: Colors.blue),
Positioned(
top: 10,
left: 10,
child: Text('Positioned text'),
),
Positioned.fill(
child: Center(child: Text('Centered in stack')),
),
],
)
Visual Modifiers
Colors & Backgrounds
// Background color
Container(
color: Colors.blue,
child: Text('Blue background'),
)
// Gradient background
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.purple],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Text('Gradient background'),
)
// Radial gradient
Container(
decoration: BoxDecoration(
gradient: RadialGradient(
colors: [Colors.yellow, Colors.orange, Colors.red],
),
),
child: Text('Radial gradient'),
)
Borders & Shadows
// Simple border
Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 2.0,
),
),
child: Text('Bordered text'),
)
// Rounded corners
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Colors.blue,
),
child: Text('Rounded container'),
)
// Custom border radius
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0),
bottomRight: Radius.circular(16.0),
),
color: Colors.green,
),
child: Text('Custom rounded corners'),
)
// Box shadow
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 3),
),
],
),
child: Text('Shadowed container'),
)
Opacity & Visibility
// Opacity
Opacity(
opacity: 0.5,
child: Text('Semi-transparent text'),
)
// Animated opacity
AnimatedOpacity(
opacity: isVisible ? 1.0 : 0.0,
duration: Duration(milliseconds: 300),
child: Text('Animated opacity'),
)
// Visibility
Visibility(
visible: isVisible,
child: Text('Conditionally visible'),
)
// Offstage (invisible but still in tree)
Offstage(
offstage: !isVisible,
child: Text('Offstage widget'),
)
Transform Modifiers
Scale & Rotation
// Scale transform
Transform.scale(
scale: 1.5,
child: Text('Scaled text'),
)
// Scale with origin
Transform.scale(
scale: 0.8,
origin: Offset(50, 50),
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
)
// Rotation
Transform.rotate(
angle: 45 * pi / 180, // 45 degrees
child: Text('Rotated text'),
)
// Rotation around center
Transform.rotate(
angle: 90 * pi / 180,
child: Container(
width: 100,
height: 50,
color: Colors.blue,
),
)
Translation
// Translate widget
Transform.translate(
offset: Offset(20, 20),
child: Text('Translated text'),
)
// Matrix transform
Transform(
transform: Matrix4.identity()
..translate(10.0, 10.0)
..scale(1.2)
..rotateZ(0.1),
child: Container(
width: 100,
height: 100,
color: Colors.purple,
),
)
Text Modifiers
Text Styling
// Basic text style
Text(
'Styled text',
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
color: Colors.blue,
fontFamily: 'Roboto',
),
)
// Rich text with multiple styles
RichText(
text: TextSpan(
style: TextStyle(color: Colors.black),
children: [
TextSpan(
text: 'Normal ',
style: TextStyle(fontSize: 16),
),
TextSpan(
text: 'Bold',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.blue,
),
),
],
),
)
// Text with decoration
Text(
'Underlined text',
style: TextStyle(
decoration: TextDecoration.underline,
decorationColor: Colors.red,
decorationThickness: 2.0,
),
)
Text Overflow
// Ellipsis overflow
Text(
'This is a very long text that will be truncated with ellipsis',
overflow: TextOverflow.ellipsis,
maxLines: 1,
)
// Fade overflow
Text(
'Long text with fade effect',
overflow: TextOverflow.fade,
maxLines: 2,
)
// Clip overflow
Text(
'Text that gets clipped',
overflow: TextOverflow.clip,
maxLines: 1,
)
Interactive Modifiers
Gesture Detection
// Tap detection
GestureDetector(
onTap: () => print('Tapped'),
onLongPress: () => print('Long pressed'),
onDoubleTap: () => print('Double tapped'),
child: Container(
color: Colors.blue,
child: Text('Tap me'),
),
)
// InkWell for Material Design ripple
InkWell(
onTap: () => print('Tapped with ripple'),
child: Container(
padding: EdgeInsets.all(16.0),
child: Text('Tap with ripple effect'),
),
)
// Custom gesture detection
GestureDetector(
onPanUpdate: (details) {
print('Pan: ${details.delta}');
},
onScaleUpdate: (details) {
print('Scale: ${details.scale}');
},
child: Container(
color: Colors.green,
child: Text('Gesture container'),
),
)
Hover & Focus
// Mouse hover
MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: () => print('Clicked'),
child: Container(
color: Colors.blue,
child: Text('Hoverable text'),
),
),
)
// Focus detection
Focus(
onFocusChange: (hasFocus) {
print('Focus changed: $hasFocus');
},
child: TextField(
decoration: InputDecoration(labelText: 'Focusable field'),
),
)
Animation Modifiers
Animated Containers
// Animated container
AnimatedContainer(
duration: Duration(milliseconds: 300),
width: isExpanded ? 200 : 100,
height: isExpanded ? 200 : 100,
color: isExpanded ? Colors.blue : Colors.red,
child: Center(child: Text('Animated')),
)
// Animated padding
AnimatedPadding(
duration: Duration(milliseconds: 300),
padding: EdgeInsets.all(isExpanded ? 32.0 : 8.0),
child: Text('Animated padding'),
)
// Animated alignment
AnimatedAlign(
duration: Duration(milliseconds: 300),
alignment: isTop ? Alignment.topCenter : Alignment.bottomCenter,
child: Text('Animated alignment'),
)
Tween Animations
// Tween animation builder
TweenAnimationBuilder<double>(
duration: Duration(milliseconds: 500),
tween: Tween(begin: 0.0, end: 1.0),
builder: (context, value, child) {
return Opacity(
opacity: value,
child: Transform.scale(
scale: value,
child: Text('Animated text'),
),
);
},
)
// Custom tween
TweenAnimationBuilder<Color>(
duration: Duration(milliseconds: 1000),
tween: ColorTween(
begin: Colors.red,
end: Colors.blue,
),
builder: (context, color, child) {
return Container(
color: color,
child: Text('Color animation'),
);
},
)
Special Widget Modifiers
ListView Modifiers
// Scroll physics
ListView(
physics: BouncingScrollPhysics(),
children: [
Text('Bouncy scroll'),
Text('Item 2'),
],
)
// Scroll controller
ListView(
controller: ScrollController(),
children: [
Text('Controlled scroll'),
Text('Item 2'),
],
)
// Custom scroll behavior
ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(
scrollbars: false,
),
child: ListView(
children: [Text('No scrollbars')],
),
)
TextField Modifiers
// Input decoration
TextField(
decoration: InputDecoration(
labelText: 'Label',
hintText: 'Hint text',
prefixIcon: Icon(Icons.person),
suffixIcon: Icon(Icons.clear),
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 2),
),
),
)
// Text input formatters
TextField(
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
LengthLimitingTextInputFormatter(10),
],
decoration: InputDecoration(labelText: 'Numbers only'),
)
// Text selection
TextField(
controller: TextEditingController(
text: 'Selectable text',
),
enableInteractiveSelection: true,
selectionControls: MaterialTextSelectionControls(),
)
Button Modifiers
// Elevated button style
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.blue,
onPrimary: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 32, vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
elevation: 4,
),
onPressed: () {},
child: Text('Styled button'),
)
// Button with icon
ElevatedButton.icon(
onPressed: () {},
icon: Icon(Icons.add),
label: Text('Add item'),
style: ElevatedButton.styleFrom(
primary: Colors.green,
),
)
// Disabled button
ElevatedButton(
onPressed: isEnabled ? () {} : null,
child: Text('Conditional button'),
)
Image Modifiers
// Image with fit
Image.network(
'https://example.com/image.jpg',
fit: BoxFit.cover,
width: 200,
height: 200,
)
// Image with placeholder
Image.network(
'https://example.com/image.jpg',
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes!
: null,
);
},
)
// Image with error handling
Image.network(
'https://example.com/image.jpg',
errorBuilder: (context, error, stackTrace) {
return Icon(Icons.error, color: Colors.red);
},
)
Advanced Modifiers
Custom Paint
// Custom painter
class CustomPainter extends CustomPainter {
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..strokeWidth = 4.0
..style = PaintingStyle.stroke;
canvas.drawCircle(
Offset(size.width / 2, size.height / 2),
50.0,
paint,
);
}
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
// Usage
CustomPaint(
painter: CustomPainter(),
child: Container(width: 200, height: 200),
)
Clip Path
// Custom clip path
class CustomClipPath extends CustomClipper<Path> {
Path getClip(Size size) {
final path = Path();
path.moveTo(0, size.height * 0.5);
path.lineTo(size.width * 0.5, 0);
path.lineTo(size.width, size.height * 0.5);
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
path.close();
return path;
}
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}
// Usage
ClipPath(
clipper: CustomClipPath(),
child: Container(
width: 200,
height: 200,
color: Colors.blue,
),
)
RepaintBoundary
// Optimize repaints
RepaintBoundary(
child: Container(
color: Colors.blue,
child: Text('Optimized widget'),
),
)
// Multiple repaint boundaries
Column(
children: [
RepaintBoundary(
child: AnimatedContainer(
duration: Duration(seconds: 1),
color: Colors.red,
child: Text('Animated 1'),
),
),
RepaintBoundary(
child: AnimatedContainer(
duration: Duration(seconds: 1),
color: Colors.green,
child: Text('Animated 2'),
),
),
],
)
Performance Modifiers
const Constructors
// Use const for static widgets
const Text('Static text')
const Icon(Icons.star)
const SizedBox(height: 16.0)
// Const widget tree
const Column(
children: [
Text('Item 1'),
Text('Item 2'),
Text('Item 3'),
],
)
AutomaticKeepAliveClientMixin
class KeepAliveWidget extends StatefulWidget {
_KeepAliveWidgetState createState() => _KeepAliveWidgetState();
}
class _KeepAliveWidgetState extends State<KeepAliveWidget>
with AutomaticKeepAliveClientMixin {
bool get wantKeepAlive => true;
Widget build(BuildContext context) {
super.build(context); // Required
return ListView.builder(
itemCount: 1000,
itemBuilder: (context, index) {
return ListTile(title: Text('Item $index'));
},
);
}
}
Common Patterns
Conditional Modifiers
// Conditional styling
Container(
color: isActive ? Colors.green : Colors.grey,
child: Text('Conditional color'),
)
// Conditional visibility
if (isVisible) Text('Conditionally visible'),
// Conditional modifiers
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
child: isExpanded
? Expanded(child: Text('Expanded'))
: Text('Not expanded'),
);
}
Responsive Modifiers
// Media query based modifiers
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return Container(
width: screenWidth > 600 ? 400 : screenWidth * 0.8,
child: Text('Responsive width'),
);
}
// Orientation based modifiers
Widget build(BuildContext context) {
final orientation = MediaQuery.of(context).orientation;
return orientation == Orientation.portrait
? Column(children: [/* portrait layout */])
: Row(children: [/* landscape layout */]);
}
Theme Based Modifiers
// Theme aware styling
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Container(
color: theme.primaryColor,
child: Text(
'Themed text',
style: theme.textTheme.headline6,
),
);
}
// Dark mode aware
Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
return Container(
color: isDark ? Colors.grey[800] : Colors.white,
child: Text(
'Dark mode aware',
style: TextStyle(
color: isDark ? Colors.white : Colors.black,
),
),
);
}
References
- Flutter Widget Catalog (flutter.dev)
- Flutter Layout Tutorial (flutter.dev)
- Flutter Styling Guide (flutter.dev)
- Flutter Animation Guide (flutter.dev)