неділя, 22 серпня 2021 р.

Кросплатформена розробка на Flutter. Частина II

 Основи Flutter

В першій частині я розповів постановку задачі. Тепер переходжу до опису процессу розробки.

Dart

Ядро Flutter написано на C++. А ось розробка виконується на мові програмування Dart. Вона розроблялась Google як більш сучасна альтернатива JavaScript. Використання не дуже поширенної мови замість, наприклад, Python або навіть JavaScript, розробники Flutter аргументують в тому числі і можливістю швидко вносити в мову необхідні нові можливості. Dart дуже схожа на більшість сучасних мов. Однак, не така солоденька, як Swift.

Flutter - все є віджет

Заголовок підрозділу - це основна концепція Flutter. Наприклад, є віджет для відображення тексту:

Text('Copyright(c) 2021 Vadym A. Khokhlov')

Якщо необхідно додати навколо тексту відступи, ми вставляємо його у віджет Padding:

Padding(
   padding: EdgeInsets.symmetric(vertical: 8.0),
   child: Text('Copyright(c) 2021 Vadym A. Khokhlov'),
),

Программа - це теж віджет. Ось, наприклад, як зазвичай виглядає початок:

void main() {
  runApp(NumberFactsApp());
}
class NumberFactsApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Facts about numbers',
      home: const NumberFactsScreen(),
    );
  }
}

Функція main запускає віджет NumberFactsApp як головний віджет програми. Він має обов'язково реалізувати метод build для своєї побудови. Цей метод повертає інший віджет - MaterialApp, якому в якості аргументу home треба вказати ще один віджет - в данному випадку NumberFactsScreen. Таким чином програма представляє собою дерево віджетів. Насправді дерев три:  Widgets, Elements, RenderObjects. Але програмісти в основному працюють саме з першим.

Стан віджета

Flutter надає крила два основних класа віджетів: stateless та statefull. 

Якщо вигляд віджету не від чого не залежить, то він утворюється як підклас StatelessWidget. Приклад - наведений вище NumberFactsApp.

Якщо ж віджет має змінювати вигляд у відповідь на дії користувача або залежить ще від якіхось факторів, то він утворюється як підкласс StatefulWidget. Такі віджети зберігають свій стан в об'єкті окремого класу, підкласу State. Ось приклад віджету, що дозволяє користувачеві вибирати мову, на якій будуть відображатись факти:

class _LangSelector extends StatefulWidget {
  ...
  @override
  __LangSelectorState createState() => __LangSelectorState();
}

class __LangSelectorState extends State<_LangSelector> {
  final LangsService langsService = serviceLocator<LangsService>();

  @override
  Widget build(BuildContext context) {
    return TextButton(
        onPressed: () {
          setState(() {
            _curLangIndex = 1 - _curLangIndex;
            ...
          });
        },
        child: Text(langsService.flag(_curLangIndex)));
  }

  int _curLangIndex = 0;
}

Для того, щоб повідомити Flutter, що стан віджету змінився і його необхідно перебудувати використвується метод setState. Одна з особливостей Dart полягає в тому, що в ній немає якогось слова для позначення  приватних методів або змінних. Замість цього достатньо ім'я розпочати з _. (Про langsService я розповім пізніше).

Звісно, що змішувати в одному класі і логіку роботи віджета, і опис його вигляду - погана ідея. Тому у Flutter використовуються механізми керування станом (state management), що дозволяют відокремити логіку від інтерфейсу. У наступних статтях я розповім про один з них. Хоча свою першу гру я написав без використання таких механізмів. Але я стидаюсь показати її код :)

Документація по widget'ам Flutter тут.

Зміст

2. Кросплатформена розробка на Flutter. Частина II

середа, 18 серпня 2021 р.

Кросплатформена розробка на Flutter. Частина I

 Коротко про Flutter

В компанії Postindustria я працюю iOS-розробником, а у вільний час в якості хобі займаюсь розробкой мобільних додатків для Android. Останні десь два роки я цікавлюсь Flutter - це фреймворк від Google для розробки додатків. Наразі це єдиний фреймворк (як запевняє Google), що дозволяє з одного коду отримувати додатки для шости платформ:
  • iOS
  • Android
  • web
  • Linux
  • macOs
  • Windows
Крім підтримки майже всіх популярних платформ він має наступні переваги:
  • на iOS та Android програма компілюється в нативний код, тобто немає ніяких js-bridges, як, наприклад, для React Native;
  • підтримує just-in-time та ahead-of-time режими компіляції. Перший дозволяє бистро компілювати код при розробці, а другий - отримувати оптимальну швидкодію для release-варіантів.
  • як на мене, підхід до побудови інтерфейсів на Flutter більш приємний і зручніший, ніж нативні варіанти для мобільних платформ; 
  • режим hot reload дозволяє тестувати зміни інтерфейсу без перекомпіляції коду;
  • версії додатка для різних платформ можуть мати однаковий вигляд оскільки всі віджети Flutter малює сам, а не делегує це базовій платформі
До недоліків можно віднести:
  • це продовження останньої переваги. Flutter має багатий набір віджетів, що імітують виджети iOS або Android. Але коли на якійсь платформі з'являється новий, доводиться чекати, коли буде реалізований аналог на Flutter;
  • дуже слабка підтримка SEO для web.
Таким чином, Flutter дуже підходить для розробки додактів, що мають виконуватись більш, ніж на одній платформі. При чому процес проходить дуже швидко и часто навіть приємніше ніж із застосуванням нативних засобів платформи.

 Мета

За останній час я встиг розробити на Flutter кілька простих ігор. В деякі можна грати навіть з іншими гравцями по Internet. Однак, переважна більшість додатків відрізняється від ігор. Як правило, вони звертаються до якогось серверу, отримують данні, показують їх користувачеві, дозволяють їх редагувати. Я вирішив написати один такий невеличкий додаток і описати процесс в кількох статтях. Це не буде детальний опис програмування на Flutter. Я планую показати основні можливості. Також я хочу трохи самому розібратися с Clean Architecture від дядечка Боба і з тестуванням Flutter-додатків.

Додаток

Я розробив невеличкий додаток, що використовує сервис NUMBERSAPI в якості серверної частини. Цей сервіс має невеличкий API для отримання цікавих фактів про числа та дати.
Моя програма буде показувати факти, а також мати можливість перекладати факти на декілька мов.
Декілька скриншотів.
Android:

iOS:

web:


Тут можна побачити, як працює web-версія на сторінці в iframe.
Є невеличка проблема в тому, що на Github використовується https, а на сайте Numbersapi - http. З цієї причини виникає помилка mixed-content при виконанні запитів на Numbersapi. Але загальне уявлення про flutter-додатки в web отримати можна: кнопки і переклад працюють.

На Android встановити додаток можна з Google Play.

Вихідні тексти додатка можна отримати тут.
Для самостійної зборки треба встановити Flutter, як описано тут a також засоби розробки для Android або iOS з емудяторами. Після цього можна запускати:

     flutter run -d Android

  flutter run -d iPhone

  flutter run -d chrome

Для Andoid/iOS після -d треба вказати справжнє ім'я емулятора.

В наступних статтях я буду пояснювати як саме розроблявся цей додаток.

Зміст

1. Кросплатформена розробка на Flutter. Частина I