Flutter is an open-source UI framework that allows developers to create high-performance, visually rich apps from a single codebase. At the heart of Flutter are widgets, which serve as the building blocks of your user interface. From simple text displays to complex animations, everything in Flutter is constructed with widgets.
In this blog post, we’ll dive deep into all Flutter widgets and provide styling tips, showcasing how to customize them for a polished and responsive UI. Let’s begin by categorizing Flutter’s vast array of widgets and how you can style them effectively.
What Are Flutter Widgets?
In Flutter, everything is a widget—from a button, text, image, to complex layouts. Widgets are classified into two types:
- Stateless Widgets: Widgets that do not maintain any internal state. They are immutable, and their properties cannot change over time.
- Stateful Widgets: Widgets that maintain their state over time, allowing them to update when necessary.
Here’s a concise list of basic and very important Flutter widgets:
- Wrap
- Container
- Row
- Column
- Text
- Image
- Icon
- SizedBox
- Stack
- ListView
- GridView
- Padding
- Center
- Scaffold
- AppBar
- TextField
- Button Widgets (e.g., ElevatedButton, TextButton, IconButton)
- Card
- Expanded
- Flexible
Below is a comprehensive guide to all Flutter widgets categorized by their functionality and how to apply styles to each of them.
Basic Flutter Widgets
These are the fundamental widgets that you’ll use to create almost any user interface in Flutter.
1. Text
Displays a string of text. The text can be styled using the TextStyle
property.
Text(
"Hello, Flutter!",
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.blue,
fontFamily: 'Roboto',
),
)
2. Container
A flexible container widget that can hold other widgets and style them (e.g., padding, margin, color, etc.).
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.blue, width: 2),
),
child: Text("Styled Container", style: TextStyle(color: Colors.white, fontSize: 18)),
)
3. Row & Column
- Row: Displays its children horizontally.
- Column: Displays its children vertically.
Row(
children: [
Icon(Icons.home),
SizedBox(width: 8),
Text("Home", style: TextStyle(fontSize: 20)),
],
)
Column(
children: [
Text("Item 1", style: TextStyle(fontSize: 20)),
Text("Item 2", style: TextStyle(fontSize: 20)),
],
)
4. Stack
Allows widgets to be placed on top of each other, useful for layered layouts.
Stack(
children: [
Positioned(top: 10, left: 10, child: Text("Top Left")),
Positioned(bottom: 10, right: 10, child: Text("Bottom Right")),
],
)
5. Padding
Adds padding around the widget.
Padding(
padding: EdgeInsets.all(16),
child: Text("Padded Text"),
)
6. Center
Centers its child within the available space.
Center(
child: Text("Centered Text"),
)
7. SizedBox
A widget used to add fixed dimensions or spacing between widgets. It’s perfect for creating space or setting explicit sizes for widgets.
// Example: Adding vertical space
Column(
children: [
Text("Text 1"),
SizedBox(height: 20), // Adds 20 pixels of vertical space
Text("Text 2"),
],
)
// Example: Creating a fixed-sized container
SizedBox(
width: 100,
height: 100,
child: Container(color: Colors.red),
)
Input Widgets
These widgets allow users to interact with the app by entering data or selecting options.
1. TextField
Allows the user to input text. The InputDecoration
property is used for styling the text field.
TextField(
decoration: InputDecoration(
labelText: 'Enter your name',
hintText: 'John Doe',
border: OutlineInputBorder(),
),
)
2. ElevatedButton
A Material Design button with a raised appearance.
ElevatedButton(
onPressed: () {},
child: Text("Click Me"),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.green),
shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(8))),
),
)
3. TextButton
A flat button with no elevation.
TextButton(
onPressed: () {},
child: Text("Flat Button"),
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all(Colors.blue),
),
)
4. Checkbox
A widget for selecting an option from a set of choices.
Checkbox(
value: _isChecked,
onChanged: (bool? newValue) {},
)
5. Switch
A toggle widget for switching between two states.
Switch(
value: _isSwitched,
onChanged: (bool value) {},
)
Material Design Widgets
These widgets follow the Material Design guidelines, providing a consistent look and feel across Android and iOS platforms.
1. AppBar
A material design app bar, often used as the header of an app or screen.
AppBar(
title: Text("App Bar"),
actions: [
IconButton(icon: Icon(Icons.search), onPressed: () {}),
],
)
2. Scaffold
Provides a basic structure for your application, including an AppBar
, body, and floating action buttons.
Scaffold(
appBar: AppBar(title: Text("Scaffold Example")),
body: Center(child: Text("Body Content")),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
)
3. Drawer
A slide-in navigation menu that appears from the side of the screen.
Drawer(
child: ListView(
children: [
ListTile(title: Text('Home'), onTap: () {}),
ListTile(title: Text('Settings'), onTap: () {}),
],
),
)
4. BottomNavigationBar
A navigation bar for displaying items at the bottom of the screen.
BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
BottomNavigationBarItem(icon: Icon(Icons.search), label: "Search"),
],
)
5. Card
A Material Design card widget for displaying content in a concise and visual manner.
Card(
elevation: 5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
child: Padding(
padding: EdgeInsets.all(16),
child: Text("This is a Card"),
),
)
6. Snackbar
A brief message that pops up at the bottom of the screen, often used for notifications.
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("This is a Snackbar!")),
)
Scrollable Widgets
These widgets allow you to create lists or grids that can be scrolled.
1. ListView
A scrollable list of items.
ListView(
children: [
Text("Item 1"),
Text("Item 2"),
Text("Item 3"),
],
)
2. GridView
A scrollable grid of items.
GridView.count(
crossAxisCount: 2,
children: [
Card(child: Text("Grid Item 1")),
Card(child: Text("Grid Item 2")),
],
)
3. SingleChildScrollView
A scrollable view for a single child widget.
SingleChildScrollView(
child: Column(
children: List.generate(50, (index) => Text("Item $index")),
),
)
Layout Widgets
These widgets help you organize and position elements within your app.
1. Expanded
A widget that expands to fill the available space inside a Row
, Column
, or Flex
.
Row(
children: [
Text("Left"),
Expanded(child: Text("Expanded")),
Text("Right"),
],
)
2. Flexible
Similar to Expanded
, but allows you to control how much space a child widget should take relative to others.
Row(
children: [
Flexible(flex: 2, child: Text("Flexible 1")),
Flexible(flex: 1, child: Text("Flexible 2")),
],
)
3. Spacer
A widget that takes up space between other widgets.
Row(
children: [
Text("Start"),
Spacer(),
Text("End"),
],
)
4. Align
Aligns a widget inside its parent according to a given alignment.
Align(
alignment: Alignment.topRight,
child: Text("Top Right"),
)
Animation Widgets
Flutter allows you to animate widget properties for smooth transitions and interactions.
1. AnimatedContainer
Animates changes to the Container
‘s properties, such as size, color, and padding.
AnimatedContainer(
duration: Duration(seconds: 1),
color: _isRed ? Colors.red : Colors.blue,
height: 200,
width: 200,
)
2. FadeTransition
Animates the opacity of a widget.
FadeTransition(
opacity: _animation,
child: Text("Fading Text"),
)
3. ScaleTransition
Animates the scaling of a widget.
ScaleTransition(
scale: _scaleAnimation,
child: Text("Scaling Text"),
)
Material Widgets for Styling and Theming
Flutter provides a way to define global styling with Themes, which apply consistent styling across the entire app.
1. ThemeData
Use ThemeData
to define global styles like primary colors, text themes, button styles, etc.
MaterialApp(
theme: ThemeData(
primaryColor: Colors.blue,
textTheme: TextTheme(bodyText1: TextStyle(fontSize: 18)),
),
home: MyHomePage(),
)
2. TextTheme
Customize text styles globally.
Text(
"Themed Text",
style: Theme.of(context).textTheme.bodyText1,
)
3. ButtonThemeData
Customize button styles globally.
MaterialApp(
theme: ThemeData(
buttonTheme: ButtonThemeData(buttonColor: Colors.green),
),
)
Additional Important Widgets
Input Widgets
DropdownButton
Provides a dropdown menu for selecting options.
DropdownButton<String>(
value: _selectedValue,
items: ['Option 1', 'Option 2', 'Option 3']
.map((String value) => DropdownMenuItem(value: value, child: Text(value)))
.toList(),
onChanged: (newValue) {
setState(() {
_selectedValue = newValue!;
});
},
)
Slider
Allows users to select a value from a range of values.
Slider(
value: _sliderValue,
min: 0,
max: 100,
divisions: 10,
label: _sliderValue.round().toString(),
onChanged: (value) {
setState(() {
_sliderValue = value;
});
},
)
Layout Widgets
Wrap
A flexible layout widget that wraps its children into the next line when there’s insufficient space.
Wrap(
spacing: 8.0,
runSpacing: 4.0,
children: List.generate(
10,
(index) => Chip(label: Text("Item $index")),
),
)
Table
Creates a table layout with rows and columns.
Table(
border: TableBorder.all(),
children: [
TableRow(children: [Text("Row 1, Col 1"), Text("Row 1, Col 2")]),
TableRow(children: [Text("Row 2, Col 1"), Text("Row 2, Col 2")]),
],
)
Scrollable Widgets
PageView
Enables horizontal or vertical swiping between pages.
PageView(
children: [
Container(color: Colors.red),
Container(color: Colors.green),
Container(color: Colors.blue),
],
)
Scrollable
Provides low-level scrolling capabilities for custom use cases.
Scrollable(
viewportBuilder: (BuildContext context, ViewportOffset position) {
return ListView(
children: List.generate(20, (index) => ListTile(title: Text("Item $index"))),
);
},
)
Material Design Widgets
TabBar and TabBarView
Useful for creating tabbed interfaces.
DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.home)),
Tab(icon: Icon(Icons.settings)),
Tab(icon: Icon(Icons.contact_mail)),
],
),
),
body: TabBarView(
children: [
Center(child: Text("Home")),
Center(child: Text("Settings")),
Center(child: Text("Contact")),
],
),
),
)
Other Widgets
Divider
A simple horizontal or vertical divider.
Divider(
color: Colors.grey,
thickness: 2,
indent: 20,
endIndent: 20,
)
Hero
Animates the transition of a widget from one screen to another.
Hero(
tag: 'hero-tag',
child: Image.network('https://example.com/image.png'),
)
ClipRRect
Clips a widget with rounded corners.
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.network('https://example.com/image.png'),
)
Conclusion
Flutter’s widget library is vast and provides countless options for creating highly interactive and visually appealing apps. Whether you’re working with simple containers or complex animations, Flutter’s rich set of widgets and styling capabilities allow you to build the app of your dreams.
By understanding the different types of widgets, their use cases, and how to style them with TextStyle
, BoxDecoration
, ButtonStyle
, and ThemeData
, you can make your Flutter app both functional and beautiful. The best way to master Flutter widgets is to practice and experiment, so dive into your projects and start building! Happy coding!