Topic: 2 Understanding widgets in detail
Hello devs, As we decided in the previous blog in this blog we discussed about Different types of widgets that are used to create UI in Flutter and deeply understand the stateful widgets lifecycle.
Types of Stateless Widgets
Basic UI Widgets:
Text: Displays a string of text.
Image: Displays an image from various sources.
Icon: Displays a Material or Cupertino icon.
Container: A rectangular visual element used for layout or styling.
Text('Hello, World!');
Image.asset('assets/image.png');
Icon(Icons.favorite);
Container(
width: 100,
height: 100,
color: Colors.blue,
child: Text('Container'),
);
UI Elements:
Button: A clickable element used to trigger actions.
TextField: Allows users to input text.
Checkbox, Radio, Switch: Input widgets for boolean values.
ElevatedButton(
onPressed: () {
// Handle button press
},
child: Text('Press Me'),
);
TextField(
decoration: InputDecoration(
labelText: 'Enter your name',
),
);
Material Design Widgets:
- Widgets that implement Google's Material Design guidelines, such as
AppBar
,Card
,Drawer
, etc.
- Widgets that implement Google's Material Design guidelines, such as
AppBar(
title: Text('My App'),
);
Card(
child: ListTile(
title: Text('Title'),
subtitle: Text('Subtitle'),
),
);
Cupertino Widgets:
- Widgets that implement Apple's iOS design guidelines, such as
CupertinoNavigationBar
,CupertinoButton
, etc.
- Widgets that implement Apple's iOS design guidelines, such as
CupertinoNavigationBar(
middle: Text('Title'),
);
CupertinoButton(
onPressed: () {
// Handle button press
},
child: Text('Press Me'),
);
Layout Widgets:
- Widgets that help with layout composition, such as
Row
,Column
,ListView
,GridView
, etc.
- Widgets that help with layout composition, such as
Row(
children: [
Icon(Icons.star),
Text('Star'),
],
);
ListView(
children: [
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
],
);
Styling Widgets:
- Widgets that apply styling to their children, such as
TextStyle
,Container
(with decoration properties), etc.
- Widgets that apply styling to their children, such as
Text(
'Styled Text',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.red,
),
);
Container(
width: 100,
height: 100,
color: Colors.blue,
child: Center(
child: Text('Container'),
),
);
Utility Widgets:
- Widgets that provide utility or convenience, such as
AspectRatio
,Opacity
, etc.
- Widgets that provide utility or convenience, such as
AspectRatio(
aspectRatio: 16 / 9,
child: Image.asset('assets/image.jpg'),
);
Opacity(
opacity: 0.5,
child: Text('Half Transparent'),
);
These are the main types of stateless widgets in Flutter, each serving different purposes and contributing to the construction of rich and dynamic user interfaces. By leveraging these widgets effectively, developers can create engaging and responsive Flutter applications.
Types of Stateful Widgets
Basic Stateful Widgets:
- These are stateful counterparts of basic UI widgets such as
Text
,Image
,Icon
, andContainer
. They maintain a mutable state to enable dynamic updates.
- These are stateful counterparts of basic UI widgets such as
class CounterWidget extends StatefulWidget {
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Counter: $_counter'),
ElevatedButton(
onPressed: () {
setState(() {
_counter++;
});
},
child: Text('Increment'),
),
],
);
}
}
Form Stateful Widgets:
- These widgets are used for capturing and validating user input, such as
TextField
,Checkbox
,Radio
,Switch
, etc.
- These widgets are used for capturing and validating user input, such as
class FormWidget extends StatefulWidget {
@override
_FormWidgetState createState() => _FormWidgetState();
}
class _FormWidgetState extends State<FormWidget> {
final TextEditingController _controller = TextEditingController();
String _inputText = '';
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
controller: _controller,
onChanged: (value) {
setState(() {
_inputText = value;
});
},
decoration: InputDecoration(
labelText: 'Enter text',
),
),
Text('Input: $_inputText'),
],
);
}
}
List Stateful Widgets:
- These widgets are used for displaying dynamic lists of items, such as
ListView
,GridView
, etc.
- These widgets are used for displaying dynamic lists of items, such as
class ListWidget extends StatefulWidget {
@override
_ListWidgetState createState() => _ListWidgetState();
}
class _ListWidgetState extends State<ListWidget> {
List<String> _items = ['Item 1', 'Item 2', 'Item 3'];
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: _items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_items[index]),
);
},
);
}
}
Navigation Stateful Widgets:
- These widgets manage navigation within the app and maintain state related to route changes, such as
Navigator
,BottomNavigationBar
,TabBar
, etc.
- These widgets manage navigation within the app and maintain state related to route changes, such as
class NavigationWidget extends StatefulWidget {
@override
_NavigationWidgetState createState() => _NavigationWidgetState();
}
class _NavigationWidgetState extends State<NavigationWidget> {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Selected index: $_selectedIndex'),
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Search',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
);
}
}
Custom Stateful Widgets:
- These are custom widgets created by developers to encapsulate complex UI components and behaviors while maintaining their own internal state.
class CustomWidget extends StatefulWidget {
@override
_CustomWidgetState createState() => _CustomWidgetState();
}
class _CustomWidgetState extends State<CustomWidget> {
bool _isActive = false;
void _toggleState() {
setState(() {
_isActive = !_isActive;
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _toggleState,
child: Container(
color: _isActive ? Colors.blue : Colors.grey,
child: Center(
child: Text(_isActive ? 'Active' : 'Inactive'),
),
),
);
}
}
These are the main types of stateful widgets in Flutter, each serving different purposes and enabling developers to build dynamic and interactive user interfaces for their applications.
As we see in our previous blog that the stateFul widget has a lifecycle. Let's understand in detail.
Stateful Widget Lifecycle
Constructor:
- When you create a stateful widget, you set it up with the constructor. This is where you prepare everything before the widget is shown.
createState():
- Next, Flutter creates the state for your widget. This is like setting up the brain of the widget to handle changes and updates.
initState():
- Now, the widget's brain (
initState()
) gets ready. It's called just once and used for setting up things like listening to events or loading data.
- Now, the widget's brain (
build():
- With everything set up, Flutter builds the widget's UI (
build()
). It's like drawing what the widget looks like.
- With everything set up, Flutter builds the widget's UI (
setState():
- When something changes, like a button press, you use
setState()
to tell Flutter. This makes the widget redraw with the new changes.
- When something changes, like a button press, you use
didUpdateWidget():
- If the widget's properties change, Flutter checks
didUpdateWidget()
to see if it needs to do anything special. It's like a check-up after a change.
- If the widget's properties change, Flutter checks
dispose():
- Finally, when the widget is removed, Flutter cleans up with
dispose()
. It's used for things like stopping listeners or releasing resources.
- Finally, when the widget is removed, Flutter cleans up with
Understanding this process helps you control how your widgets behave and keep your app running smoothly.
Alright, Devs this is the end of the blog. I hope this blog helps you to understand Widgets and Stateful Widget lifecycle. So In our next blog, we talk about Flutter Tree.
Connect with Me:
Hey there! If you enjoyed reading this blog and found it informative, why not connect with me on LinkedIn? ๐ You can also follow my Instagram page for more mobile development-related content. ๐ฒ๐จโ๐ป Letโs stay connected, share knowledge and have some fun in the exciting world of app development! ๐
Subscribe to my newsletter
Read articles from Mayursinh Parmar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Mayursinh Parmar
Mayursinh Parmar
๐ฑMobile App Developer | Android & Flutter ๐๐ก Passionate about creating intuitive and engaging apps ๐ญโจ Letโs shape the future of mobile technology!