AAcademyCloud
Flutter: мобільна розробка
Безкоштовний урок-прев'ю

Dart і перший застосунок

Flutter дозволяє писати один код і випускати його на Android, iOS, веб і десктоп. На відміну від старих кросплатформних рішень, він не обгортає нативні компоненти й не показує вебсторінку — він малює інтерфейс сам, власним рушієм. Тому вигляд однаковий скрізь, а швидкість близька до нативної.

Як це працює

Твій код на Dart
      ↓
Flutter framework (віджети)
      ↓
Skia / Impeller — графічний рушій
      ↓
Полотно на екрані пристрою

Наслідки цієї архітектури:

  • Однаковий вигляд на всіх платформах — бо все малюється однаково
  • Швидкість — немає прошарку між кодом і промальовуванням
  • Розмір застосунку більший — рушій їде разом із програмою (близько 5–7 МБ)
  • Нативні компоненти доступні через платформні канали, коли справді потрібні

Встановлення

  1. Завантаж Flutter SDK з flutter.dev
  2. Додай flutter/bin у PATH
  3. Перевір готовність:
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 — вихід

У редакторі те саме робиться збереженням файлу.

Практика

  1. Постав Flutter, доможися чистого flutter doctor.
  2. Створи проєкт і запусти на емуляторі або пристрої.
  3. Заміни main.dart прикладом вище, зміни колір теми й текст — перевір hot reload.
  4. Напиши клас Course із const конструктором і виведи список у консоль.
  5. Зроби асинхронну функцію із затримкою і виклич її через await.

Підсумок

  • Flutter малює інтерфейс сам — звідси однаковий вигляд і швидкість
  • flutter doctor — перше, що треба привести до порядку
  • Dart близький до Java/C#/TS; null safety як у сучасному C#
  • Іменовані параметри роблять код віджетів читабельним
  • const конструктори економлять перемальовки
  • Hot reload зберігає стан — головна зручність розробки

Далі — віджети.

Сподобався урок?

Придбайте повний курс, щоб отримати доступ до всіх уроків.

Перейти до курсу