Flutter Widgets — шта је то, стабло виџета и build

Аутор: IT Sectr Објављено: 2026-02-21 Време читања: 8 мин

Flutter Widgets — основни градивни блокови корисничког интерфејса у Google Flutter оквиру, објављеном у стабилној верзији 1.0 у децембру 2018. године. У Flutter-у све је виџет: од екрана и дугмета до размака и поравнања. Виџети формирају стабло (widget tree) које Flutter рендерује на сопствени погон Skia/Impeller, заобилазећи native компоненте платформе. Према Google I/O (2025), Flutter се користи у преко 500 000 апликација у Google Play и App Store. Архитектура Flutter-а дели виџете на StatelessWidget (непроменљиве) и StatefulWidget (са променљивим стањем путем State објекта).

Главно

  • Flutter Widgets — сви UI елементи у Flutter-у: од екрана и дугмета до размака и поравнања; оквир не користи native компоненте платформе.
  • StatelessWidget — виџет без променљивог стања; приказује податке прослеђене кроз конструктор и не мења се након изградње (build).
  • StatefulWidget — виџет са променљивим стањем, смештеним у засебном State објекту који преживљава rebuild-ове.
  • Стабло виџета (widget tree) — хијерархија виџета који описују UI; Flutter је претвара у Element Tree и Render Tree ради рендеровања.
  • BuildContext — контекст изградње, који пружа приступ позицији виџета у стаблу, теми, MediaQuery и InheritedWidget.

Шта су Flutter Widgets?

Flutter Widgets — сви UI елементи у Flutter оквиру, имплементирани као непроменљиве (immutable) Dart класе. Виџет је конфигурација UI елемента: његова величина, боја, положај, руковање догађајима. За разлику од Android-а (XML + View) или iOS-а (Storyboard + UIView), Flutter не користи native компоненте — све се црта погоном Skia (Android/iOS/Linux) или Impeller (iOS/macOS) на Canvas. То обезбеђује идентичан изглед на свим платформама без платформских разлика. Flutter се испоручује са два скупа виџета: Material Widgets (дизајн Google Material Design 3 за Android/Web) и Cupertino Widgets (дизајн Apple HIG за iOS/macOS). Програмер може комбиновати оба скупа у једној апликацији. Сваки виџет има метод build() који враћа виџет потомак или њихову композицију — тако се гради стабло виџета.

Три Flutter стабла

Flutter оперише са три стабла: Widget Tree (конфигурација, креира је програмер), Element Tree (повезивање виџета са позицијом у стаблу, управља оквир), Render Tree (објекти који израчунавају layout и врше paint). Widget ствара Element који ствара RenderObject. Element се поново користи при промени конфигурације (rebuild) — то је механизам оптимизације Flutter-а: ако се тип виџета и key поклапају, Element се не ствара поново, већ се ажурира нова конфигурација. Разумевање три стабла је кључ за оптимизацију перформанси Flutter апликација.

StatelessWidget: непроменљиви виџети

StatelessWidget — виџет који не чува унутрашње стање. Прима параметре кроз конструктор и приказује их без могућности промене након изградње. StatelessWidget је идеалан за статичке елементе: заглавља, иконе, аватаре, листе са фиксним подацима. Метод build() се позива једном приликом креирања и при промени родитељског виџета. Пошто StatelessWidget нема стање, не захтева засебан State објекат — build() је дефинисан директно у класи виџета.

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 — StatelessWidget који прима name и avatarUrl кроз конструктор. CircleAvatar приказује аватар, Text — име. Виџет не може променити ове вредности након креирања. Коришћење const конструктора (const ProfileHeader) омогућава Flutter-у да поново користи инстанцу виџета при rebuild родитеља — то је микрооптимизација препоручена за све StatelessWidget.

StatefulWidget: виџети са стањем

StatefulWidget — виџет са променљивим стањем које се чува у засебном State објекту. Сам StatefulWidget је непроменљив (immutable), као и StatelessWidget. Променљиви део је издвојен у State: State — објекат који се креира једном и преживљава вишеструке rebuild-ове виџета. Када се стање промени (setState()), Flutter позива build() State-а, ажурирајући UI. StatefulWidget се користи за интерактивне елементе: бројаче, текстуална поља, checkbox-ове, анимације, тајмере.

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 — StatefulWidget са State класом _LikeButtonState. Поља liked и count су стање које се чува у State-у и не ресетује се при rebuild. setState() обавештава Flutter о потреби поновне изградње UI. Flutter не ствара State поново при сваком rebuild родитеља — само при промени конфигурације (key или тип виџета). У IT Sectr користимо StatelessWidget за приказ и StatefulWidget за интерактивне компоненте, пратећи принцип минимизације StatefulWidget до граница мутације.

Стабло виџета: од Widget до RenderObject

Widget Tree — хијерархијска структура виџета која описује UI апликације. Flutter претвара Widget Tree у Element Tree: сваки Widget ствара Element који прати позицију у стаблу и везу са RenderObject. Render Tree извршава layout (одређивање величина и положаја) и paint (цртање). Element је кључни оптимизациони слој: ако се тип виџета и key нису променили при rebuild, Element се поново користи, ажурирајући конфигурацију без стварања новог RenderObject-а. То обезбеђује перформансе Flutter-а при високој фреквенцији кадрова (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(
              'Здраво, Flutter!',
              style: TextStyle(fontSize: 24),
            ),
          ],
        ),
      ),
    );
  }
}

Стабло виџета HomeScreen: Scaffold → AppBar + Center → Column → [Icon, SizedBox, Text]. Scaffold — главни layout виџет Material Design-а. Center центрира потомак Column. Column распоређује децу вертикално са поравнањем на средину (mainAxisAlignment.center). Flutter израчунава layout одозго надоле (constraints се преносе од родитеља), а величине одоздо нагоре (sizedByParent или sizing from children).

BuildContext: контекст изградње и приступ стаблу

BuildContext — дескриптор позиције виџета у Element Tree. Сваки метод build() добија BuildContext кроз који виџет може приступити:MediaQuery (величина екрана, оријентација, густина пиксела, сигурна зона), Theme (MaterialThemeData или CupertinoThemeData), Navigator (навигациони стек), ScaffoldMessenger (SnackBar), InheritedWidget (прослеђивање података низ стабло). BuildContext не треба чувати након завршетка build() или користити ван синхроног контекста — то доводи до грешака „Scaffold.of() called with a context that does not contain a Scaffold". Уместо чувања context-а, користите Builder виџет или InheritedWidget образац за приступ подацима.

Key: идентификација виџета у стаблу

Key — опциони параметар конструктора сваког виџета (super.key). Key помаже Flutter-у да идентификује виџет при промени редоследа/броја елемената у листи. Без key-а, Flutter пореди виџете по типу и позицији; при додавању елемента у средину листе без key-а, Flutter поново користи Element за погрешан виџет, изазивајући грешке стања (StatefulWidget) и анимације. Користите ValueKey (јединствени идентификатор) за листе, ObjectKey (на основу објекта података), UniqueKey (гарантовано јединствен при сваком rebuild — за присилно поновно креирање).

Каталог виџета Flutter: Material, Cupertino, Layout

Flutter SDK (стабилна верзија 3.3+, Dart 3+) укључује 200+ уграђених виџета, подељених у категорије: 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) и Accessibility (Semantics, MergeSemantics, ExcludeSemantics). Layout виџети су основа сваког Flutter UI-ја: Row за хоризонталне секвенце, Column за вертикалне, Stack за преклапајуће елементе, Container са BoxDecoration за декорацију.

КатегоријаКључни виџетиНамена
LayoutRow, Column, Stack, Container, Expanded, FlexibleПозиционирање и величине елемената потомака
MaterialScaffold, AppBar, Card, Drawer, FAB, TabBarUI компоненте Material Design 3
CupertinoCupertinoPageScaffold, CupertinoNavigationBar, CupertinoButtonКомпоненте стилизоване за iOS
PaintingOpacity, ClipRect, Transform, DecoratedBox, BackdropFilterВизуелни ефекти и сечење
AsyncFutureBuilder, StreamBuilderАсинхроно учитавање података са UI стањима
AccessibilitySemantics, MergeSemanticsСемантичко означавање за читаче екрана

Често постављана питања

По чему се StatelessWidget разликује од StatefulWidget?

StatelessWidget нема унутрашње стање — сви подаци се прослеђују кроз конструктор и не мењају се. StatefulWidget чува променљиво стање у засебном State објекту који преживљава rebuild-ове. Промена стања позива setState(), а Flutter поново гради UI. За непроменљиве елементе користите StatelessWidget; за интерактивне — StatefulWidget.

Шта је BuildContext у Flutter-у?

BuildContext — дескриптор позиције виџета у Element Tree, прослеђен методи build(). Кроз context виџет приступа MediaQuery, Theme, Navigator, ScaffoldMessenger и InheritedWidget. BuildContext не треба чувати након завршетка build(). За приступ подацима користите Builder виџет или InheritedWidget.

Да ли је потребно знати Dart за рад са Flutter-ом?

Да, Flutter користи Dart као једини програмски језик. Dart је статички типизиран језик са null-safety, звучним типовима (sound null safety), extension methods и pattern matching. За почетак су довољне основе Dart-а: класе, функције, async/await, колекције. Dart се компајлира у изворни код (AOT) путем Dart Native и у JavaScript (за веб) путем Dart2JS.

Да ли је Flutter само за мобилне платформе?

Не, Flutter подржава шест платформи: iOS, Android, Web, macOS, Windows, Linux. Преко 90% кода је заједничко за све платформе. Прилагођавања платформи (камера, фајл систем) се реализују кроз додатке или platform channels. За десктоп Flutter користи прозорски омотач Flutter Desktop, за веб — погон CanvasKit (WebGL) или HTML рендерер.

Како Flutter обезбеђује перформансе од 60 FPS?

Flutter постиже 60/120 FPS захваљујући: сопственом 2D погону (Skia/Impeller), одсуству native bridge-а (за разлику од React Native), три стабла (Widget → Element → Render) са поновним коришћењем Element-а при непромењеном типу/key, layout алгоритму са једносмерним пролазом (constraints down, sizes up) и RepaintBoundary за изолацију прецртавања појединих зона екрана.

Резиме

  • Flutter Widgets — сви UI елементи: од Scaffold до SizedBox; Flutter их сам црта на Skia/Impeller, не користећи native компоненте.
  • StatelessWidget — виџет без стања; build() враћа UI на основу непроменљивих параметара конструктора.
  • StatefulWidget — виџет са променљивим стањем у State; setState() изазива rebuild UI.
  • Три стабла Flutter: Widget (конфигурација) → Element (позиција) → Render (layout + paint); Element се поново користи за перформансе.
  • BuildContext — позиција виџета у стаблу; приступ MediaQuery, Theme, Navigator, InheritedWidget.
  • Material и Cupertino — два скупа виџета за Google Material Design 3 и Apple HIG.
  • Key (ValueKey, ObjectKey, UniqueKey) — идентификација виџета при промени редоследа/броја у листи.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође