Flutter представляє фреймворк від компанії Google, який дозволяє створювати кросплатформні програми, які можуть використовувати один і той же код. Спектр платформ широкий - це веб-додатки, мобільні програми під Android та iOS, графічні програми під настільні операційні системи Windows, MacOS, Linux, а також веб-додатки. Особливістю роботи з Flutter є те, що програми під різні платформи можуть мати той самий код. Оскільки платформи не еквіваленти, то якісь окремі частини коду необхідно налаштовувати під певну ОС, наприклад, під iOS, але тим не менш більша частина коду може збігатися. Це дозволяє розробникам суттєво заощадити час та ресурси на створення додатків під усі підтримувані платформи. Як мова розробки використовується мова програмування Dart. При побудові програми Flutter транслює код на Dart в нативний код програми за допомогою Dart AOT (компіляція програми перед запуском), яку можна запускати на Android або iOS або іншій платформі. Однак при розробці програми для її прискорення Flutter використовує JIT (компіляція програми у його запуску). Слід зазначити, що Flutter щодо новий фреймворк. Хоча прототип фреймворку з'явився ще у 2015 році, а перша альфа-версія вийшла у травні 2017 року, але перший стабільний реліз – Flutter 1.0 побачив світ лише у грудні 2018 року. Проте регулярно з невеликою періодичністю виходять підверсії, додаючи нову функціональність і виправляючи наявні баги. На момент публікації цієї статті останньою стабільною версією є Flutter 3, яка вийшла у травні 2022 року, але постійно виходять нові підверсії, які також привносять нововведення у фреймворк (наприклад, на момент написання цієї статті останньою підверсією є 3.19 , яка вийшла у лютому 2024 р. .). Що використовується для розробки під Flutter? Насамперед треба мати базові знання мови Dart. Для цього можна прочитати посібник на цьому сайті https://metanit.com за адресою Посібник з мови Dart Для написання коду програми можна використовувати будь-який улюблений текстовий редактор і потім за допомогою утиліт командного рядка з Flutter SDK компілювати програму. Однак для таких середовищ, як Android Studio та IntelliJ IDEA, а також текстового редактора Visual Studio Code, компанія Google випустила спеціальні плагіни, які дозволяють спростити розробку. Тому найчастіше для розробки під Flutter використовуються саме Android Studio та IntelliJ IDEA. Перед безпосередньою установкою слід зазначити, що Flutter залежить від багатьох компонентів. Так, якщо ми збираємося створювати програми під Android (а це найбільш популярний сценарій застосування Flutter), то нам треба встановити Android SDK. Найлегший спосіб встановити Android SDK – одразу встановити Android Studio, разом з якою будуть встановлені всі необхідні інструменти. Процес встановлення Android Studio описаний у статті Установка Android Studio Щоб розпочати розробку програм за допомогою Flutter, необхідно встановити SDK. На сторінці https://flutter.dev/docs/get-started/install/ можна знайти посилання на завантаження SDK для різних операційних систем. Розглянемо, як встановити Flutter SDK на Windows, MacOS та Linux. Для роботи Flutter SDK у Windows у системі має бути встановлений Git for Windows, який можна знайти за адресою https://git-scm.com/download/win. Також на Windows слід інсталювати пакет Microsoft C++ Build Tools. У програмі встановлення треба вибрати пункт "Розробка класичних програм на C++" (Desktop development with C++). Докладніше про встановлення можна переглянути у статті Установка Microsoft C++ Build Tools Безпосередньо для встановлення Flutter SDK перейдемо на сторінку https://docs.flutter.dev/get-started/install/windows/desktop?tab=download. На цій сторінці знайдемо у секції Get the Flutter SDK посилання на zip-архів з Flutter SDK та завантажимо його: Далі розпакуємо архів, наприклад, на диску С. Наприклад, у моєму випадку архів розпакований у папку C:\flutter. У архіві в папці flutter\bin ми знайдемо інструменти для компіляції програми. Наприклад, у моєму випадку повний шлях до цієї папки C:\flutter\bin: Якщо ми працюємо в Windows, то для додавання змінного середовища через пошук знайдемо параметр "Зміна змінних середовища поточного користувача". Для цього введемо в полі пошуку "Зміна змінних": Виберемо пункт "Зміна змінних середовища поточного користувача". Потім нам відкриється вікно, де ми можемо побачити всі змінні середовища. (Також можна перейти через Параметри та пункт Система ->Додаткові параметри системи ->Змінні середовища) Тут нам треба змінити змінну Path, додавши шлях до папки bin у Flutter SDK. Для цього виберемо пункт Path і натиснемо на кнопку "Змінити": Далі натиснемо на кнопку "Створити" і поле введення, що з'явилося, введемо шлях до папки bin з Flutter SDK: Для встановлення та оновлення Flutter використовує git, тому необхідно встановити git. Однак якщо встановлений Xcode, то git встановлювати не треба, оскільки Xcode вже включає git. Як альтернативний спосіб можна встановити Git через пакетний менеджер Homebrew, виконавши команду: Для встановлення Flutter SDK перейдемо на сторінку https://docs.flutter.dev/get-started/install/macos/desktop?tab=download. Тут нам доступно два варіанти виконання Flutter SDK – для MacOS на архітектурі Intel x86-64 та для MacOS на ARM. Завантажимо варіант, який відповідає нашій операційній системі: Далі розпакуємо архів і помістимо розпаковану папку з Flutter SDK десь на жорсткому диску.Наприклад, помістимо Flutter SDK у кореневій папці поточного користувача (папка $HOME). Для використання Flutter SDK у терміналі, необхідно додати шлях до папки bin у SDK до системних змінних. Додавання для поточного вікна терміналу: Для цього відкриємо або створимо (за відсутності) у кореневій папці поточного користувача файл .zshenv . Додамо до цього файлу рядок Збережемо та закриємо файл Попередньою умовою використання Flutter на Linux також є наявність у системі Git. Тому перш за все встановимо сам Git: Для встановлення Flutter на Linux можна використовувати два способи. Перший і найпростіший спосіб – установка через менеджер snap за допомогою наступної команди: Другий спосіб представляє ручну установку. У цьому випадку завантажуємо сам архів із файлами Flutter SDK зі сторінки https://docs.flutter.dev/get-started/install/linux і знайдемо на сторінці посилання на Flutter SDK та завантажимо його: Так, у моєму випадку це архівний пакет "flutter_linux_3.19.0-stable.tar.xz". Далі розпакуємо цей архів десь на жорсткому диску папку. Наприклад, у моєму випадку я розпакую Flutter SDK у кореневу папку поточного користувача: Перейдемо в консолі в цю папку та розпакуємо до неї завантажений архів Після розпакування компілятор мови Dart та утиліта flutter опиняться у папці "/flutter/bin". І щоб їх використовувати, внесемо шлях до цієї папки у змінні середовища. Для цього додамо до кінця файлу $HOME/.profile або /etc/profile наступний рядок І для негайного застосування її виконаємо команду Для коректної роботи Flutter на Linux також необхідно встановити ряд пакетів: Також необхідно встановити пакет Android SDK Command Line Tools. Це можна зробити, завантаживши пакет з офіційного сайту з адреси https://developer.android.com/studio#command-line-tools-only або через Android SDK Manager, який можна відкрити в Android Studio: Щоб перевірити версію Flutter, відкриємо командний рядок і введемо команду flutter --version , яка виводить версію фреймворку: Однак коректність установки Flutter ще не означає, що все буде працювати, тому що Flutter залежить від багатьох компонентів. І щоб перевірити, що все встановлено та налаштовано правильно, треба ввести команду Під час коректного встановлення та налаштування всіх супутніх компонентів консоль відобразить ряд пунктів із зеленою галочкою для кожного пункту. Якщо будуть якісь проблеми, то у зведенні команди буде вказано, яких компонентів не вистачає або що ще треба зробити, щоб установка Flutter була коректною. Для різних систем цей набір може трохи відрізнятись. Якщо згодом необхідно буде оновити Flutter, то для цього достатньо буде виконати командному рядку команду Оскільки Flutter активно розвивається, краще оновлюватися регулярно. Flutter — фреймворк, що динамічно розвивається, для написання кросплатформових додатків. Незважаючи на свою молодість (першу стабільну версію Flutter 1.0 було представлено лише 4 грудня 2018 року, тобто трохи більше року тому на момент публікації статті), він набув чимало прихильників, і його популярність тільки зростає.Сьогодні ми хотіли б розповісти про одну з найпопулярніших серед Flutter-розробників архітектур, яка була розроблена в Google, і називається – BLoC. Давайте розберемося з основною термінологією. BLoC - це акронім від "Business Logic Component" (компонент бізнес-логіки). Як випливає з назви, це клас, що відокремлює бізнес-логіку програми від інтерфейсу користувача. Такий компонент містить код, який можна повторно використовувати будь-де: в іншому модулі, на іншій платформі, в іншому додатку. Якщо ви до цього працювали з архітектурою MVVM, можете провести аналогію і порівняти Bloc з ViewModel — вони схожі за своїм призначенням. Зверніть увагу на різницю у написанні термінів. Тут і далі використовується BLoC, коли йдеться про архітектуру, і Bloc - коли про клас у програмі. Відділення UI від бізнес-логіки для Flutter життєво потрібне. Погодьтеся, що дертися вгору-вниз по дереву віджетів (UI-компонентів) у пошуках потрібної вам логіки – не найприємніша річ. Особливо якщо верстка і так містить дуже багато коду і розкидана по різних файлах. Крім того, якщо ми слідуємо завітам Clean Architecture (а ми їм слідуємо, чи не так?), то в нашому UI взагалі не повинно бути нічого зайвого. Так само як і бізнес-логіка нічого не повинна знати про UI, який до неї звертається. Завдяки такому ретельному поділу відповідальності ми отримуємо повністю ізольований компонент, який можна легко тестувати незалежно від UI та використовувати в іншому оточенні. Цей компонент є наш Bloc. Однією з відмінних рис патерну є те, що він повністю базується на реактивності. Що це означає? Реактивне програмування – це програмування з асинхронними потоками даних.У традиційному імперативному стилі ми зазвичай пишемо код наступного змісту: ось текстове поле, призначаємо йому обробник, що реагує на введення нового символу, додаємо об'єкт, у якого викликаємо метод оновлення текстового поля в моделі. Ми чітко описуємо кожен крок. У реактивному підході все виглядає трохи інакше. Текстове поле зв'язується з конкретною змінною моделі. І як тільки користувач починає щось друкувати, ця змінна відразу набуває того значення, яке зараз міститься в текстовому полі. Для реалізації реактивних сценаріїв мову Dart за промовчанням пропонує клас StreamController. Він дозволяє нам моделювати потік даних за допомогою двох складових - sink (вхідний потік, куди користувач додає події) та stream (вихідний потік, який слухають один або кілька об'єктів та реагують на зміни). Приклад опису входу-виходу для екрана в коді Bloc-а виглядає так: Окремі гетери зручно робити з наступних причин. По-перше, так набагато простіше, ніж щоразу писати nameController.sink, по-друге, ви даєте входу/виходу осмислене ім'я, що дозволяє легше зрозуміти його призначення і тим самим покращує читабельність. Код методу build для вашого віджету може виглядати так: Тут ми створюємо спеціальний віджет StreamBuilder. Першим аргументом вказуємо потік, який постачає дані нашому віджету, другим — функцію, що «збирає» віджет на основі контексту відтворення і даних, що асинхронно приходять з потоку. Для реалізації BLoC часто використовуються готові бібліотеки, наприклад, ця. Нашій же команді вона видалася надто важкою, тому ми скористалися кастомною, спрощеною реалізацією, описаною в цій статті. Розглянемо її основні тези. Кожен Bloc підтримує загальний інтерфейс BlocBase, що містить лише один обов'язковий до реалізації метод dispose.Він потрібний, щоб не забути реалізувати звільнення ресурсів, зайнятих Bloc-ом, наприклад, закрити активні потоки. Виглядає він так: Для того щоб ви могли отримати доступ до Bloc з будь-якого вузла дерева віджетів, корінням цього дерева стає така сутність, як BlocProvider. Розглянемо її код: Ідея полягає в тому, що наш провайдер — такий самий віджет, який складається з двох доданків: Bloc, до якого будуть звертатися віджети, і дерево віджетів, яке ми бачимо на екрані. Для доступу до Bloc у методі віджету build вам потрібно написати так: Доступ до Bloc під капотом реалізований дуже просто. Ми рухаємося вгору ієрархією віджетів в рамках BuildContext, поки не зустрінемо BlocProvider. Як тільки це сталося, ми можемо повернути Bloc цього постачальника. Невелике уточнення щодо оптимізації. Пошук по ієрархії віджетів має обчислювальну складність O(n). Якщо ваш провайдер розташований відносно близько до віджету, який запросив Bloc, така операція не триватиме багато часу. Однак у випадку, коли ваш віджет має велику глибину вкладеності, а доступ до Bloc йому потрібно часто, це може позначитися на продуктивності. Тоді є сенс подумати про те, щоб кешувати посилання на Bloc, наприклад, передаючи його як аргумент конструктор віджету. Розглянемо, як робота з BLoC-архітектурою може виглядати практично. Перепишемо приклад, який за умовчанням генерується під час створення Flutter-проекта. Так як тут всього один екран, у нас буде один віджет MainScreen з MainBloc, що додається до нього. MainBloc має вхідний потік з UI подіями (у нашому випадку натискання на кнопку «+») і вихідний потік зі значенням лічильника натискань. Саме значення лічильника counter зі State має переїхати сюди, оскільки воно є частиною бізнес-логіки. В результаті отримуємо наступний код для MainBloc: Якщо створення окремого потоку для UI-подій вам здається зайвим, ви можете написати окремий метод-обробник натискання на кнопку «+» (onIncrementButton) і викликати його безпосередньо. Тепер винесемо код віджету з main.dart в MainScreen і інтегруємо в нього наш MainBloc: Зверніть увагу, що текстовий віджет зі значенням лічильника тепер знаходиться в StreamBuilder, який підписаний на потік з Bloc-а. При натисканні на кнопку Bloc прокидається відповідна подія (на ваш розсуд, через потік або обробник). Bloc обробляє подію, збільшуючи лічильник, що зберігається в ньому, натискань на 1. Після чого значення цього лічильника передається в інший потік, на який підписаний віджет на стороні UI. StreamBuilder отримує новий стан із потоку (AsyncSnapshot) і перемальовує свій вміст із новими даними. Зрештою, створимо BlocProvider для нашого екрану. Винесемо цей код у main.dart: Запускаємо додаток та перевіряємо його працездатність. Код проекту ви можете переглянути тут. Отже, алгоритм роботи при створенні нових екранів з використанням BLoC-архітектури виглядає так: Зрозуміло, ніхто не змушує вас обмежувати себе виключно StreamBuilder-ами. Більше того, у випадку, коли для малювання віджету вам потрібно просто один раз синхронно отримати дані з Bloc-а, «плодити» stream-и навіть нераціонально. А для разового підвантаження даних через мережу можна використовувати, наприклад, FutureBuilder. Тому вивчайте, експериментуйте, створюйте. У наступній статті ми розповімо, як наша команда переходила від звичного патерну VIPER до BLoC і з якими складностями ми зіткнулися. З попередніми статтями на тему Flutter можна познайомитися тут. Автор: Ярослав Магін, мобільний розробник компанії INOSTUDIO. У цій статті ми познайомимося з Flutter - популярним фреймворком для кроссплатформенної розробки. Ми крок за кроком пройдемо через встановлення інструментів у Visual Studio Code, створимо простий мобільний додаток і запустимо його як на емуляторі, так і на реальному пристрої. Flutter - популярний фреймворк для кроссплатформенної розробки. Ви можете створювати програми для комп'ютерів, мобільних пристроїв та Інтернету. Основна мова програмування для Flutter - Dart. Dart – це альтернатива JavaScript. Розробники хотіли зробити мову гнучкою, структурованою і простою для вивчення. Їм це вдалося. Тепер перейдемо до практики та почнемо з встановлення інструментів. Android Studio є офіційним IDE (інтегрованим середовищем розробки) від Google. У ній можна встановити спеціальний плагін для розробки на Flutter. Але, мабуть, не для Росії. Під час спроби встановлення плагіна ви можете зіткнутися з таким повідомленням: Джерело: автор статті Переклад: Плагін Flutter не був встановлений: на жаль, в даний час ми не можемо надати вам нашу продукцію або послуги через правила експортного контролю. Звичайно, можна вирішити цю проблему через спеціальні сервіси, але ми цього не робитимемо, а спробуємо встановити редактор Visual Studio Code і вже через його менеджер розширень поставити все необхідне. Visual Studio Code - це потужний редактор коду від Microsoft, який за допомогою різних розширень можна легко перетворити на практично повноцінну IDE. Завантажити його можна тут.Після встановлення редактора запускаємо його та заходимо до розділу розширень. У рядку пошуку вводимо слово flutter та вибираємо розширення під назвою Flutter від розробника Dart Code. Натискаємо кнопку встановлення. Разом із цим розширенням автоматично встановиться розширення Dart від того самого розробника. Додатково ще можна русифікувати редактор. Для цього нам знадобиться розширення Russian Language Pack для Visual Studio Code від Microsoft. Знаходимо його та встановлюємо. Загалом наш редактор після всіх маніпуляцій повинен виглядати приблизно так: Джерело: автор статті Тепер спробуємо створити наш перший проект на Flutter. Для створення програми потрібно перейти в меню "Вид" і вибрати там пункт "Палітра команд". У рядку пошуку пишемо flutter та вибираємо пункт Flutter: New Project. Далі вибираємо як тип проекту Application і вибираємо його місце розташування. Залишається лише ввести назву проекту (counter) та натиснути на клавішу Enter. У нас має вийти приблизно ось це: Джерело: автор статті Шаблон проекту успішно створено. Але це не все. У правому нижньому кутку має з'явитися повідомлення про те, що Flutter SDK не знайдено. Це набір інструментів розробки, який необхідний для збирання та запуску проекту. Через це повідомлення можна завантажити SDK або якщо він вже завантажений, то вказати місце його розташування. Завантажити SDK можна звідси. Для запуску програми нам знадобиться емулятор на Android. Такий емулятор входить до складу Android SDK. Можна встановити Android Studio і разом із нею встановляться всі необхідні компоненти. Завантажити його можна тут. Для перевірки правильності встановлення всіх компонентів скористаємося інструментом Flutter Doctor. Знайдемо його на панелі команд і запустимо. Висновок його буде приблизно таким: Джерело: автор статті Якщо лікар показує якісь проблеми, то, швидше за все, не вистачає якихось компонентів або їх не вдалося знайти.У такому випадку потрібно уважно прочитати висновок лікаря та доустановити необхідні компоненти або вказати їх місцезнаходження у файловій системі. Щоб запустити програму в емуляторі, спочатку потрібно запустити сам емулятор. Для цього нам знову знадобиться палітра команд. Знайдемо в ній команду Flutter: Launch Emulator та запустимо її. Далі нам буде надано список доступних емуляторів. Якщо список порожній, доведеться створити емулятор за допомогою Android Studio. Запускаємо студію: Джерело: автор статті Натискаємо на More Actions та вибираємо Virtual Device Manager. Відкриється таке вікно: Джерело: автор статті Щоб створити новий емулятор просто натискаємо на значок плюса і вибираємо будь-який телефон або планшет, що сподобався. У нас у списку один уже є. Отже, якщо у списку панелі команд відображається хоча б один емулятор, то вибираємо його і чекаємо на його запуск. Ось емулятор у запущеному вигляді: Джерело: автор статті Щоб запустити проект натиснемо кнопку запуску, розташовану у правій верхній частині редактора, прямо над оглядовою картою. Після успішного складання програма запуститься в емуляторі: Джерело: автор статті Натисніть на кнопку зі знаком плюс кілька разів, щоб перевірити роботу програми: Джерело: автор статті Все працює! Тепер давайте трохи доопрацюємо програму. У шаблоні міститься якийсь урізаний проект. І справді: при натисканні на плюс число постійно збільшуватиметься. Давайте додамо ще одну кнопку, яка зменшуватиме число. Але спочатку вивчимо вихідник докладніше: Що ми тут бачимо? На самому початку вихідного коду імпортується пакет material.dart. З назви має бути зрозуміло, що він потрібний для створення дизайну програми у стилі Material Design. Далі йде точка входу в додаток – метод main. У його тілі міститься виклик єдиного методу runApp. На вхід цього методу подається клас MyApp. У цьому класі відбувається встановлення заголовків, тем та домашньої сторінки. Далі слідує, власне, сам клас домашньої сторінки MyHomePage, а за ним клас _MyHomePageState, в якому містяться опис інтерфейсу та логіка програми. Кнопка floatingActionButton (плаваюча кнопка) описується в самому кінці класу _MyHomePageState. При натисканні кнопки спрацьовує метод _incrementCounter, який збільшує число в компоненті Text на одиницю.Нам потрібно додати ще одну кнопку, навісивши на неї метод _decrementCounter, який зменшуватиме число на одиницю. Кнопки можна розмістити у контейнері Row. Він розташує їх горизонтально. Таким чином, код для кнопок буде виглядати так: Контейнер Row із кнопками ми розташували відразу після компонента Text. І тепер інтерфейс програми повинен виглядати компактніше, так як всі компоненти зібралися в центральній області екрана. Тепер спробуємо запустити нашу програму в емуляторі. Виглядатиме воно наступним чином: Джерело: автор статті Джерело: автор статті Джерело: автор статті Ось тепер це схоже на Counter. Далі поговоримо про те, як запустити наш додаток на фізичному девайсі. Для запуску нашої програми на фізичному смартфоні спочатку необхідно активувати режим розробника. Ми будемо використовувати старий Samsung Galaxy A6.У розділі відомостей про ПЗ (у налаштуваннях) знаходимо пункт «Номер складання» та топаємо по ньому кілька разів. Після появи повідомлення про те, що режим розробника активовано, повертаємося до списку налаштувань і бачимо, що там з'явився новий пункт під назвою «Параметри розробника»: Джерело: автор статті Заходимо до нього та шукаємо пункт «Налагодження USB». Активуємо цей пункт: Джерело: автор статті Далі підключаємо телефон до комп'ютера. Дозволяємо передачу даних і налагодження по USB в діалогових вікнах, що з'явилися. Зрештою, запускаємо Visual Studio Code з нашим проектом. У бічній панелі заходимо у вкладку Flutter і бачимо там наш девайс (SM A600FN): Джерело: автор статті Натискаємо на кнопку запуску і через деякий час бачимо наш додаток запущений на телефоні: Джерело: автор статті Джерело: автор статті Джерело: автор статті А зараз пропонуємо виконати невелике завдання. Додайте в інтерфейс програми ще одну кнопку для скидання значень лічильника. Розташуйте її між двома наявними. Також поміняйте напис у заголовку сторінки на Counter. Fullstack-розробники можуть самостійно створити IT-проект від архітектури до інтерфейсу. Їхні навички затребувані у роботодавців, особливо у стартапах. Навчіться програмувати на Python і JavaScript та створюйте сервіси з нуля.Введення у Flutter
Установка Flutter SDK
Встановлення Flutter на Windows
Встановлення Flutter на MacOS
export PATH=$HOME/flutter/bin:$PATH
Встановлення Flutter на Linux
sudo apt install git
sudo snap install flutter --classic
cd ~/ tar xf ~/Downloads/flutter_linux_3.19.0-stable.tar.xz
export PATH="$PATH:`pwd`/flutter/bin"
sudo apt install clang sudo apt install cmake sudo apt install ninja-build sudo apt install libgtk-3-dev
Перевірка установки
C:\Users\eugen>flutter --version Flutter 3.19.0 • channel stable • https://github.com/flutter/flutter.git Framework • revision bae5e49bc2 (5 днів тому) • 2024-02-13 17:46 :18 -0800 Engine • revision 04817c99c9 Tools • Dart 3.3.0 • DevTools 2.31.1 C:\Users\eugen>
Оновлення Flutter
Flutter. Розбираємось з архітектурою Flutter-додатку.
Відокремлюємо бізнес-логіку від інтерфейсу користувача за допомогою патерна BLoC.
Що таке BLoC
Знайомство з BlocProvider
Приклад реалізації
Чек-лист по роботі з BLoC-архітектурою
Що таке Flutter або як створити простий мобільний додаток
Що таке Flutter та Dart
Як встановити плагін Flutter
Як написати просте додаток-лічильник на Flutter
Доопрацювання програми
import 'package:flutter/material.dart'; void main() < runApp(const MyApp()); >class MyApp extends StatelessWidget < const MyApp(); // Цей widget is the root of your application.@override Widget build(BuildContext context) < return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage( Flutter Demo Home Page'), ); >> class MyHomePage extends StatefulWidget < const MyHomePage(); final String title; @override State createState() => _MyHomePageState(); > class _MyHomePageState extends State < int _counter = 0; void _incrementCounter() < setState(() < _counter++; >); > @override Widget build(BuildContext context) < return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: Center( child: Column( mainAxisAlig) : MainAxisAlignment.center, children: [ const Text( 'You hash pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.headlineMedium, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), // Це trailing comma makes auto-formatting nicer for build methods ); > >
Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ FloatingActionButton( onPressed: _decrementCounter, інструмент: 'Decrement', child: const Icon(Icons.remove), ), FloatingActionsButton( 'Increment', child: const Icon(Icons.add), ), ], )
void _decrementCounter() < setState(() < _counter--; >); >
import 'package:flutter/material.dart'; void main() < runApp(const MyApp()); >class MyApp extends StatelessWidget < const MyApp(); // Цей widget is the root of your application.@override Widget build(BuildContext context) < return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage( Flutter Demo Home Page'), ); >> class MyHomePage extends StatefulWidget < const MyHomePage(); final String title; @override State createState() => _MyHomePageState(); > class _MyHomePageState extends State < int _counter = 0; void _incrementCounter() < setState(() < _counter++; >); > void _decrementCounter() < setState(() < _counter--; >); > @override Widget build(BuildContext context) < return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: Center( child: Column( mainAxisAlig) : MainAxisAlignment.center, children: [ const Text( 'You hash pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.headlineMedium, ), Row( mainAxisAlignment: MainAxisAlignment.spaceAround children: [ FloatingActionButton( onPressed: _decrementCounter, tooltip: 'Decrement', child: const Icon(Icons.remove), ), FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), ) , ), ), ); > >
Як запустити програму на Flutter на смартфоні
Завдання для самостійного виконання
Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ FloatingActionButton( onPressed: _decrementCounter, інструмент: 'Decrement', child: const Icon(Icons.remove), ), FloatingActionButton 'Reset', child: const Icon(Icons.restart_alt), ), FloatingActionButton( onPressed: _incrementCounter, інструмент: 'Increment', child: const Icon(Icons.add), ), ], )
home: const MyHomePage(title: 'Counter')
import 'package:flutter/material.dart'; void main() < runApp(const MyApp()); >class MyApp extends StatelessWidget < const MyApp(); // Цей widget is the root of your application.@override Widget build(BuildContext context) < return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage( Counter'), ); >> class MyHomePage extends StatefulWidget < const MyHomePage(); final String title; @override State createState() => _MyHomePageState(); > class _MyHomePageState extends State < int _counter = 0; void _incrementCounter() < setState(() < _counter++; >); > void _resetCounter() < setState(() < _counter = 0; >); > void _decrementCounter() < setState(() < _counter--; >); > @override Widget build(BuildContext context) < return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: Center( child: Column( mainAxisAlig) : MainAxisAlignment.center, children: [ const Text( 'You hash pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.headlineMedium, ), Row( mainAxisAlignment: MainAxisAlignment.spaceAround children: [ FloatingActionButton( onPressed: _decrementCounter, tooltip: 'Decrement', child: const Icon(Icons.remove), ), FloatingActionButton( onPressed: _resetCounter, tooltip: 'Reset', child: const Icon(Icons.restart_alt), , _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), ], ) ], ), ), ); > >