Flutter. Много
Заказать мобильную разработку: https://amiga.agency/?utm_source=tg Заказать рекламу в канале @amiga_agency_bot Новости Flutter-разработки, дайджесты мероприятий, личный опыт.
Ko'proq ko'rsatish2 660
Obunachilar
-1724 soatlar
-217 kunlar
+18230 kunlar
- Kanalning o'sishi
- Post qamrovi
- ER - jalb qilish nisbati
Ma'lumot yuklanmoqda...
Obunachilar o'sish tezligi
Ma'lumot yuklanmoqda...
Photo unavailableShow in Telegram
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 и присваивать их путям в наших настройках.
Было полезно? Если у вас еще остались вопросы, то пишите в чат.❤ 4👍 2🔥 1
Photo unavailableShow in Telegram
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.
А пока на этом всё, пишите в чате, было ли полезно?❤ 10👍 2🔥 1
Photo unavailableShow in Telegram
Hola, Amigos! Лето богато на события, поэтому мы снова с анонсом. 29-30 августа приглашаем вас на BOOST — это крупнейшая конференция для руководителей студий и агентств 🅰️
Соберется 1000 IT-специалистов из разных направлений: менеджмент, разработка, дизайн, креатив, продажи, PR и маркетинг.
Мы уже готовим свои доклады, о которых расскажем чуть позже, а пока знакомьтесь с программой по ссылке.
Успейте купить билет по самой выгодной стоимости, ведь цена будет расти!
И ловите наш промокод AMIGA10, который дарит скидку 10% 🙂
До встречи на BOOST!
🔥 5❤ 2🥰 2
Photo unavailableShow in Telegram
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 подошла к концу. Делитесь в комментариях, было ли полезно?🔥 3
Photo unavailableShow in Telegram
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
Photo unavailableShow in Telegram
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👎 2❤ 1😢 1
00:48
Video unavailableShow 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 в своих проектах? Расскажите о своем опыте в чате.IMG_8943.MP42.12 MB
👍 15🔥 5💘 2👏 1
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 предлагает гибкие настройки, позволяя управлять последовательностью создания зависимостей в случае необходимости ⚙️
Будем рады вашим вопросам и обсуждениям в чате!🔥 5👍 3❤ 2💩 2👎 1👏 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. Это позволит нам собирать быструю обратную связь по добавленному материалу и вносить правки.
Хочешь принять участие? Предлагай тему сквозного проекта для книги в нашем чате, и если авторскому коллективу она понравится, мы добавим отдельное упоминание в графе с благодарностями.
Ждите прямых эфиров на нашем канале. Будем держать вас в курсе новостей о развитии книги! 🙂
🔥 12❤ 3👏 2💯 2
00:09
Video unavailableShow 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,
),
),
],
);
}
Хорошего всем кода! Делитесь в чате своим опытом использования данного пакета.IMG_8742.MP48.65 KB
🔥 16👍 7💯 2👀 1
Boshqa reja tanlang
Joriy rejangiz faqat 5 ta kanal uchun analitika imkoniyatini beradi. Ko'proq olish uchun, iltimos, boshqa reja tanlang.