Flutter. Много
2.76K subscribers
332 photos
23 videos
257 links
Заказать мобильную разработку: https://amiga.agency/?utm_source=tg
Заказать рекламу в канале @amiga_agency_bot

Новости Flutter-разработки, дайджесты мероприятий, личный опыт.
Download Telegram
Многомодульность в Flutter

Hola, Amigos! На связи Павел Гершевич, Flutter Team Lead в Amiga. Сегодня расскажу, как создавать большие приложения на Flutter с помощью многомодульности. Также она пригодится в случаях, когда нужно создать набор библиотек и когда общий код должен быть у 2 и более приложений.

У многомодульности есть 2 основных подхода: монорепозиторий и полирепозиторий. Сегодня рассмотрим первый. Кто-то изобретает велосипед, а мы используем готовый пакет Melos.

Для начала нам нужно установить его глобально через консоль.

dart pub global activate melos

Далее создаем папку под проект. В ней обязательно должно быть 2 файла: pubspec.yaml, в котором обозначим название проекта и версию Dart, а также melos.yaml для настроек монорепозитория. Создаём нужные приложения, пакеты и плагины, в которые будем писать код. Вот примерное расположение папок для 2 приложений:

my_project
|— apps
| |— app_1
| |— app_2
|— common
| |— ui_kit
| |— models
|— features
| |— feature_1
| |— feature_2
| |— feature_3
|— melos.yaml
|— pubspec.yaml
|— README.md


pubspec.yaml
name: my_project

environment:
sdk: '>=3.0.0 <4.0.0'

dev_dependencies:
melos: ^6.0.0


melos.yaml
name: my_project

packages:
- apps/**
- common/**
- features/**


После этого мы получаем зависимости для всех созданных нами пакетов. Также это сгенерирует файлы pubspec_overrides.yaml, которые нужно не забыть добавить в .gitignore. Делается это командой:

melos bootstrap

Так у нас появляется наш многомодульный проект на Dart и Flutter.

Поделитесь в чате, в каких многомодульных Flutter-проектах вы участвовали? С какими трудностями встречались?
🔥12👍63👎1💘1
Project IDX

Hola, Amigos! Недавно мы рассказывали про Gemini в Android Studio, но в Flutter он не у всех работает, как мы узнали из нашего чата. И для вас у нас есть решение — Project IDX.

Project IDX — облачная IDE от Google нового поколения, которая позволяет создавать fullstack приложения прямо в браузере. Уже поддерживает основные технологии:

⚪️ Для Backend: Node Express, Go, Rust, Django, Flask, .NET.
⚪️ Для Frontend: Angular, React.js, Vue.js, Svelte и многое другое, можно даже на простом HTML и CSS что-то написать.
⚪️ Если нужно и то, и другое — NextJS.
⚪️ Для ИИ: Gemini API.
⚪️ И для мобильных приложений, конечно же, Flutter.

Под каждую из этих технологий уже есть шаблоны, но вы можете подключить свой проект из GitHub.

Flutter проекты в Project IDX умеют запускаться на Android и Web. Работают Hot Restart и Hot Reload, причем иногда быстрее, чем через Android Studio или Xcode. Даже DevTools не нужно отдельно запускать, они уже встроены.

При помощи Project IDX можно сразу захостить Web сборку в Firebase или добавить Gemini API в приложение, нажатием одной кнопки ⚙️

Делитесь в чате, пробовали ли вы Project IDX?
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍6🤝4
Hola, Amigos! На связи Владимир Зевеке и Михаил Чернецов, Flutter-devs Amiga. Сегодня обсудим MediaQuery — важный инструмент для адаптивной верстки.

MediaQuery — это класс, устанавливающие поддерево, в котором для заданных данных разрешаются медиа-запросы. Самое популярное его свойство — size, к которому часто обращаются через MediaQuery.of(context).size.

Однако, это не оптимально. Рекомендуется использовать MediaQuery.sizeOf(context). Разница в том, что функция of() заставляет виджет перестраиваться при изменении любого свойства MediaQuery, тогда как sizeOf() этого не делает, что повышает производительность. То же самое относится и к другим свойствам MediaQuery.

Несмотря на удобство MediaQuery, им не рекомендуется злоупотреблять в коде, поскольку в определённых случаях поведение данного инструмента может стать труднопредсказуемым. Его можно использовать, если:

🔴 Приложение должно адаптировать дизайн под разные размеры экрана.
🔴 Виджету требуется динамическая ширина (width).
🔴 Задачу нельзя решить другим инструментом адаптивной верстки, например, Flexible.

MediaQuery также предоставляет информацию об экране устройства: viewInsets и viewPadding. viewInsets полезен для определения, открыта ли клавиатура. viewPadding дает информацию о небезопасной зоне устройства.

Ещё одна фишка — использование textScaler для адаптивной верстки, это полезно если размеры какого-то виджета должны увеличиваться при увеличении размера текста. Например, виджет фиксированной высоты или размер иконок в кнопках.

Кроме того, MediaQuery позволяет узнать находится ли устройство в режиме «темной темы», используя поле platformBrightness и ориентацию устройства (ландшафтный или портретный режим).

Делитесь своими вопросами и опытом в чате!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍194🔥4👌1
Hola, Amigos! Недавно прошла главная конференция по мобильной разработке этой весны — Mobius 2024 Spring.

Mobius — техническая конференция для специалистов, связанных с мобильной разработкой: iOS- и Android-разработчиков, архитекторов мобильных приложений, специалистов по DevOps, тестировщиков, тимлидов и руководителей проектов.

Для каждой из платформ спикеры обсуждают как нативную, так и кроссплатформенную разработку. И всё, что «вокруг»: от Swift до систем сборки.

От Amiga на Mobius выступил Павел Гершевич, наш Flutter Team Lead с докладом «Создание indoor-карты здания на Flutter».

Обсудили реализацию интересной задачи — размещение на одном или нескольких экранах внутренней карты здания. Рассказали о подходах и собственном решении с использованием Flutter.

Кроме этого, Павел выступил экспертом у Кирилла Адещенко из РСХБ-Интех на теме «Многомодульное приложение на Flutter» и доказал, что на Flutter можно создавать крупные приложения.

Пока доступны только презентации. Видеозаписями поделимся немного позже!

Пишите в чат, кто был на конференции? Чьи доклады понравились больше всего?
👍10👏4🔥3
IT’S TIME TO RUN

Hola, Amigos! Приглашаем 07 июля всех-всех-всех разработчиков, аналитиков, маркетологов, тестировщиков и других специалистов, кто напрямую связан с IT-сферой поучаствовать в самом масштабном и энергичном мероприятии RUNIT.

RUNIT — это спортивный фестиваль для IT-сообщества. В этом году пройдет юбилейный 5-ый забег в музее-заповеднике «Коломенское». В этом году участвует 4000 бегунов и еще как минимум 2000 болельщиков!

Amiga также присоединится к этому событию, такое нельзя пропускать! И в этот раз вы увидите нас в новом свете. Участвуйте и приходите на нашу промо-площадку, где вы сможете:

🔴 познакомиться с нашей командой и обменяться опытом;
🔴 поучаствовать в ловком конкурсе «Кольцеброс» и получить самый классный мерч от нас и подарки от наших партнеров HolyCorn и FitnesSHOK.
🔴 отдохнуть в тени под кронами деревьев на пледе или зарядиться энергетическим гелем от Спорт Фермы перед забегом.

Для участия регистрируйтесь на сайте!

До встречи на RUNIT 07 июля ❤️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍63🔥3💘2
This media is not supported in your browser
VIEW IN TELEGRAM
Hola, Amigos! На связи Вова Зевеке, Flutter dev Amiga. Сегодня расскажу про #пп scroll_highlight_text.

Пакет полезен для поиска в большом объеме текста. Виджет HighlightedTextScrollable позволяет скроллить текст и выделять совпадения при вводе ключевого слова в поиск.

Виджет обладает свойствами:
⚪️ text (String, отображаемый текст виджета);
⚪️ searchController (TextEditingController, контроллер для управления поведением виджета);
⚪️ autoDisposeSearchController (bool, определяет, нужно ли автоматически удалять контроллер при удалении виджета из дерева виджетов);
⚪️ textDirection (TextDirection, определяет направление текста);
⚪️ highlightedTextStyle (TextStyle, стиль текста, применяемый к выделенным участкам текста);
⚪️ unHighlightedTextStyle (TextStyle, стиль текста, примененный к остальной части текста);
⚪️ padding (EdgeInsetsGeometry, внутренние отступы вокруг текстового виджета);
⚪️ durationOfScroll (Duration, продолжительность анимации скролла);
⚪️ animationCurveOfScroll (Curve, тип анимации скролла).

Пример:


final TextEditingController controller = TextEditingController();
final String value =
'Понедельник - день тяжёлый, <…>';

@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: SearchBar(
hintText: 'Start search',
controller: controller,
),
),
HighlightedTextScrollable(
text: value,
searchController: controller,
highlightedTextStyle: const TextStyle(
fontSize: 22,
color: Colors.red,
fontWeight: FontWeight.w600,
),
unHighlightedTextStyle: const TextStyle(
fontSize: 22,
color: Colors.black,
),
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 20,
),
),
],
);
}


Хорошего всем кода! Делитесь в чате своим опытом использования данного пакета.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍7💯2👀1
Hola, Amigos! На связи Павел Гершевич, Flutter Team Lead в Amiga. Вы часто спрашиваете в комментариях, где можно научиться Flutter, и просите поделиться полезными материалами. И мы очень стараемся делать это в наших постах!

Но хотим порадовать вас еще одной классной новостью: вместе с тремя талантливыми и увлеченными Flutter авторами мы напишем книгу «Основы Flutter».

Вы должны знать своих героев:

🔵 Станислав Чернышев — автор YouTube-канала «MADTeacher» и учебника «Основы Dart».
🔵 Юрий Петров — Flutter Tech Lead в Friflex, автор YouTube- и телеграм-каналов «Мобильный разработчик», а также курсов на платформе Stepik.
🔵 Станислав Ильин — Lead Flutter developer, автор YouTube- и телеграм-каналов «Стас Ильин».
🔵 И конечно же я, Павел Гершевич — Flutter Team Lead в Amiga, спикер различных конференций и автор телеграм-канала «Flutter TechLead Notes» буду соавтором книги.

Все самые свежие материалы книги, прошедшие редактуру, будут выкладываться в курс на Stepik — Основы Flutter. Это позволит нам собирать быструю обратную связь по добавленному материалу и вносить правки.

Хочешь принять участие? Предлагай тему сквозного проекта для книги в нашем чате, и если авторскому коллективу она понравится, мы добавим отдельное упоминание в графе с благодарностями.

Ждите прямых эфиров на нашем канале. Будем держать вас в курсе новостей о развитии книги! 🙂
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥134👏2💯2
Hola, Amigos! На связи Михаил Чернецов, Flutter dev в Amiga. Сегодня поговорим про Injectable — мощный пакет для управления зависимостями в приложении.

Injectable является оберткой над GetIt и помогает создавать Dependency Injection (DI) с помощью кодогенерации, избавляя от необходимости вручную редактировать файл с зависимостями ⚙️

GetIt — это популярный service locator, который позволяет централизованно управлять зависимостями в приложении. Однако, некоторые считают service locator антипаттерном, так как он может нарушать принципы SOLID и инкапсуляции.

Основные возможности Injectable

Injectable создает файл, который автоматически регистрирует сервисы, синглтоны и модули. Для добавления модуля достаточно пометить класс аннотацией @injectable. Этот класс затем будет доступен через GetIt.instance<YourService>(). Вы также можете объявить синглтоны с помощью аннотаций @singleton и @lazysingleton.

Пример использования

Чтобы подключить сторонние зависимости, такие как dio или shared_preferences, создайте класс ServicesInjectionModule и пометьте его аннотацией @module. Если вам нужно дождаться завершения фабрики, возвращающей future, используйте аннотацию @preResolve:


@preResolve
Future<SharedPreferences> get sharedPreferences => SharedPreferences.getInstance();


Многомодульность

Injectable поддерживает многомодульность. Чтобы создать файл в модуле, используйте:


@InjectableInit.microPackage()
void initMicroPackage() {}


Это создаст FeaturePackageModule, который нужно будет добавить в externalPackageModules приложения.

Injectable предлагает гибкие настройки, позволяя управлять последовательностью создания зависимостей в случае необходимости ⚙️

Будем рады вашим вопросам и обсуждениям в чате!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍32💩2👎1👏1
This media is not supported in your browser
VIEW IN TELEGRAM
Hola, Amigos! На связи Владимир Зевеке, Flutter dev в Amiga. Сегодня поговорим о пакете audio_waveforms. Этот пакет добавляет возможность записывать аудиофайлы и воспроизводить их в отдельном виджете, с красивым визуальным шлейфом звуков. Он особенно полезен для разработки чатов.

Установка и настройка

Для установки нам нужно подключить пакет и следуя инструкции из pub.dev добавить разрешение на использование микрофона для необходимых платформ.

Инициализация

Создаем поля для виджетов записи и воспроизведения аудио:

late final RecorderController recorderController;
late final PlayerController playerController


Инициализируем контроллеры:

@override
void initState() {
recorderController = RecorderController()
..androidEncoder = AndroidEncoder.aac
..androidOutputFormat = AndroidOutputFormat.mpeg4
..iosEncoder = IosEncoder.kAudioFormatMPEG4AAC
..sampleRate = 16000;

playerController = PlayerController();
super.initState();
}


Не забываем освобождать ресурсы:

@override
void dispose() {
recorderController.dispose();
playerController.dispose();
super.dispose();
}


Запись и воспроизведение

Для записи нужно проверить дал ли пользователь разрешение на использование микрофона:

final bool hasPermission = await recorderController.checkPermission();


Если оно у нас есть, то мы можем запустить запись, вызвав:

await recorderController.record();


Или остановить запись при помощи:

String pathAudio = await recorderController.stop() ?? '';
await playerController.preparePlayer(path: pathAudio);


Для проигрывания используем метод:

await playerController.startPlayer(finishMode: FinishMode.pause);


Для завершения вызываем:

await playerController.pausePlayer();


Для вывода на экран понадобятся виджеты AudioWaveforms и AudioFileWaveforms. Они легко настраиваются с помощью полей waveStyle и playerWaveStyle, которые предлагают множество опций для кастомизации.


AudioWaveforms(
size: const Size(double.infinity, 50.0),
recorderController: recorderController,
),


Пакет также поддерживает различные слушатели для работы контроллеров, что делает его гибким и мощным инструментом для разработки.

Использовали ли вы пакет audio_waveforms в своих проектах? Расскажите о своем опыте в чате.
👍15🔥5💘2👏1
Hola, Amigos! На связи Михаил Чернецов, Flutter dev в Amiga. Сегодня расскажу про пакет auto_route, который создает роуты для приложения с помощью кодогенерации.

Он поддерживает deeplinks, с помощью которых можно открыть приложение на необходимой странице: например ссылка в письме, ведущая на сделанный пользователем заказ. А также Route Guard, который создатели библиотеки сравнивают с интерсептором для навигации, но о нем чуть позже.

Для создание конфигурации роутера необходимо создать класс роутера:


@AutoRouterConfig()
class AppRouter extends $AppRouter {

@override
List<AutoRoute> get routes => [
AutoRoute(page: HomeRoute.page),
];
}


Для получения HomeRoute, необходимо пометить аннотацией RoutePage HomeScreen. Причем в стандартной настройке Screen и Page в названии страницы заменяются на Route.


@RoutePage()
class HomeScreen extends StatefulWidget {}


В роуты также можно передавать параметры, при этом сохраняются стандартные значения и учитывается наличие поля required.


context.router.push(BookRoute(bookId: id));


Для того, что бы им можно было пользоваться, необходимо добавить роутер в приложение:


final _appRouter = AppRouter();



@override
Widget build(BuildContext context){
return MaterialApp.router(
routerConfig: _appRouter.config(),
);
}


Далее с помощью extension над context можем получать router, имеющий такое же api как у navigator и так же использует навигацию через стек.

– maybePop — по возможности убирает последний роут из стека.
– push — добавляет в стек новый роут.
– replace — заменяет текущий роут на другой. При этом не меняет стек роутов.
– remove — убирает определенный роут из стека.
– navigate — если роут в стеке, убирает роуты до того, как попадется необходимый или добавляет роут в стек.

Большая часть остальных методов является просто комбинацией из этих 5-ти. Всем хорошего кода!

Делитесь в чате своим опытом работы с библиотекой.
🔥8👍5👏3👎21😢1
Hola, Amigos! На связи Михаил Чернецов, Flutter dev в Amiga. Продолжаем нашу серию постов о библиотеке auto_route. И во второй части поговорим о вложенной навигации, анимациях и многомодульности.

Вложенная навигация (Nested Navigation) используется для роутов с несколькими вложенными вкладками.в

AutoRoute содержит поле children, в который можно передать список AutoRoute.
И при помощи виджета AutoRouter организовать автоматическую навигацию между вложенными страницами.

AutoRoute(
page: BottomNavRoute.page,
children: [
AutoRoute(page: HomeRoute.page),
AutoRoute(page: ListRoute.page),
...
],
);


  @override
Widget build(BuildContext context) {
return Scaffold(
body: AutoRouter(),
bottomNavigationBar: BottomNavigationBar(
/// Navigate here
),
);
}
}


Анимация при навигации
Используем transitionBuilder и создаём собственный вариант перехода для анимации роута.

CustomRoute(
page: ZoomInScreen,
transitionsBuilder:
(BuildContext context, Animation<double> animation, _, Widget child) {
return ScaleTransition(scale: animation, child: child);
},
)


Многомодульность
При вводе бойлерплейт генерируется модуль для всех роутов модуля.

@AutoRouterConfig.module()
class MyPackageModule extends $MyPackageModule {}


При добавлении модуля, AppRouter получает доступ ко всей информации о роутах MyPackageModule. Однако, как и при обычной генерации, все роуты необходимо прописать в класс AppRouter.

@AutoRouterConfig([
MyPackageModule,

])
class AppRouter extends $AppRouter {
@override
List<AutoRoute> get routes => [
AutoRoute(page: HomeRoute.page),

];
}


В следующий раз расскажем про RouteGuard и их применение. Всем хорошего кода!

Делитесь в чате своим опытом работы с библиотекой.
5🔥4👍3
Hola, Amigos! На связи Михаил Чернецов, Flutter dev в Amiga. Как и обещали, сегодня расскажем про Route Guard. Он позволяет манипулировать навигацией в самом приложении и переводить пользователя на необходимый экран.


class AuthGuard extends AutoRouteGuard {

@override
void onNavigation(NavigationResolver resolver, StackRouter router) {
final authenticated = myService().authenticated;
if (authenticated) {
resolver.next(true);
}
else {
resolver.redirect(const AuthRoute());
}
}
}


Единственная проблема — это необходимость использовать или глобальные переменные или каждый раз инициализировать сервисы для проверки каких-то данных.

Для этого RouteGuard, можно пометить аннотацией @injectable из одноименной библиотеки, и можно туда передать уже существующий синглтон.


@injectable
class AuthGuard extends AutoRouteGuard {
final MySingleton singleton;

AuthGuard({required this.singleton});

@override
void onNavigation(NavigationResolver resolver, StackRouter router) {
final authenticated = singleton.isAuth;
…..,
}
}


Добавление же AuthGuard в роут тоже достаточно просто:


AutoRoute(
page: HomeRoute.page,
guards: [
AuthGuard(),
],
),


Или в случае использования injectable/getIt:

GetIt.instance<AuthGuard>().


Route wrapper позволяет оборачивает роут. Используя аннотацию AutoRouteWrapper.


@RoutePage()
class ProductsScreen extends StatelessWidget implements AutoRouteWrapper {

@override
Widget wrappedRoute(BuildContext context) {
return Provider(create: (ctx) => ProductsBloc(), child: this);
}
...
}


Самое интересное то, что дочерний Route не только будет иметь доступ к блоку, но и может быть обернут, например, в Scaffold с AppBar.

На этом наша серия постов о библиотеке auto_route подошла к концу. Делитесь в комментариях, было ли полезно?
🔥51👏1
Hola, Amigos! Лето богато на события, поэтому мы снова с анонсом. 29-30 августа приглашаем вас на BOOST — это крупнейшая конференция для руководителей студий и агентств 🅰️

Соберется 1000 IT-специалистов из разных направлений: менеджмент, разработка, дизайн, креатив, продажи, PR и маркетинг.

Мы уже готовим свои доклады, о которых расскажем чуть позже, а пока знакомьтесь с программой по ссылке.

Успейте купить билет по самой выгодной стоимости, ведь цена будет расти!

И ловите наш промокод AMIGA10, который дарит скидку 10% 🙂

До встречи на BOOST!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥52🥰2
Hola, Amigos! На связи Павел Гершевич, Flutter Team Lead в Amiga. Недавно в чате вы спрашивали, в чем разница между go_router и auto_route. Рассказываем!

Сходства

Обе этих библиотеки работают на Navigator 2.0, что дает нам больший контроль над навигацией в наших приложениях. Также часть функционала в них совпадает.

Количество кода

В auto_route мы пишем намного меньше кода, так как используется кодогенерация. Но некоторые не любят ее, поэтому используют GoRouter. Также auto_route позволяет нам напрямую передавать нужные аргументы прямо в Route, не используя дополнительный код.

Разберем на примере вот такого экрана:


class HomePage extends StatelessWidget {
final String appName;
const HomePage({required this.appName, super.key});

}


Для auto_route у нас будет:


AutoRoute(page: HomeRoute.page);

context.router.push(HomeRoute(appName: ‘My App Name’));


А для go_router:


GoRoute(
path: ‘/home’,
builder: (context, state) {
final appName = state.queryParams[‘appName’];
return HomePage(appName: appName);
}
);

GoRouter.of(context).push(‘/home?appName=”My App Name”’);


В следующей части поговорим о количестве багов, вложенной навигации и Route Guards.

А пока на этом всё, пишите в чате, было ли полезно?
13👍5🔥2
Hola, Amigos! На связи Павел Гершевич, Flutter Team Lead в Amiga. Продолжаем рассказывать, в чем разница между go_router и auto_route.

Количество багов и костылей

На личном опыте можем сказать, что с go_router костылей и правок, которых нужно исправлять вручную, всегда больше, чем с auto_route. Да, первые версии могли пропускать кадры при переходах, но со временем это исправили.

Вложенная навигация

В auto_route вложенная навигация устроена намного удобнее, чем в go_router. Так как у нас есть возможность создать дополнительный роутер внутри нашего экрана и переходить внутри него.


Scaffold(

body: AutoRoute(),

);


Да, go_router поддерживает такое, но настройка будет в разы сложнее.

Route Guards

Настройка guards в go_router делается при настройке самого роутера, а перенаправление — при помощи функции redirect.

В auto_route мы можем создавать именно отдельные Route Guards и присваивать их путям в наших настройках.

Было полезно? Если у вас еще остались вопросы, то пишите в чат.
7👍5🔥4
Hola, Amigos! На связи Павел Гершевич, Flutter Team Lead в Amiga. Приготовили для вас серию статей переводов о тестировании в Flutter.

Сегодня первый выпуск, в котором познакомимся с Unit-тестированием, Widget-тестированием, Golden-тестами и интеграционным тестированием (оригинал).

В статье приведено много примеров и часто встречаемых ошибок, с которыми сталкиваются специалисты, когда пишут тесты. Показано, как писать код, чтобы сделать тестирование проще, и как использовать AI-инструменты, такие как ChatGPT или GitHub Copilot для увеличения скорости написания тестов.

Переходите по ссылке. По ходу материала вам будут встречаться мои комментарии.

Приятного чтения! Будем рады вашей обратной связи в чате.
🔥82👏2👍1
Hola, Amigos! На связи Павел Гершевич, Flutter Team Lead в Amiga. Продолжаем раскрывать тему тестирования в Flutter и сегодня поговорим о модульном (Unit) тестировании.

В данной статье описан простой Unit-тест и использование функций expect и Matcher. Скорее переходите на Habr, чтобы узнать подробности! ⬅️

Еще несколько выпусков будут посвящены Unit-тестам, разберем более сложные случаи с использованием продвинутых техник: Mock, Fake и Stub.

Ставьте реакцию, если ждете продолжения! 🙂
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍6👏2👨‍💻1
Hola, Amigos! На связи Павел Гершевич, Flutter Team Lead в Amiga. Вот и третья часть перевода подъехала⚙️

В предыдущих статьях мы научились писать модульные тесты для статичных функций, верхнеуровневых функций и расширений. На этот раз напишем Unit-тесты для методов класса.

Читайте по ссылке на Habr. Пишите комментарии и ставьте реакции, если тема вам интересна!⚙️
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍42
Hola, Amigos! На связи команда агентства продуктовой разработки Amiga. Делимся лучшими практиками работы с BLoC.

Немного терминологии для тех, кто только начинает погружаться в кроссплатформенную разработку.

Что такое BLoC?

BLoC (компонент бизнес-логики) — это класс, отделяющий бизнес-логику приложения от пользовательского интерфейса. Такой компонент содержит код, который можно повторно использовать в любом модуле, платформе или приложении.

Почему это важно?

Отделение UI от бизнес-логики для Flutter жизненно необходимо. Карабкаться вверх-вниз по дереву виджетов в поисках нужной логики — не самая приятная задача. Особенно, если верстка и так содержит много кода и разбросана по разным файлам.

Использование BLoC помогает:

⚙️ Упрощать тестирование кода.
⚙️ Повышать читаемость и поддерживаемость кода.
⚙️ Переиспользовать бизнес-логику между различными модулями и платформами.

Смотрите карточки, забирайте советы себе на заметку!

И пишите в комментариях, что хотелось бы ещё узнать?
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18👍126