Junior
What is a widget in Flutter and how is it displayed on the screen?
sobes.tech AI
Answer from AI
Widget — is a fundamental building block in Flutter, describing a part of the user interface. Almost everything in Flutter is a widget: buttons, text, padding, layouts, even the app itself.
Widgets form a widget tree.
The display of a widget on the screen occurs in several stages:
- Build: Flutter traverses the widget tree and constructs an element tree. Each widget in the tree creates a corresponding Element. An Element represents a specific instance of a widget, located at a certain position in the tree.
- Layout: For each element in the element tree, its size and position are determined. This process also happens recursively, bottom-up. Child elements propose sizes to their parents, and parents impose constraints on their children.
- Paint: The Element delegates drawing to the associated RenderObject. RenderObject is an object that knows how to draw itself on the screen using low-level APIs (e.g., Skia). RenderObjects store sizes and positions determined during the Layout stage.
- Composite: Various RenderObjects are combined into layers, which are then sent to the GPU for final rendering.
When the widget's state changes (for example, when calling setState), Flutter marks that widget as "dirty". In the next frame, Flutter rebuilds only those widgets marked as "dirty" and their child widgets. Elements (Element) and RenderObjects are reused if possible, significantly improving performance.
// Example of a simple StatelessWidget
import 'package:flutter/material.dart';
class MyTextWidget extends StatelessWidget {
const MyTextWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// build method returns a widget tree
return const Text('Hello, Flutter!');
}
}
// Example of a StatefulWidget
import 'package:flutter/material.dart';
class CounterWidget extends StatefulWidget {
const CounterWidget({Key? key}) : super(key: key);
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
void _incrementCounter() {
// setState marks the widget as "dirty" and triggers a rebuild
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('Counter:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
ElevatedButton(
onPressed: _incrementCounter,
child: const Text('Increase'),
),
],
);
}
}
Widgets come in two main types:
| Widget Type | Description | Example |
|---|---|---|
| StatelessWidget | Widgets without internal mutable state. Depend only on input parameters. | Text, Icon, Padding |
| StatefulWidget | Widgets that can change their state during their lifetime. | Checkbox, Slider, TextField |