Flutter у мобільній розробці: що це, ключові поняття та як працює

Автор: IT Sectr Опубліковано: 2026-07-09 Час читання: 11 хв

Flutter — UI-фреймворк від Google для нативних крос-платформенних застосунків. За даними Flutter Docs (2025), Flutter використовується більш ніж у 500 000 застосунків у Google Play. Розуміння Widget, StatefulWidget, BuildContext та дерева рендерингу — основа Flutter-розробки.

Головне

  • Widget — базовий будівельний блок. StatelessWidget (незмінний) vs StatefulWidget (змінний з setState()).
  • Три дерева: Widget Tree (конфігурація), Element Tree (елементи), RenderObject Tree (рендеринг).
  • BuildContext — доступ до InheritedWidget: Theme, MediaQuery, Navigator. InheritedWidget — передавання даних униз.
  • Navigator — стек екранів (Routes). Navigator 2.0 (Router) — декларативна навігація.
  • Hot Reload — ін'єкція змін за 1-2 секунди. Зберігає стан. Hot Restart — повний перезапуск.

Flutter: основи Widget, StatelessWidget та StatefulWidget

Widget — декларативний опис частини UI. Все у Flutter — це Widget: від кнопки до самого застосунку. Widget — це конфігурація (не сам UI). StatelessWidget — незмінний Widget. build() викликається один раз. Не має стану. Використовується для статичного контенту. StatefulWidget — змінний Widget. Має об'єкт State, який може змінюватися. setState() — тригер rebuild. State — змінний об'єкт, прив'язаний до StatefulWidget. Містить дані, які можуть змінюватися.

StatelessWidget vs StatefulWidget

StatelessWidget — build() викликається один раз. Підходить для заголовків, іконок, статичних текстів. StatefulWidget — build() викликається кожного разу при setState(). Підходить для форм, списків зі змінами, таймерів. InheritedWidget — передавання даних униз без явної передачі через конструктори. Theme, MediaQuery, Navigator — InheritedWidget. BuildContext — позиція Widget у дереві. context.of<T>, context.watch<T>, context.select<T,R> — доступ до InheritedWidget.

dart
// Приклад Flutter Widget: StatefulWidget з setState
class CounterWidget extends StatefulWidget {
  const CounterWidget({Key? key}) : super(key: key);

  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _counter = 0;

  void _increment() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter Counter')),
      body: const Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('You have pushed the button:'),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _increment,
        child: const Icon(Icons.add),
      ),
    );
  }
}

Widget — конфігурація. StatelessWidget — незмінний. StatefulWidget — змінний з setState(). IT Sectr рекомендує починати з StatelessWidget і переходити на StatefulWidget тільки коли потрібен стан.

Дерева (Widget Tree, Element Tree, RenderObject Tree)

Flutter використовує три дерева для ефективного рендерингу. Widget Tree — дерево конфігурацій. Widget'и створюються часто (кожен build), легкі. Element Tree — дерево елементів. Один елемент на кожен Widget (якщо тип не змінюється). Element — міст між Widget і RenderObject. RenderObject Tree — дерево рендерингу. Відповідає за розміри, позиції, малювання. RenderObject — важкий, створюється рідко. Flutter порівнює Widget Tree та оновлює Element Tree, що викликає оновлення RenderObject Tree.

Keys та Element Tree

Key — ідентифікатор Widget в Element Tree. ValueKey, ObjectKey, UniqueKey, PageStorageKey. Key дозволяє Flutter зіставляти старі та нові Widget при rebuild. Без Key Flutter зіставляє за типом Widget та позицією. GlobalKey — доступ до State з іншого Widget. Використовується для: складних форм, анімацій, доступу до State в тестах. IT Sectr рекомендує використовувати Key для списків (List.generate) та уникати GlobalKey без необхідності.

Expanded — Widget, що заповнює доступний простір у Row/Column/Flex. Flexible — не примушує до заповнення (може бути меншим). MediaQuery — InheritedWidget з інформацією про пристрій: розмір екрана, орієнтація, платформа, текстовий масштаб. Theme/ThemeData — централізована тема. Theme.of(context) — доступ. MaterialApp — кореневий Widget з налаштуванням маршрутизації, тем, локалей. Scaffold — базовий layout з AppBar, Drawer, BottomNavigationBar. AppBar — верхня панель.

Navigator — стек маршрутів (Routes). Navigator.push — відкрити екран (повертає Future). Navigator.pop — закрити (з результатом). MaterialPageRoute — анімований перехід (слайд справа). Named Routes — рядкові ідентифікатори. onGenerateRoute — централізований обробник. Navigator 2.0 (Router + RouteInformationParser + RouterDelegate) — декларативна навігація для веб, deep linking та складних сценаріїв.

Navigator 2.0 — декларативна навігація. Router — центральний Widget. RouteInformationParser — парсинг URL. RouterDelegate — управління стеком. GoRouter (пакет) — спрощена обгортка над Navigator 2.0. Підтримує: іменовані маршрути, параметри, redirect, deep linking. IT Sectr рекомендує GoRouter для більшості проектів і Navigator 2.0 тільки для складних сценаріїв (веб, десктоп).

Асинхронність (FutureBuilder, StreamBuilder)

FutureBuilder — Widget, що будує UI на основі Future. connectionState: none, waiting, active, done. Використовується для: HTTP-запитів, читання БД, таймерів. StreamBuilder — Widget для Stream (нескінченний потік даних). snapshot.data, snapshot.hasError, snapshot.hasData. Використовується для: WebSocket, Firebase, оновлення локації. Обидва Widget перебудовуються при отриманні нових даних.

State Management

Provider — простий DI + state management. ChangeNotifierProvider, MultiProvider. Riverpod — сучасна заміна Provider: compile-safe, не залежить від BuildContext. Bloc — Event-Driven архітектура: Cubit (прості події) vs Bloc (складні). GetX — легкий state management + DI + routing. setState — найпростіший, для локального стану. IT Sectr рекомендує Riverpod для нових проектів і Provider для існуючих.

Теми та адаптація (MediaQuery, ThemeData)

MediaQuery — розмір екрана, орієнтація, платформа, textScaleFactor. MediaQuery.of(context).size.width. ThemeData — тема застосунку: кольори, шрифти, форми. Theme.of(context).textTheme.bodyLarge. Hot Reload — ін'єкція коду в працюючий застосунок. Зберігає стан. Не підтримує: зміну main(), глобальні змінні, статичні поля. Hot Restart — повний перезапуск застосунку (втрата стану). Hot Reload — головна перевага Flutter для розробника.

Тип Widget Опис Приклади
StatelessWidgetНезмінний, build один разText, Icon, Padding, Center
StatefulWidgetЗмінний, setState rebuildTextField, Checkbox, AnimationController
InheritedWidgetПередача даних унизTheme, MediaQuery, Navigator
ProxyWidgetОбгортка для інших Widget'івParentDataWidget (Positioned, Expanded)
RenderObjectWidgetСтворює RenderObjectColumn, Row, Stack (кастомні)

StatelessWidget — для статики. StatefulWidget — для динаміки. InheritedWidget — для DI. IT Sectr рекомендує StatelessWidget за замовчуванням і StatefulWidget тільки при необхідності.

Responsive Layout

LayoutBuilder — адаптація під розміри батька. OrientationBuilder — адаптація під орієнтацію. Expanded vs Flexible — розподіл простору в Row/Column. MediaQuery — breakpoints для планшетів і десктопів. SafeArea — відступи від системних елементів (notch, status bar). AspectRatio — збереження пропорцій. IT Sectr рекомендує LayoutBuilder для адаптивних макетів і OrientationBuilder для альбомної орієнтації.

Тестування (Widget, Integration, Unit)

Unit тести — тестування бізнес-логіки, репозиторіїв, моделей. dart test — запуск. Widget тести — тестування віджетів ізольовано. WidgetTester — pumpWidget, tap, enterText. Integration тести — повні сценарії на реальному пристрої/емуляторі. Mockito — мокування залежностей. Golden тести — порівняння скріншотів (золоті файли). IT Sectr рекомендує Widget тести для кожного екрана і Unit тести для бізнес-логіки.

dart
void main() {
  testWidgets('Counter increments on tap', (tester) async {
    await tester.pumpWidget(const MaterialApp(home: CounterWidget()));

    expect(find.text('0'), findsOneWidget);

    await tester.tap(find.byType(FloatingActionButton));
    await tester.pump();

    expect(find.text('1'), findsOneWidget);
  });
}

Анімації (Implicit, Explicit, Hero)

Implicit анімації — AnimatedContainer, AnimatedOpacity, AnimatedPadding, TweenAnimationBuilder. Зміна властивостей автоматично анімується. Explicit анімації — AnimationController з Tween. forward() / reverse(). Hero анімація — Hero Widget з тегом — анімація переходу між екранами. Staggered анімація — ланцюжок анімацій з Interval. Lottie — інтеграція After Effects анімацій. Rive — інтерактивні анімації (state machine). IT Sectr рекомендує AnimatedContainer для 80% випадків і AnimationController для складних сценаріїв.

dart
class AnimatedBox extends StatefulWidget {
  @override
  State<AnimatedBox> createState() => _AnimatedBoxState();
}

class _AnimatedBoxState extends State<AnimatedBox> {
  bool _expanded = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => setState(() => _expanded = !_expanded),
      child: AnimatedContainer(
        duration: const Duration(milliseconds: 300),
        curve: Curves.easeInOut,
        width: _expanded ? 200 : 100,
        height: _expanded ? 200 : 100,
        color: _expanded ? Colors.blue : Colors.red,
        child: const Center(child: Text('Tap me')),
      ),
    );
  }
}

Мережа (http, dio, graphql)

http — простий HTTP-клієнт (get, post, put, delete). dio — просунутий клієнт з інтерцепторами, таймаутами, повторними спробами, логуванням. graphql_flutter — GraphQL клієнт для Flutter. json_serializable — генерація fromJson/toJson через анотації. Retrofit Dart — type-safe HTTP клієнт як Retrofit. WebSocket — через web_socket_channel. Firebase — Cloud Firestore, Realtime Database, Cloud Functions. IT Sectr рекомендує dio для REST API та graphql_flutter для GraphQL.

Flutter DevTools — набір інструментів: Inspector (дерево віджетів), Timeline (продуктивність), Memory, Network, Logging. Profile mode — профілювання без дебагу. Performance overlay — FPS, час побудови. Flame chart — флейм чарт. DevTools — обов'язковий інструмент для оптимізації Flutter-застосунків у продакшні.

Flutter Web — компіляція Flutter у WASM (WebAssembly). CanvasKit (Skia) vs HTML renderer. CanvasKit — pixel-perfect, але важчий. HTML renderer — легкий, але з обмеженнями. WASM (Flutter 3.22+) — нативна продуктивність. Responsive адаптація через LayoutBuilder та MediaQuery. IT Sectr рекомендує CanvasKit для десктопних веб-застосунків і HTML renderer для контентних сайтів.

Часто задавані питання

У чому різниця між StatelessWidget та StatefulWidget?

StatelessWidget — незмінний, build один раз. StatefulWidget — зі змінним State та setState().

Що таке Widget Tree, Element Tree та RenderObject Tree?

Widget Tree — конфігурація. Element Tree — міст. RenderObject Tree — рендеринг (розміри, малювання).

Що таке BuildContext та InheritedWidget?

BuildContext — позиція Widget у дереві. InheritedWidget — передача даних униз (Theme, MediaQuery).

Як працюють Navigator та Route у Flutter?

Navigator — стек екранів. push() → pop(). Named Routes — рядкові імена. Navigator 2.0 — декларативний.

Як працює Hot Reload у Flutter?

Hot Reload — ін'єкція коду за 1-2 секунди, збереження стану. Hot Restart — повний перезапуск.

Підсумки

  • Widget — все Widget. StatelessWidget vs StatefulWidget — базова дихотомія.
  • Три дерева: Widget → Element → RenderObject. Widget — конфігурація, RenderObject — рендеринг.
  • BuildContext + InheritedWidget — доступ до Theme, MediaQuery, Navigator без явної передачі.
  • Navigator — стек екранів. Navigator 2.0 — декларативна навігація для веб та deep links.
  • FutureBuilder — для Future. StreamBuilder — для Stream (Firebase, WebSocket).
  • MaterialApp + Scaffold — каркас застосунку. ThemeData — централізована тема.
  • Hot Reload — killer feature Flutter. Оновлення коду за секунди зі збереженням стану.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект