Flutter is a popular open-source UI software development kit (SDK) that enables developers to build natively compiled applications for mobile, web, and desktop platforms from a single codebase. One of the core concepts in Flutter development is "widgets." In this article, we will delve into the world of Flutter widgets, exploring their functionality, types, and their significance in creating dynamic and interactive user interfaces.
In Flutter, widgets are the basic building blocks used to construct user interfaces. Everything you see on the screen, such as buttons, text, images, and layout elements, is a widget. Flutter widgets are not just static components; they are designed to be dynamic and responsive, allowing developers to create interactive and visually appealing applications.
Flutter widgets follow a hierarchical structure, forming a "widget tree." Each widget can have children, and when you assemble them, they create the entire user interface. When you make changes to a widget, Flutter efficiently rebuilds only that specific part of the widget tree, resulting in excellent performance and smooth user experiences.
Flutter offers two main types of widgets:
a. StatelessWidget: As the name suggests, a StatelessWidget is a widget that cannot change its state once it is built. These widgets are immutable, making them more straightforward and efficient. They are ideal for representing static content like texts, images, and icons.
b. StatefulWidget: StatefulWidgets, on the other hand, are mutable widgets. They can change their appearance or behavior over time, making them perfect for creating dynamic and interactive components, such as forms, animations, and progress indicators.
Let's explore some of the essential widgets frequently used in Flutter app development:
In this example, we'll create a simple text using container widgets
Container(
width: 150,
height: 50,
color: Colors.blue,
child: Center(
child: Text('Click Me!', style: TextStyle(color: Colors.white)),
),
)
In this example, we'll create a simple layout using Row and Column widgets to arrange multiple elements horizontally and vertically, respectively.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Row and Column Example'),
),
body: Padding(
padding: EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: 50,
height: 50,
color: Colors.red,
),
Container(
width: 50,
height: 50,
color: Colors.green,
),
Container(
width: 50,
height: 50,
color: Colors.blue,
),
],
),
SizedBox(height: 20),
Text(
'Three colored boxes arranged horizontally',
style: TextStyle(fontSize: 16),
),
],
),
),
),
);
}
}
In this example, we'll create a simple item list show the some information like title, description.
ListView.builder(
itemCount: itemList.length,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.star),
title: Text(itemList[index].title),
subtitle: Text(itemList[index].description),
onTap: () => _handleItemTap(itemList[index]),
);
},
)
In this example, we'll create a Stack of widgets, overlaying two containers with different colors.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Stack Example'),
),
body: Center(
child: Stack(
alignment: Alignment.center,
children: [
Container(
width: 200,
height: 200,
color: Colors.blue,
),
Container(
width: 150,
height: 150,
color: Colors.orange,
),
Text(
'Stacked Containers',
style: TextStyle(fontSize: 20, color: Colors.white),
),
],
),
),
),
);
}
}
In this example, we'll create a simple AppBar with a leading icon and a title.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
leading: Icon(Icons.menu),
title: Text('AppBar Example'),
),
body: Center(
child: Text(
'Welcome to the AppBar example!',
style: TextStyle(fontSize: 20),
),
),
),
);
}
}
In Flutter, widgets can have children widgets. This composition allows developers to build complex user interfaces by combining multiple widgets together. For instance, you can have a Row widget with multiple Text widgets inside, aligning them horizontally.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Row with Children Example'),
),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.account_circle,
size: 50,
),
SizedBox(width: 10),
Text(
'John Doe',
style: TextStyle(fontSize: 24),
),
SizedBox(width: 20),
ElevatedButton(
onPressed: () {
// Button action
},
child: Text('Follow'),
),
],
),
),
),
);
}
}
In this example, we've used the Row widget to arrange the children widgets horizontally in the center of the screen. We have an Icon widget followed by a Text widget, and then an ElevatedButton. The SizedBox widget is used to add spacing between the elements. This demonstrates how you can easily place multiple widgets side by side using the Row widget in Flutter.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Column with Children Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'Hello,',
style: TextStyle(fontSize: 24),
),
SizedBox(height: 10),
Text(
'Flutter!',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Button action
},
child: Text('Click Me'),
),
SizedBox(height: 10),
Text('Tap the button above!'),
],
),
),
),
);
}
}
The key difference lies in the ability to manage state:
a StatelessWidget: These widgets are immutable and do not hold any state. They are useful for representing static elements that do not change.
b StatefulWidget: Stateful widgets can hold state, and their appearance can change over time. They are suitable for implementing components that require dynamic updates or user interactions.
In Flutter, the widget tree represents the hierarchical structure of widgets used to build the user interface of an application. Every Flutter application is constructed using widgets, and these widgets form a tree-like structure where each widget is a node, and the parent-child relationship between widgets determines the layout and composition of the user interface.
The widget tree is a visual representation of how widgets are nested inside one another. When you create a Flutter application, you start with a single root widget, typically a MaterialApp or CupertinoApp, which serves as the entry point of your app. From there, you build your widget tree by adding child widgets to the root and subsequent widgets.
For example, let's say you want to create a simple widget tree with a text widget inside a container widget. The widget tree might look like this:
MaterialApp (Root)
Scaffold
AppBar
Body (Column)
Container
Text
In this example, the MaterialApp serves as the root of the widget tree, and under it, we have a Scaffold widget, which provides a basic structure for the app with an AppBar and a body. The body contains a Column widget, which is used to vertically arrange multiple children. Inside the Column, we have a Container widget, and within the Container, there's a Text widget displaying some text.
Each widget in the tree can have multiple children, and the layout of the user interface is determined by the order and arrangement of these widgets within the tree. When a widget is updated, Flutter efficiently rebuilds only the parts of the widget tree that have changed, making it highly performant.
Below is a simple Flutter widget tree for a user registration page with fields for Full Name, Email, Password, and a Register Button:
MaterialApp (Root)
Scaffold
AppBar
Body (Column)
Container
Column
SizedBox (for top spacing)
Text (Title: User Registration)
SizedBox (for spacing)
TextFormField (Full Name)
SizedBox (for spacing)
TextFormField (Email)
SizedBox (for spacing)
TextFormField (Password)
SizedBox (for spacing)
ElevatedButton (Register)
In this widget tree:
Below is a simple Flutter widget tree for a user login page with fields for Email, Password, and a Login Button:
MaterialApp (Root)
Scaffold
AppBar
Body (Column)
Container
Column
SizedBox (for top spacing)
Text (Title: User Login)
SizedBox (for spacing)
TextFormField (Email)
SizedBox (for spacing)
TextFormField (Password)
SizedBox (for spacing)
ElevatedButton (Login)
In this widget tree:
In conclusion, understanding Flutter widgets is crucial for building engaging and responsive user interfaces. With StatelessWidget and StatefulWidget, developers have the flexibility to design static and dynamic components effectively. By leveraging the power of widgets and their composition, Flutter continues to be a top choice for developers to create cross-platform applications with ease and efficiency. Whether you are a beginner or an experienced developer, mastering Flutter widgets is a key step towards becoming proficient in Flutter app development and delivering delightful user experiences. Happy coding!
My name is Deepak tailor as a fullstack developer. I have been in the IT industry (PHP, Nodejs, flutter) for the last 5 years. For professional and customize web development & app development, you can send inquiry on our email.
----
You can contact him at deepaktailor10@yahoo.in