Flutter — UI-фреймворк від Google для нативних крос-платформенних застосунків. За даними Flutter Docs (2025), Flutter використовується більш ніж у 500 000 застосунків у Google Play. Розуміння Widget, StatefulWidget, BuildContext та дерева рендерингу — основа Flutter-розробки.
Головне
Widget — декларативний опис частини UI. Все у Flutter — це Widget: від кнопки до самого застосунку. Widget — це конфігурація (не сам UI). StatelessWidget — незмінний Widget. build() викликається один раз. Не має стану. Використовується для статичного контенту. StatefulWidget — змінний Widget. Має об'єкт State, який може змінюватися. setState() — тригер rebuild. State — змінний об'єкт, прив'язаний до StatefulWidget. Містить дані, які можуть змінюватися.
StatelessWidget — build() викликається один раз. Підходить для заголовків, іконок, статичних текстів. StatefulWidget — build() викликається кожного разу при setState(). Підходить для форм, списків зі змінами, таймерів. InheritedWidget — передавання даних униз без явної передачі через конструктори. Theme, MediaQuery, Navigator — InheritedWidget. BuildContext — позиція Widget у дереві. context.of<T>, context.watch<T>, context.select<T,R> — доступ до InheritedWidget.
// Приклад 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 тільки коли потрібен стан.
Flutter використовує три дерева для ефективного рендерингу. Widget Tree — дерево конфігурацій. Widget'и створюються часто (кожен build), легкі. Element Tree — дерево елементів. Один елемент на кожен Widget (якщо тип не змінюється). Element — міст між Widget і RenderObject. RenderObject Tree — дерево рендерингу. Відповідає за розміри, позиції, малювання. RenderObject — важкий, створюється рідко. Flutter порівнює Widget Tree та оновлює Element Tree, що викликає оновлення RenderObject 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 — Widget, що будує UI на основі Future. connectionState: none, waiting, active, done. Використовується для: HTTP-запитів, читання БД, таймерів. StreamBuilder — Widget для Stream (нескінченний потік даних). snapshot.data, snapshot.hasError, snapshot.hasData. Використовується для: WebSocket, Firebase, оновлення локації. Обидва Widget перебудовуються при отриманні нових даних.
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 — розмір екрана, орієнтація, платформа, 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 rebuild | TextField, Checkbox, AnimationController |
| InheritedWidget | Передача даних униз | Theme, MediaQuery, Navigator |
| ProxyWidget | Обгортка для інших Widget'ів | ParentDataWidget (Positioned, Expanded) |
| RenderObjectWidget | Створює RenderObject | Column, Row, Stack (кастомні) |
StatelessWidget — для статики. StatefulWidget — для динаміки. InheritedWidget — для DI. IT Sectr рекомендує StatelessWidget за замовчуванням і StatefulWidget тільки при необхідності.
LayoutBuilder — адаптація під розміри батька. OrientationBuilder — адаптація під орієнтацію. Expanded vs Flexible — розподіл простору в Row/Column. MediaQuery — breakpoints для планшетів і десктопів. SafeArea — відступи від системних елементів (notch, status bar). AspectRatio — збереження пропорцій. IT Sectr рекомендує LayoutBuilder для адаптивних макетів і OrientationBuilder для альбомної орієнтації.
Unit тести — тестування бізнес-логіки, репозиторіїв, моделей. dart test — запуск. Widget тести — тестування віджетів ізольовано. WidgetTester — pumpWidget, tap, enterText. Integration тести — повні сценарії на реальному пристрої/емуляторі. Mockito — мокування залежностей. Golden тести — порівняння скріншотів (золоті файли). IT Sectr рекомендує Widget тести для кожного екрана і Unit тести для бізнес-логіки.
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 анімації — 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 для складних сценаріїв.
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 — простий 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 — незмінний, build один раз. StatefulWidget — зі змінним State та setState().
Widget Tree — конфігурація. Element Tree — міст. RenderObject Tree — рендеринг (розміри, малювання).
BuildContext — позиція Widget у дереві. InheritedWidget — передача даних униз (Theme, MediaQuery).
Navigator — стек екранів. push() → pop(). Named Routes — рядкові імена. Navigator 2.0 — декларативний.
Hot Reload — ін'єкція коду за 1-2 секунди, збереження стану. Hot Restart — повний перезапуск.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.