Flutter для розробників Jetpack Compose: повний практичний посібник

Останнє оновлення: 12/05/2025
Автор: C SourceTrail
  • Flutter та Jetpack Compose мають декларативну, реактивну модель інтерфейсу користувача, але відрізняються мовою програмування, екосистемою та охопленням платформи.
  • Compose чітко відповідає концепціям Flutter: компоновані об'єкти – віджетам, ліниві списки – ListView/GridView, Canvas – CustomPainter, а теми – ThemeData.
  • Навички, характерні для Android (життєвий цикл, навігація, ресурси, паралельність), передаються безпосередньо у Flutter через віджети, Navigator, ресурси та async/await.
  • Для проектів лише для Android Compose чудово підходить, тоді як Flutter чудово підходить, коли вам потрібна єдина база коду для Android, iOS, веб-сайтів та настільних комп'ютерів.

Flutter для розробників Jetpack Compose

Якщо ви вже почуваєтеся як вдома, пишучи інтерфейси за допомогою Jetpack Compose, і вам цікаво, наскільки важко перейти на Flutter, ви у чудовому становищі. Обидва інструментарії є декларативними, реактивними та створеними Google, тому значна частина вашої ментальної моделі переноситься майже один до одного. Основні відмінності полягають у мові (Kotlin проти Dart), структурі проекту та тому, як кожен фреймворк взаємодіє з базовими шарами Android (а у випадку Flutter, iOS, веб- та десктопними).

Цей посібник написаний спеціально для розробників Jetpack Compose, які хочуть глибоко зрозуміти Flutter без маркетингових зайвих слів. Ви побачите, як основні концепції взаємопов'язані між двома світами: компоновані елементи проти віджетів, модифікатори проти параметрів конструктора, ліниві макети проти ListView/GridView, Canvas проти CustomPainter, Navigation Compose проти Navigator, remember проти StatefulWidget та багато іншого. Ми також пов'яжемо ваш ширший досвід роботи з Android (Views, життєвий цикл, ресурси, наміри, фонова робота) з їхніми еквівалентами у Flutter, щоб крива навчання більше нагадувала крок убік, ніж підйом.

Пов'язана стаття:
Вирішено: alertDialog із тремтінням валідатора текстового поля

Від Jetpack Compose до Flutter: де ваші навички передаються

Flutter — це фреймворк інтерфейсу Google для створення кросплатформних додатків за допомогою мови Dart, тоді як Jetpack Compose — це сучасний набір інструментів інтерфейсу Google для нативного Android, що використовує Kotlin. В основі своїй вони орієнтовані на різні середовища виконання, але архітектурно мають одну й ту саму головну ідею: описати інтерфейс користувача як функцію стану, дозволити фреймворку визначити, коли і як перемальовувати.

У Jetpack Compose ви думаєте з точки зору компонованих функцій, модифікаторів та рекомпозиції; у Flutter ви думаєте з точки зору віджетів, параметрів конструктора та перебудов. Незважаючи на різні назви, поведінка разюче схожа: ви будуєте дерево елементів інтерфейсу, кожен вузол є незмінним, і коли стан змінюється, фреймворк знову проходить це дерево, щоб створити оновлений інтерфейс.

Одна ключова відмінність полягає в тому, що Flutter за своєю суттю є кросплатформним. Та сама кодова база Dart може бути орієнтована на Android, iOS, веб, Windows, macOS та Linux. Compose виходить за межі Android (наприклад, з Compose Multiplatform), але історія Flutter для різних пристроїв зараз набагато зріліша та цілісніша, саме тому багато команд, що спеціалізуються на Android, звертають увагу на нього, коли хочуть розширити можливості для iOS або настільних комп'ютерів.

Ваше розуміння самої платформи Android все ще надзвичайно цінне у проектах Flutter. Хоча рівень інтерфейсу користувача — це чисто Dart та віджети, Flutter покладається на Android (та iOS) для дозволів, конфігурації системи, API платформи, сповіщень, фонової роботи та багатьох інших можливостей, доступ до яких здійснюється через плагіни та канали платформи. Це означає, що вся інтуїція, яку ви накопичили щодо поведінки Android, не пропадає даремно — він просто переміщується на один рівень нижче.

Декларативна модель інтерфейсу користувача: компоновані елементи проти віджетів

Як Jetpack Compose, так і Flutter реалізують декларативну модель інтерфейсу користувача: ви описуєте, «як» має виглядати інтерфейс користувача для заданого стану, а не «як» крок за кроком змінювати представлення. Замість виклику сеттерів у представленнях, ви перебудовуєте дерево, коли стан змінюється, і дозволяєте фреймворку ефективно змінювати та перемальовуватися.

У Jetpack Compose елементи інтерфейсу користувача – це компоновані функції, анотовані за допомогою @Composable, часто налаштований з Modifier. Кнопка може бути Button(onClick = ..., modifier = Modifier.padding(16.dp))Ланцюжок модифікаторів декорує або розміщує компонований об'єкт, не змінюючи його базового типу, а Compose використовує рекомпозицію для оновлення лише тих частин дерева, вхідні дані яких змінилися.

У Flutter елементи інтерфейсу користувача – це віджети – звичайні об'єкти Dart, які описують конфігурацію. Вони також незмінні та розташовані у вигляді дерева, але замість передачі модифікатора ви зазвичай передаєте аргументи макета або стилю безпосередньо через параметри конструктора, або ви обгортаєте віджет в інші віджети макета. Наприклад, ви можете написати Padding(padding: EdgeInsets.all(16), child: ElevatedButton(...)) щоб досягти подібного результату.

Життєвий цикл як компонованих об'єктів, так і віджетів навмисно короткочасний та незмінний. Вони існують лише доти, доки нові дані не вимагають їх заміни; жоден з них не намагається керувати власним життям або безпосередньо мутувати. Це концептуальний зсув зі старого світу Android View, де представлення (views) є довгоживучими об'єктами, які повторно використовуються та мутують з часом, і саме тому ваш спосіб мислення Compose виглядає таким природним у Flutter.

Під капотом, макет в обох фреймворках дотримується одного й того ж шаблону, керованого батьками та заснованого на обмеженнях. Батьківський об'єкт вимірює себе, передає обмеження, дочірні об'єкти вибирають розмір, враховуючи ці обмеження, а батьківський об'єкт позиціонує своїх дочірніх об'єктів. У Flutter ви побачите це безпосередньо як BoxConstraints; у Compose це обробляється в реалізаціях MeasurePolicy. В обох випадках батьки можуть обмежувати дітей — віджети не можуть просто вибрати будь-який розмір чи положення, яке їм подобається.

Структурування застосунку: точка входу, скамейкування та макети

На Android із Compose ваша точка входу зазвичай є Activity (часто ComponentActivity) куди ви телефонуєте setContent для розміщення ваших компонованих елементів. Звідти ви будуєте компонуване дерево, зазвичай починаючи з MaterialTheme та поверхню або каркас, що визначає ваш макет високого рівня.

У Flutter точкою входу є Dart. main функція, яка викликає runApp з кореневим віджетом вашої програми. Цей корінь зазвичай є MaterialApp or WidgetsApp віджет, який налаштовує маршрутизацію, теми, локалізацію та базовий навігатор. Перший «екран», який ви показуєте, часто використовує Scaffold віджет, який відіграє роль, дуже схожу на Scaffold У Material 3 Compose: панель програм, текст, плаваюча кнопка дій, висувні ящики тощо.

Для простого тексту та статичного контенту Compose може за замовчуванням обтікати контент — підбираючи розмір відповідно до внутрішнього контенту — тоді як багато віджетів Flutter за замовчуванням займають більше доступного простору, якщо це не обмежено. Наприклад, якщо ви розмістите Text компонується всередині колонки, він не заповнить її автоматично шириною. У Flutter, Text всередині а Column може поводитися по-різному залежно від обмежень батьківського об'єкта. Щоб центрувати контент у Flutter, ви часто будете обгортати його в Center віджет або використовуйте віджети макета, такі як Align, Row, Column та Expanded у поєднанні з властивостями вирівнювання.

Лінійні макети майже ідеально відображаються: Compose має Row та Column, і Flutter також. У Flutter ви передаєте дітей як List<Widget> і керувати інтервалами та вирівнюванням за допомогою таких властивостей, як MainAxisAlignment та CrossAxisAlignmentУ Compose ви покладаєтеся на horizontalArrangement, verticalArrangement, horizontalAlignment та verticalAlignmentКорисний спосіб подумати про це: властивості, що закінчуються на «Arrangement» (Розташування), відповідають головній осі Flutter, а ті, що закінчуються на «Alignment» (Вирівнювання), відповідають поперечній осі.

Коли вам потрібні відносні або перекриваючі макети, підходи також концептуально узгоджені. У Android XML ви можете звернутися до RelativeLayout або вкладену суміш LinearLayout та FrameLayoutУ Compose ви пишете Row, Column та Box (або напишіть власний макет). У Flutter аналогом є Row, Column та Stack у поєднанні з позиціонованими дочірніми елементами та опціями вирівнювання. Ваша ментальна модель розташування елементів відносно один одного переміщується майже без змін.

Кнопки, введення та взаємодія

У Jetpack Compose створення кнопки зазвичай означає використання Button або один з його варіантів Material, який у Material 3 відповідає певній реалізації, такій як FilledTonalButton. Ви надаєте onClick лямбда та необов'язкове стилізування, часто за допомогою таких параметрів, як colors або модифікатори для відступів, ширини та вирівнювання.

У Flutter еквівалентом є використання віджетів, таких як FilledButton, ElevatedButton, TextButton or OutlinedButton. Кожен бере onPressed зворотний виклик та child віджет — найчастіше TextВи можете налаштувати їх, передавши style через ButtonStyle або використання глобального перевизначення теми, яке дозволяє централізовано налаштовувати колір, форму, висоту та розмір для всієї родини кнопок.

Для обробки жестів Compose використовує такі модифікатори, як Modifier.clickable у багатьох випадках, але за потреби ви також можете скористатися спеціалізованими детекторами жестів. Тривалі натискання, перетягування та користувацькі жести зазвичай створюються за допомогою спеціальних API-інтерфейсів модифікаторів та джерел взаємодії.

Flutter розкриває явний GestureDetector віджет, який обгортає все, що не має вбудованої підтримки жестів. Він пропонує широкий спектр зворотних дзвінків: onTap, onDoubleTap, onLongPress, onVerticalDragStart, onVerticalDragUpdate, onHorizontalDragEnd та багато інших. Віджети, як-от ElevatedButton вже викривають onPressed властивість, але для повністю налаштовуваних елементів інтерфейсу можна використовувати GestureDetector або віджети вищого рівня, такі як InkWell для зворотного зв'язку по пульсаціях матеріалу.

Введення тексту у Flutter керується за допомогою TextField or TextFormField, стиль якого аналогічний Compose TextField та OutlinedTextField композитні матеріали. Ви налаштовуєте підказки, мітки, помилки та межі за допомогою InputDecoration подібно до того, як ви використовуєте TextFieldDefaults або параметри в текстових полях Compose. Як і в Compose, ви зазвичай відображаєте повідомлення про помилки реактивно, змінюючи стан і перебудовуючи декор, а не вручну маніпулюючи виглядами.

Списки, сітки та прокручуваний вміст

Jetpack Compose пропонує дві основні стратегії для списків: прості Column/Row з ітерацією для невеликих колекцій та LazyColumn/LazyRow/LazyVerticalGrid/LazyHorizontalGrid для великих або динамічних списків. Лениві контейнери складають лише те, що видно, що забезпечує високу продуктивність під час роботи з тисячами елементів.

Flutter дотримується того ж підходу «маленький проти великого», але з іншими віджетами. Для крихітного списку, який поміщається на екрані, можна просто використати Column та зіставте свої дані з childrenЗа всім, що прокручується, ви тягнетеся ListView or GridView, з конструкторами-будівельниками, які ліниво створюють дочірні об'єкти лише за потреби.

Поширений шаблон у Flutter такий: ListView.builder, що відображає DSL елементів лінивого списку Compose. Ви надаєте itemCount і itemBuilder зворотний виклик; Flutter викликає цей конструктор з індексом від 0 до itemCount - 1 щоразу, коли з'являється новий елемент. У конструкторі ви можете повернути майже будь-який віджет — від простого ListTile з текстом та піктограмами до складних, користувацьких рядків списку.

Для сіток, Compose LazyVerticalGrid та LazyHorizontalGrid карта до Flutter GridView віджет Замість того, щоб передавати кількість стовпців безпосередньо до сітки, Flutter часто використовує делегат, такий як SliverGridDelegateWithFixedCrossAxisCount or SliverGridDelegateWithMaxCrossAxisExtent щоб контролювати розташування комірок. Ці делегати інкапсулюють правила, такі як «кількість стовпців» або «максимальна ширина комірок», подібні за духом до параметрів розміру сітки, які використовуються в Compose.

Поведінка прокручування також аналогічна в обох наборах інструментів. Ледачі списки Compose мають вбудовану функцію прокручування; ви не обгортаєте їх у додаткові контейнери прокручування. У Flutter багато віджетів списків і сіток самі по собі є прокручуваними, але для одиничного, неповторюваного контенту, який має прокручуватися, ви можете використовувати SingleChildScrollViewСтворення власних сторінок з можливістю прокручування стає питанням вкладення або складання фрагментів для більш складних випадків використання.

Адаптивні та чуйні шаблони інтерфейсу користувача

Compose пропонує кілька стратегій для адаптивного дизайну: користувацькі макети, BoxWithConstraints, WindowSizeClass та адаптивну бібліотеку Material 3. Вони дозволяють змінювати композицію залежно від доступного простору, пози та категорії пристрою, а також комбінувати їх залежно від складності проєкту.

Flutter не намагається безпосередньо відображати ці API, але основна ідея та сама: перевірити обмеження та характеристики екрана, а потім розгалужувати макет. Два основні інструменти - це LayoutBuilder та MediaQuery. LayoutBuilder проходить BoxConstraints вниз, щоб ви могли міняти місцями або переставляти віджети, що перевищують певну ширину або висоту. MediaQuery надає доступ до розміру екрана, орієнтації, відступів та щільності пікселів для точок зупинки високого рівня.

Замість того, щоб прагнути до однозначного зіставлення між адаптивними рішеннями Compose та Flutter, ефективніше думати з точки зору ваших вимог до дизайну. Щойно ви зрозумієте, як ваш інтерфейс користувача має адаптуватися до телефонів, планшетів та настільних комп’ютерів, ви зможете виразити цю логіку за допомогою Compose. WindowSizeClass та адаптивні макети або розгалуження Flutter, кероване обмеженнями та медіа-орієнтоване. Те саме дизайн-мислення — різні API.

Управління станом: пам'ятайте проти StatefulWidget та не тільки

Jetpack Compose зберігає тимчасовий стан інтерфейсу користувача за допомогою remember та власники державних коштів, як-от mutableStateOf, часто поєднуються з ViewModel та архітектурні компоненти для довшого терміну служби. Коли стан змінюється, відбувається рекомпозиція, і відповідні компоновані елементи отримують нові значення.

Історія низькорівневого стану Flutter обертається навколо StatefulWidget і пов'язані з ним State об'єкт Ви визначаєте віджет, який хоче зберігати стан, розширюючи StatefulWidget, а потім реалізуйте окремий State<MyWidget> клас для зберігання змінних полів. Щоразу, коли ви оновлюєте ці поля, ви викликаєте setState(), що позначає цю частину дерева віджетів як брудну та запускає перебудову. На цьому рівні це дуже схоже на збереження стану Compose за допомогою remember та анулювання складових елементів при зміні значень.

Для складніших додатків Flutter значною мірою спирається на шаблони спільноти та власних розробників: Provider, Riverpod, Bloc, магазини в стилі Redux та багато іншого. Вони виступають аналогами ваших стеків архітектури Android: ViewModel + LiveData/Flow + репозиторії в проектах Compose. Вони централізують бізнес-логіку та надають доступ до реактивних потоків даних, які керують перебудовою віджетів. З досвіду роботи з Compose ви знайдете багато з цих шаблонів знайомими, навіть якщо API відрізняються.

Один момент, який часто дивує розробників Android, полягає в тому, що як віджети з відображенням стану, так і віджети зі станом у Flutter часто перебудовуються — можливо, кожен кадр під час анімації. Різниця полягає не в частоті перебудови, а в тому, де зберігається змінний стан: StatefulWidget дає тобі супутника State об'єкт, який витримує перебудови, подібно до того, як remember дозволяє значенням пережити рекомпозицію в Compose.

Малювання, анімація та візуальна обробка

Якщо ви коли-небудь працювали безпосередньо з Android Canvas та Drawable, Compose's Canvas composable, мабуть, здавався простим. Він надає декларативний спосіб малювання фігур, зображень та тексту в Kotlin, приховуючи значну частину імперативної церемонії традиційних користувацьких представлень.

Flutter відкриває подібну поверхню для малювання через Canvas API, доступ до якого здійснюється через CustomPaint та CustomPainter. Ви впроваджуєте CustomPainter клас, де ви перевизначаєте paint метод малювання на полотні за допомогою Paint об'єкти, контури, трансформації тощо. Потім ви прикріплюєте цей інструмент для малювання до CustomPaint віджет. Під капотом і Compose, і Flutter спираються на рушій Skia, тому примітиви — лінії, шляхи, шейдери — виглядають дуже знайомими з 2D-рендерингу Android.

Для анімації Flutter спирається на чітку систему анімації, побудовану навколо AnimationController, Animation<T> і підлітки, а також багатий набір анімованих віджетів. Ви створюєте екземпляр контролера (зазвичай за допомогою SingleTickerProviderStateMixin для vsync), визначте CurvedAnimations або Tweens, які відображають прогрес 0-1 у значення домену, а потім зв'яжіть їх з віджетами, такими як FadeTransition, ScaleTransition, AnimatedBuilder або неявні віджети, такі як AnimatedContainerСистема анімації також виявляє AnimationStatus зворотні виклики для реагування на початок, завершення або розворот.

API анімації Jetpack Compose є декларативними зверху вниз, з такими функціями, як animate*AsState, переходи та анімовану видимість. Замість ручного керування контролерами, як у більшості поширених випадків, ви описуєте цільові стани, а фреймворк керує інтерполяцією з часом. Коли вам потрібен більш індивідуальний контроль, ви все ще маєте доступ до низькорівневих примітивів, але звичайний шлях є більш стислим, ніж класичний Android XML або імперативний код анімації.

Концептуально, ви використовуєте обидва набори інструментів однаково: зберігаєте віджети/компоновані елементи легкими та чистими, пропускаєте через них змінні в часі значення та дозволяєте фреймворку обробляти інтерполяцію та недійсність. Як розробник Compose, додаткова явність Flutter AnimationController Спочатку може здатися трохи старомодним, але це дає вам дуже детальний контроль над таймінгом, кривими та оркестровкою.

Стиль, теми, шрифти та ресурси

Сучасні додатки живуть або вмирають завдяки поліруванню, тому і Flutter, і Compose приділяють багато уваги тематиці та стилю. Використання у Compose MaterialTheme з колірними схемами, типографікою та визначеннями фігур, а також ви можете вкладати теми, щоб перевизначати значення для піддерев, включаючи примусове встановлення світлих або темних поверхонь для певних регіонів.

У Flutter еквівалентом є ThemeData перейшов до MaterialApp or Theme віджети. Ви визначаєте основні кольори, яскравість, типографіку та теми, що стосуються певних компонентів, такі як elevatedButtonTheme, textButtonTheme, appBarTheme та багато іншого. Ви можете перевизначити теми локально, обгорнувши піддерева в Theme віджети, що копіюють батьківський елемент і налаштовують певні поля. Світлий і темний режим можна перемикати на рівні програми, надаючи theme та darkTheme і контролюючий themeMode.

Стилізація тексту — це звичний шлях: у Compose ви або передаєте прості властивості безпосередньо до Text або надати TextStyle об'єкт Flutter відображає це за допомогою Text віджет, який приймає TextStyle через його style параметр. TextStyle охоплює сімейство шрифтів, розмір, товщину, інтервал між літерами, висоту рядка, декорування тощо. Ви можете визначити глобальні текстові теми в ThemeData.textTheme і посилайтеся на них скрізь, так само, як ви використовуєте типографіку з MaterialTheme у Compose.

Шрифти та зображення обробляються через ресурси, а не традиційно, як в Android. /res дерево каталогів. Flutter не вимагає певного макета папок; ви оголошуєте ресурси в pubspec.yaml а потім посилатися на них з коду. Зображення зазвичай завантажуються за допомогою Image.asset(), що відповідає правильному діапазону щільності на основі devicePixelRatioЛогічні пікселі відіграють ту саму роль, що й dp на Android, абстрагуючи фізичну щільність пікселів.

Для користувацьких шрифтів Compose дозволяє або пакувати ресурси шрифтів, або отримувати їх під час виконання через такі постачальники, як Google Fonts, а потім підключати їх до FontFamily та типографіка. Flutter використовує майже той самий шаблон: поміщає файли шрифтів у папку assets, перелічує їх у pubspec.yaml, а потім посилатися на назву сімейства шрифтів у TextStyleЯкщо вам потрібні шрифти, отримані під час виконання, існує популярний google_fonts плагін, який надає функції Dart, названі на честь шрифтів, наприклад GoogleFonts.robotoTextTheme()— щоб швидко підключити їх до вашої теми.

Обидві екосистеми ставляться до рядків та локалізації як до першочергових завдань, хоча Flutter не має прямого еквівалента XML-рядковим ресурсам Android. Натомість, найкращою практикою є зберігання перекладів у .arb файли та пов’язати їх за допомогою інструментарію локалізації Flutter. Доступ потім здійснюється через згенеровані класи Dart, приблизно аналогічно використанню R.string ідентифікатори в коді Android.

Концепції платформи Android крізь призму Flutter

Окрім інтерфейсу користувача, одне з найбільших питань, яке виникає у розробників Compose, полягає в тому, як їхні знання про Android співвідносяться з архітектурою Flutter. На щастя, багато основних ідей — дії, життєвий цикл, наміри, фонова робота, ресурси, мережа — мають чіткі аналоги, навіть якщо API поверхні виглядає інакше.

В Android, Activity та Fragment є вашими основними екранами та контейнерами; у Flutter все є віджетом, а навігація відбувається через Navigator та Route об’єкти. Маршрут приблизно відповідає дії або фрагменту, але зазвичай існує лише один хостинг Activity на Android, що вбудовує рушій Flutter. Ви розміщуєте та витягуєте маршрути в стеку Navigator або через іменовані маршрути, визначені в MaterialApp або через безпосередньо побудовані PageRoute такі випадки, як MaterialPageRoute.

Зворотні виклики життєвого циклу Android (onCreate, onStart, onResumeтощо) не мають один-до-одного перехоплення у коді Flutter, але ви можете спостерігати за життєвим циклом програми за допомогою WidgetsBindingObserver. Це викриває такі стани, як resumed, inactive, paused та detached, що приблизно відповідає фазам видимості, фону та знищення Android. Коли вам дійсно потрібні низькорівневі перехоплювачі життєвого циклу для керування ресурсами, ви зазвичай реалізуєте їх на рідній стороні Android у FlutterActivity або плагін, не в Dart.

Наміри відіграють дві ролі в Android: навігація в додатку та комунікація між додатками. Як згадувалося, Flutter не має API навігації на основі намірів — Navigator повністю замінює його у світі Dart. Для крос-додаткових завдань (запуск камери, вибір файлів, обробка намірів спільного доступу) зазвичай використовуються плагіни, які обгортають необхідні виклики Android (та iOS). Якщо плагіна не існує, ви можете написати свій власний за допомогою MethodChannels для взаємодії між Dart та нативним кодом, пересилаючи наміри та результати як повідомлення.

Ваше розуміння фонової роботи та потоків також переноситься, але примітиви виглядають інакше. Android спонукає вас переносити мережевий та дисковий ввід/вивід з основного потоку за допомогою корутин, AsyncTask (застарілий), WorkManager, JobScheduler, RxJava тощо. Dart, навпаки, використовує однопотоковий цикл подій для кожного ізоляту, з async/await для вводу/виводу та окремими ізолятами для роботи, що вимагає багато ресурсів процесора. Для будь-чого, що пов'язано з вводом/виводом, просто позначте свої функції. async, await операцію та дозволяє циклу подій підтримувати чутливість інтерфейсу користувача; для важких завдань процесора ви розкручуєте ізолят та спілкуєтесь через передачу повідомлень замість спільної пам'яті.

Що стосується мережевого фронту, Flutter популярний http Пакет відіграє роль, подібну до OkHttp + Retrofit, для базових випадків використання. Він приховує значну частину роботи з низькорівневими сокетами та природно інтегрується з async/await. Для складних потреб можна перейти на такі пакети, як dio, але фундаментальна схема залишається: зробити асинхронний виклик, очікувати результату, оновити стан за допомогою setState() або вибраний вами менеджер станів та перебудуйте відповідні віджети.

Плагіни, сховище, Firebase та інструменти

На Android ви звикли оголошувати залежності в Gradle; у Flutter ви оголошуєте їх у pubspec.yaml та отримати їх з pub.dev. Файли Gradle під android/ Папки проекту Flutter здебільшого призначені для інтеграцій з певною платформою або коли вам потрібні власні нативні бібліотеки — щоденна розробка додатків залишається в країні Dart.

Спільні налаштування та SQLite також мають готові еквіваленти. Де пропонує Android SharedPreferences для невеликого сховища ключ-значення та SQLite (або Room) для структурованих даних, Flutter обгортає їх за допомогою плагінів, таких як shared_preferences та sqfliteЦі плагіни об'єднують роботу Android та iOS, тому ви можете використовувати один Dart API незалежно від платформи, все ще покладаючись на базові нативні реалізації.

Інтеграція з Firebase є так само простою та першокласною. Більшість сервісів Firebase — автентифікація, Firestore, база даних у реальному часі, хмарний обмін повідомленнями, аналітика, віддалене налаштування та інші — мають офіційні плагіни Flutter, що підтримуються командами Firebase та Flutter. Вони відображають концептуальну модель з SDK Firebase для Android, але з ідіоматичними API Dart. Для більш нішевих функцій Firebase, які не розглядаються безпосередньо, існує здорова екосистема сторонніх плагінів на pub.dev.

Для налагодження та профілювання пакет DevTools від Flutter надає вам багатий набір інструментів, безпосередньо порівнянний з профайлером та інспектором макета Android Studio. Ви можете перевіряти дерево віджетів, відстежувати перебудови, спостерігати за розподілом пам'яті, діагностувати витоки та фрагментацію, а також покроково проходити код Dart. У поєднанні з підтримкою IDE в Android Studio та VS Code, гарячим перезавантаженням та гарячим перезапуском, цикл зворотного зв'язку в розробці на Flutter здається щонайменше таким же щільним, а часто й щільнішим, ніж той, до якого ви звикли в Compose.

Push-сповіщення, ще одна поширена проблема Android, обробляються у Flutter за допомогою плагінів, таких як firebase_messaging. «Під капотом» вони взаємодіють із Firebase Cloud Messaging та нативними фреймворками сповіщень на Android та iOS, але логіка вашого додатка знаходиться в єдиному API Dart. Конфігурація та поведінка, специфічна для платформи (наприклад, канали сповіщень на Android), все ще важливі, і ваш поточний досвід роботи з цими деталями платформи залишається дуже актуальним.

Навіть віджети головного екрана на Android, які не можна реалізувати виключно у Flutter, все ще можна інтегрувати з кодом Flutter. Зазвичай ви створюєте їх за допомогою макетів Jetpack Glance або XML, а потім використовуєте такий пакет, як home_widget для взаємодії з вашим застосунком Flutter, обміну даними та навіть вбудовування растеризованого інтерфейсу Flutter як зображення всередині нативного віджета. Такий гібридний підхід дозволяє вам зберегти основний інтерфейс у Flutter, дотримуючись обмежень платформи.

Дивлячись на всі ці паралелі, розробник Jetpack Compose, який починає працювати з Flutter, зовсім не починає з нуля. Ваше розуміння декларативного інтерфейсу користувача, життєвого циклу Android, навігації, стану, ресурсів та асинхронної роботи дуже природно відображається у світі Flutter; найбільше змінюються назви, мова (Dart) та мультиплатформенний менталітет. Щойно ви засвоїте віджети та Navigator як фундаментальні концепції, решта стеку, як правило, досить швидко стане на свої місця.

Схожі повідомлення: