Flutter Widgets — ce este, arborele de widgeturi și build

Autor: IT Sectr Publicat: 2026-02-21 Timp de citire: 8 min

Flutter Widgets — blocurile de construcție de bază ale interfeței de utilizator în frameworkul Google Flutter, lansat în versiunea stabilă 1.0 în decembrie 2018. În Flutter totul este un widget: de la ecran și buton până la spațiere și aliniere. Widgeturile formează un arbore (widget tree) pe care Flutter îl randă pe propriul motor Skia/Impeller, ocolind componentele native ale platformei. Potrivit Google I/O (2025), Flutter este folosit în peste 500 000 de aplicații în Google Play și App Store. Arhitectura Flutter împarte widgeturile în StatelessWidget (imuabile) și StatefulWidget (cu stare modificabilă prin obiectul State).

Principalele

  • Flutter Widgets — toate elementele UI în Flutter: de la ecran și buton până la spațiere și aliniere; frameworkul nu folosește componente native ale platformei.
  • StatelessWidget — widget fără stare modificabilă; afișează datele transmise prin constructor și nu se schimbă după construire (build).
  • StatefulWidget — widget cu stare modificabilă, stocată într-un obiect State separat, care supraviețuiește rebuildurilor.
  • Arborele de widgeturi (widget tree) — ierarhia widgeturilor care descriu UI; Flutter o transformă în Element Tree și Render Tree pentru randare.
  • BuildContext — contextul de construcție, care oferă acces la poziția widgetului în arbore, temă, MediaQuery și InheritedWidget.

Ce sunt Flutter Widgets?

Flutter Widgets — toate elementele UI în frameworkul Flutter, implementate ca clase Dart imuabile (immutable). Un widget este o configurație a unui element UI: dimensiunea, culoarea, poziția, gestionarea evenimentelor. Spre deosebire de Android (XML + View) sau iOS (Storyboard + UIView), Flutter nu folosește componente native — totul este desenat de motorul Skia (Android/iOS/Linux) sau Impeller (iOS/macOS) pe Canvas. Acest lucru asigură un aspect identic pe toate platformele fără diferențe de platformă. Flutter vine cu două seturi de widgeturi: Material Widgets (design Google Material Design 3 pentru Android/Web) și Cupertino Widgets (design Apple HIG pentru iOS/macOS). Dezvoltatorul poate combina ambele seturi într-o singură aplicație. Fiecare widget are metoda build(), care returnează un widget copil sau o compoziție a acestora — astfel se construiește arborele de widgeturi.

Cei trei arbori Flutter

Flutter operează cu trei arbori: Widget Tree (configurație, creată de dezvoltator), Element Tree (potrivirea widgetului cu poziția în arbore, gestionată de framework), Render Tree (obiecte care calculează layoutul și execută paintul). Widgetul creează Elementul, care creează RenderObject. Elementul este reutilizat la schimbarea configurației (rebuild) — acesta este mecanismul de optimizare al Flutter: dacă tipul widgetului și key coincid, Elementul nu este recreat, ci doar configurația nouă este actualizată. Înțelegerea celor trei arbori este cheia optimizării performanței aplicațiilor Flutter.

StatelessWidget: widgeturi imuabile

StatelessWidget — un widget care nu stochează stare internă. Primește parametrii prin constructor și îi afișează fără posibilitatea de modificare după construire. StatelessWidget este ideal pentru elemente statice: titluri, iconițe, avatare, liste cu date fixe. Metoda build() este apelată o dată la creare și la modificarea widgetului părinte. Deoarece StatelessWidget nu are stare, nu necesită un obiect State separat — build() este definit direct în clasa widgetului.

dart
import 'package:flutter/material.dart';

class ProfileHeader extends StatelessWidget {
  final String name;
  final String avatarUrl;

  const ProfileHeader({super.key, required this.name, required this.avatarUrl});

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        CircleAvatar(
          radius: 24,
          backgroundImage: NetworkImage(avatarUrl),
        ),
        const SizedBox(width: 12),
        Text(
          name,
          style: const TextStyle(
            fontSize: 18,
            fontWeight: FontWeight.bold,
          ),
        ),
      ],
    );
  }
}

ProfileHeader — un StatelessWidget care primește name și avatarUrl prin constructor. CircleAvatar afișează avatarul, Text — numele. Widgetul nu poate schimba aceste valori după creare. Folosirea constructorului const (const ProfileHeader) permite Flutter să reutilizeze instanța widgetului la rebuildul părintelui — aceasta este o microoptimizare recomandată pentru toate StatelessWidgeturile.

StatefulWidget: widgeturi cu stare

StatefulWidget — un widget cu stare modificabilă, stocată într-un obiect State separat. Însuși StatefulWidget este imuabil (immutable), ca și StatelessWidget. Partea modificabilă este extrasă în State: State — un obiect care este creat o dată și supraviețuiește rebuildurilor multiple ale widgetului. Când starea se schimbă (setState()), Flutter apelează build() al State, actualizând UI. StatefulWidget este folosit pentru elemente interactive: contoare, câmpuri text, checkboxuri, animații, temporizatoare.

dart
import 'package:flutter/material.dart';

class LikeButton extends StatefulWidget {
  const LikeButton({super.key});

  @override
  State<LikeButton> createState() => _LikeButtonState();
}

class _LikeButtonState extends State<LikeButton> {
  bool liked = false;
  int count = 42;

  void _toggleLike() {
    setState(() {
      liked = !liked;
      count += liked ? 1 : -1;
    });
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _toggleLike,
      child: Text(liked ? '♥ $count' : '♡ $count'),
    );
  }
}

LikeButton — un StatefulWidget cu clasa State _LikeButtonState. Câmpurile liked și count sunt starea stocată în State și nu se resetează la rebuild. setState() notifică Flutter despre necesitatea reconstruirii UI. Flutter nu recrează State la fiecare rebuild al părintelui — doar la schimbarea configurației (key sau tipul widgetului). În IT Sectr folosim StatelessWidget pentru afișare și StatefulWidget pentru componente interactive, respectând principiul minimizării StatefulWidget până la granițele mutației.

Arborele de widgeturi: de la Widget la RenderObject

Widget Tree — structura ierarhică a widgeturilor care descrie UI-ul aplicației. Flutter transformă Widget Tree în Element Tree: fiecare Widget creează un Element care urmărește poziția în arbore și legătura cu RenderObject. Render Tree execută layout (determinarea dimensiunilor și pozițiilor) și paint (desenarea). Elementul este stratul cheie de optimizare: dacă tipul widgetului și key nu s-au schimbat la rebuild, Elementul este reutilizat, actualizând configurația fără a recrea RenderObject. Acest lucru asigură performanța Flutter la frecvență ridicată de cadre (60/120 FPS).

dart
import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter Widgets')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Icon(Icons.flutter_dash, size: 80),
            const SizedBox(height: 16),
            const Text(
              'Salut, Flutter!',
              style: TextStyle(fontSize: 24),
            ),
          ],
        ),
      ),
    );
  }
}

Arborele de widgeturi HomeScreen: Scaffold → AppBar + Center → Column → [Icon, SizedBox, Text]. Scaffold — widgetul de layout principal Material Design. Center centrează Columnul copil. Column aranjează copiii vertical cu aliniere la centru (mainAxisAlignment.center). Flutter calculează layoutul de sus în jos (constraints sunt transmise de la părinte), iar dimensiunile — de jos în sus (sizedByParent sau sizing from children).

BuildContext: contextul de construcție și accesul la arbore

BuildContext — un descriptor al poziției widgetului în Element Tree. Fiecare metodă build() primește BuildContext, prin care widgetul poate accesa:MediaQuery (dimensiunea ecranului, orientarea, densitatea pixelilor, zona sigură), Theme (MaterialThemeData sau CupertinoThemeData), Navigator (stiva de navigare), ScaffoldMessenger (SnackBar), InheritedWidget (transmiterea datelor în josul arborelui). BuildContext nu trebuie stocat după terminarea build() sau folosit în afara contextului sincron — aceasta duce la erori de tip „Scaffold.of() called with a context that does not contain a Scaffold". În locul stocării contextului, folosiți widgetul Builder sau patternul InheritedWidget pentru acces la date.

Key: identificarea widgetului în arbore

Key — un parametru opțional al constructorului fiecărui widget (super.key). Key ajută Flutter să identifice widgetul la schimbarea ordinii/numărului elementelor dintr-o listă. Fără key, Flutter compară widgeturile după tip și poziție; la adăugarea unui element în mijlocul listei fără key, Flutter reutilizează Elementul pentru widgetul greșit, cauzând buguri de stare (StatefulWidget) și animație. Folosiți ValueKey (identificator unic) pentru liste, ObjectKey (pe baza obiectului de date), UniqueKey (unic garantat la fiecare rebuild — pentru recrearea forțată).

Catalogul widgeturilor Flutter: Material, Cupertino, Layout

Flutter SDK (versiunea stabilă 3.3+, Dart 3+) include 200+ widgeturi încorporate, împărțite pe categorii: Layout (Row, Column, Stack, Container, Expanded, Flexible, Wrap, GridView, ListView, CustomScrollView), Material Design (Scaffold, AppBar, Card, Drawer, BottomNavigationBar, FloatingActionButton, TabBar, Chip, DataTable), Cupertino (CupertinoPageScaffold, CupertinoNavigationBar, CupertinoButton, CupertinoTabBar), Painting & Effects (Opacity, DecoratedBox, ClipRect, Transform, BackdropFilter, ShaderMask), Async (FutureBuilder, StreamBuilder) și Accessibility (Semantics, MergeSemantics, ExcludeSemantics). Widgeturile de Layout sunt baza oricărui UI Flutter: Row pentru secvențe orizontale, Column pentru verticale, Stack pentru elemente suprapuse, Container cu BoxDecoration pentru decorare.

CategorieWidgeturi cheieRol
LayoutRow, Column, Stack, Container, Expanded, FlexiblePoziționarea și dimensiunile elementelor copil
MaterialScaffold, AppBar, Card, Drawer, FAB, TabBarComponente UI Material Design 3
CupertinoCupertinoPageScaffold, CupertinoNavigationBar, CupertinoButtonComponente stilizate iOS
PaintingOpacity, ClipRect, Transform, DecoratedBox, BackdropFilterEfecte vizuale și tăiere
AsyncFutureBuilder, StreamBuilderÎncărcarea asincronă a datelor cu stări UI
AccessibilitySemantics, MergeSemanticsMarcare semantică pentru cititoare de ecran

Întrebări frecvente

Cu ce diferă StatelessWidget de StatefulWidget?

StatelessWidget nu are stare internă — toate datele sunt transmise prin constructor și nu se schimbă. StatefulWidget stochează starea modificabilă într-un obiect State separat, care supraviețuiește rebuildurilor. Schimbarea stării apelează setState(), iar Flutter reconstruiește UI. Pentru elemente imuabile folosiți StatelessWidget; pentru interactive — StatefulWidget.

Ce este BuildContext în Flutter?

BuildContext — un descriptor al poziției widgetului în Element Tree, transmis metodei build(). Prin context, widgetul accesează MediaQuery, Theme, Navigator, ScaffoldMessenger și InheritedWidget. BuildContext nu trebuie stocat după terminarea build(). Pentru acces la date folosiți widgetul Builder sau InheritedWidget.

Este necesar să știu Dart pentru a lucra cu Flutter?

Da, Flutter folosește Dart ca singur limbaj de programare. Dart este un limbaj tipizat static cu null-safety, tipuri sigure (sound null safety), extension methods și pattern matching. Pentru început sunt suficiente bazele Dart: clase, funcții, async/await, colecții. Dart este compilat în cod nativ (AOT) prin Dart Native și în JavaScript (pentru web) prin Dart2JS.

Flutter este doar pentru platforme mobile?

Nu, Flutter suportă șase platforme: iOS, Android, Web, macOS, Windows, Linux. Peste 90% din cod este comun pentru toate platformele. Adaptările de platformă (cameră, sistem de fișiere) se realizează prin pluginuri sau platform channels. Pentru desktop, Flutter folosește învelișul de fereastră Flutter Desktop, iar pentru web — motorul CanvasKit (WebGL) sau rendererul HTML.

Cum asigură Flutter performanța de 60 FPS?

Flutter atinge 60/120 FPS datorită: propriului motor 2D (Skia/Impeller), absenței unui bridge nativ (spre deosebire de React Native), celor trei arbori (Widget → Element → Render) cu reutilizarea Elementului la tip/key neschimbat, algoritmului de layout cu trecere unidirecțională (constraints down, sizes up) și RepaintBoundary pentru izolarea redesenării zonelor individuale ale ecranului.

Rezumat

  • Flutter Widgets — toate elementele UI: de la Scaffold la SizedBox; Flutter le desenează singur pe Skia/Impeller, fără a folosi componente native.
  • StatelessWidget — widget fără stare; build() returnează UI pe baza parametrilor imuabili ai constructorului.
  • StatefulWidget — widget cu stare modificabilă în State; setState() declanșează rebuildul UI.
  • Trei arbori Flutter: Widget (configurație) → Element (poziție) → Render (layout + paint); Elementul este reutilizat pentru performanță.
  • BuildContext — poziția widgetului în arbore; acces la MediaQuery, Theme, Navigator, InheritedWidget.
  • Material și Cupertino — două seturi de widgeturi pentru Google Material Design 3 și Apple HIG.
  • Key (ValueKey, ObjectKey, UniqueKey) — identificarea widgetului la schimbarea ordinii/numărului în listă.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și