Dart і перший застосунок
Flutter дозволяє писати один код і випускати його на Android, iOS, веб і десктоп. На відміну від старих кросплатформних рішень, він не обгортає нативні компоненти й не показує вебсторінку — він малює інтерфейс сам, власним рушієм. Тому вигляд однаковий скрізь, а швидкість близька до нативної.
Як це працює
Твій код на Dart
↓
Flutter framework (віджети)
↓
Skia / Impeller — графічний рушій
↓
Полотно на екрані пристрою
Наслідки цієї архітектури:
- Однаковий вигляд на всіх платформах — бо все малюється однаково
- Швидкість — немає прошарку між кодом і промальовуванням
- Розмір застосунку більший — рушій їде разом із програмою (близько 5–7 МБ)
- Нативні компоненти доступні через платформні канали, коли справді потрібні
Встановлення
- Завантаж Flutter SDK з
flutter.dev - Додай
flutter/binуPATH - Перевір готовність:
flutter doctor
Ця команда перелічить, чого бракує: Android SDK, ліцензії, Xcode для iOS. Проходь по її списку, доки не лишиться помилок.
Редактор: VS Code з розширеннями Flutter і Dart, або Android Studio. Обидва дають гарячий перезапуск і інспектор віджетів.
⚠ Для складання під iOS потрібен macOS з Xcode. Android збирається на будь-якій системі.
Перший проєкт
flutter create my_app
cd my_app
flutter run
Що всередині:
my_app/
├── lib/
│ └── main.dart ← весь твій код тут
├── android/ нативна обгортка Android
├── ios/ нативна обгортка iOS
├── test/
└── pubspec.yaml залежності й ресурси
Dart за десять хвилин
Мова близька до Java, C# і TypeScript — якщо знаєш будь-яку з них, читатимеш без словника.
void main() {
// Змінні
var name = 'Оля'; // тип виводиться — String
String city = 'Львів';
final age = 25; // не можна перепризначити
const pi = 3.14; // константа на етапі компіляції
int count = 10;
double price = 249.99;
bool isActive = true;
List<String> tags = ['flutter', 'dart'];
Map<String, int> scores = {'оля': 95, 'іван': 87};
// Інтерполяція
print('$name з $city, ${age + 1} наступного року');
// Умови й цикли — як усюди
if (age >= 18) print('Дорослий');
for (final tag in tags) print(tag);
tags.forEach(print);
}
Null safety
Dart, як і сучасний C#, розрізняє те, що може бути null, і те, що не може:
String name = 'Оля'; // ніколи не null
String? nickname; // може бути null
print(nickname?.length); // безпечний доступ
print(nickname ?? 'без ніка'); // значення за замовчуванням
nickname ??= 'гість'; // присвоїти, якщо null
// ! каже компілятору «я знаю, що не null» — падає в рантаймі, якщо помилився
print(nickname!.length);
Це те саме, що ти бачив у C# — і та сама порада: ! використовуй лише тоді, коли справді знаєш більше за компілятор.
Функції
int add(int a, int b) => a + b;
// Іменовані параметри — у Flutter вони скрізь
void greet({required String name, String greeting = 'Привіт'}) {
print('$greeting, $name!');
}
greet(name: 'Оля');
greet(name: 'Іван', greeting: 'Вітаю');
Іменовані параметри — причина, чому код Flutter такий читабельний: у виклику віджета одразу видно, що є що.
Класи
class Course {
final String title;
final int price;
final String level;
const Course({
required this.title,
required this.price,
this.level = 'Початковий',
});
String get priceLabel => '${price / 100} ₴';
@override
String toString() => 'Course($title, $priceLabel)';
}
final course = Course(title: 'Flutter', price: 299900);
const конструктор — не дрібниця: він дозволяє Flutter перевикористовувати готовий об'єкт замість створення нового при кожній перемальовці. Це помітно впливає на продуктивність.
Асинхронність
Той самий async/await, що й у C# та JavaScript:
Future<String> loadData() async {
await Future.delayed(Duration(seconds: 1));
return 'дані';
}
void main() async {
final data = await loadData();
print(data);
}
Перший екран
Заміни весь lib/main.dart на це:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Мій застосунок',
theme: ThemeData(
colorSchemeSeed: Colors.indigo,
useMaterial3: true,
),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Привіт, Flutter')),
body: const Center(
child: Text('Перший екран', style: TextStyle(fontSize: 24)),
),
);
}
}
flutter run — і застосунок на пристрої.
Гарячий перезапуск
Головна причина, чому на Flutter приємно розробляти:
r— hot reload: код оновлюється, стан лишається. Ти на п'ятому екрані з заповненою формою — після правки стилю лишаєшся там жеR— hot restart: застосунок перезапускається з нуляq— вихід
У редакторі те саме робиться збереженням файлу.
Практика
- Постав Flutter, доможися чистого
flutter doctor. - Створи проєкт і запусти на емуляторі або пристрої.
- Заміни
main.dartприкладом вище, зміни колір теми й текст — перевір hot reload. - Напиши клас
Courseізconstконструктором і виведи список у консоль. - Зроби асинхронну функцію із затримкою і виклич її через
await.
Підсумок
- Flutter малює інтерфейс сам — звідси однаковий вигляд і швидкість
flutter doctor— перше, що треба привести до порядку- Dart близький до Java/C#/TS; null safety як у сучасному C#
- Іменовані параметри роблять код віджетів читабельним
constконструктори економлять перемальовки- Hot reload зберігає стан — головна зручність розробки
Далі — віджети.