неділю, 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

Немає коментарів:

Дописати коментар