Hola, Amigos!
На связи Михаил Чернецов, Flutter Dev агентства продуктовой разработки Amiga. Сегодня мы поговорим про Draggable, который позволяет перетаскивать виджет по всему пространству экрана.
При передвижении объекта под курсором отображается виджет, передаваемый в свойство feedback. Если необходимо изменить сам виджет, можно передать свойство в
Однако само перетаскивание виджета ничего не делает. Необходимо также предоставить ему место, куда его можно передвинуть. Этим занимается виджет DragTarget.
Необходимо предоставить ему билдер и опциональные callback
Однажды это нами было использовано, т.к. при драге виджета мы не можем использовать другие жесты, в том числе скролл. На верхней и нижней границе экрана были расположены два невидимых драг таргета, которые начинали движение ScrollController при срабатывании onMove и останавливали движение контроллера при срабатывании onLeave.
Из интересных применений Draggable является также оборачивание виджета в DragTarget. Его нельзя будет перетаскивать, но он будет реагировать на перетаскивание Draggable. Например, когда нужно сделать что-то наподобие ReorderableList, когда можно взять необходимый элемент, а остальные элементы обернуть в DragTarget.
Также существует виджет LongPressDraggable, который перетаскивается только при срабатывание на длительное нажатие и при этом триггерит
Всем хорошего кода! Делитесь в чате своим опытом работы с Draggable.
На связи Михаил Чернецов, Flutter Dev агентства продуктовой разработки Amiga. Сегодня мы поговорим про Draggable, который позволяет перетаскивать виджет по всему пространству экрана.
При передвижении объекта под курсором отображается виджет, передаваемый в свойство feedback. Если необходимо изменить сам виджет, можно передать свойство в
childWhenDragging
.
Draggable(
data: …, // Данные
feedback: Container(), // Виджет который перетаскивается
childWhenDragging: Container(), // Виджет который заменяет child, когда виджет перетаскивают, необязательный.
child: Container(), // Сам виджет
),
Однако само перетаскивание виджета ничего не делает. Необходимо также предоставить ему место, куда его можно передвинуть. Этим занимается виджет DragTarget.
Необходимо предоставить ему билдер и опциональные callback
onWillAcceptWithDetails
, отвечающий за приём Draggable widget и отработку onAcceptWithDetails
. onMove
и onLeave
— интересные callback, т.к. реагируют не на то, что Draggable был туда передан, а на появление в этой области Draggable.
DragTarget(
builder: (BuildContext context, List<dynamic> _, List<dynamic> _,) {
return Container();
},
onAcceptWithDetails: (DragTargetDetails details) {
…
},
),
Однажды это нами было использовано, т.к. при драге виджета мы не можем использовать другие жесты, в том числе скролл. На верхней и нижней границе экрана были расположены два невидимых драг таргета, которые начинали движение ScrollController при срабатывании onMove и останавливали движение контроллера при срабатывании onLeave.
Из интересных применений Draggable является также оборачивание виджета в DragTarget. Его нельзя будет перетаскивать, но он будет реагировать на перетаскивание Draggable. Например, когда нужно сделать что-то наподобие ReorderableList, когда можно взять необходимый элемент, а остальные элементы обернуть в DragTarget.
Также существует виджет LongPressDraggable, который перетаскивается только при срабатывание на длительное нажатие и при этом триггерит
hapticFeedback
(вибрацию).Всем хорошего кода! Делитесь в чате своим опытом работы с Draggable.
👍11❤3🔥2🙏2
Hola, Amigos!
На связи Павел Гершевич, Mobile Team Lead агентства продуктовой разработки Amiga. Сегодня обсудим кастомизацию иконок по формам и цветам на Flutter. Особенно интересно рассмотреть кейсы с Android выше 12 версии и iOS 18, который пока еще в бете.
Конечно, можно использовать библиотеку flutter_launcher_icons, о которой мы уже рассказывали, но она пока не работает с новыми иконками для iOS. Изменение иконки у приложения — задача достаточно редкая. Давайте посмотрим, как это можно сделать вручную.
👾 Начнем с Android. Можно создать статичные иконки (прямоугольные и круглые), динамическую форму и монохромные, чтобы потом менять цвет.
Для этого понадобится цвет фона или сам фон (только для статичных и динамической формы) и объект на передний план. Всё это в векторе.
Если используем статичные картинки, то их можно подготовить и сделать нужных размеров вручную или при помощи специальных генераторов. Добавляем их в папки /android/app/src/main/res/mipmap-xxxx/ (xxxx заменить на нужный размер) под именами ic_launcher и ic_launcher_round. Далее вписываем код в AndroidManifest:
Если хотим динамические картинки, то можно воспользоваться встроенным инструментом в Android Studio. Для этого откройте папку Android вашего проекта как отдельный проект. После нажмите правой кнопкой мыши на res и выберите New -> Image Asset.
Далее выбираем картинку в Foreground и фон в Background. И Android Studio все сделает сама.
Теперь перейдем в res/drawables/anydpi-v26/ic_launcher.xml и добавим монохромную версию. Если она у вас будет отличаться от фона стандартной, то сначала добавьте свое изображение.
🤖 На iOS все проще. С приходом iOS 18 придет еще 2 типа иконок: для темного режима (Dark) и окрашенные (Tinted).
Лучше всего попросить дизайнера сделать эти 2 типа иконок и изменить их размер, чтобы вставить в Xcode. Сейчас это делается через Xcode Beta. Для темной темы и окраски можно обойтись прозрачными изображениями в отличии от светлой темы.
Всем хорошего кода! Пишите в чате, как вы кастомизируете иконки на Flutter?
На связи Павел Гершевич, Mobile Team Lead агентства продуктовой разработки Amiga. Сегодня обсудим кастомизацию иконок по формам и цветам на Flutter. Особенно интересно рассмотреть кейсы с Android выше 12 версии и iOS 18, который пока еще в бете.
Конечно, можно использовать библиотеку flutter_launcher_icons, о которой мы уже рассказывали, но она пока не работает с новыми иконками для iOS. Изменение иконки у приложения — задача достаточно редкая. Давайте посмотрим, как это можно сделать вручную.
👾 Начнем с Android. Можно создать статичные иконки (прямоугольные и круглые), динамическую форму и монохромные, чтобы потом менять цвет.
Для этого понадобится цвет фона или сам фон (только для статичных и динамической формы) и объект на передний план. Всё это в векторе.
Если используем статичные картинки, то их можно подготовить и сделать нужных размеров вручную или при помощи специальных генераторов. Добавляем их в папки /android/app/src/main/res/mipmap-xxxx/ (xxxx заменить на нужный размер) под именами ic_launcher и ic_launcher_round. Далее вписываем код в AndroidManifest:
<application
...
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
...>
</application>
Если хотим динамические картинки, то можно воспользоваться встроенным инструментом в Android Studio. Для этого откройте папку Android вашего проекта как отдельный проект. После нажмите правой кнопкой мыши на res и выберите New -> Image Asset.
Далее выбираем картинку в Foreground и фон в Background. И Android Studio все сделает сама.
Теперь перейдем в res/drawables/anydpi-v26/ic_launcher.xml и добавим монохромную версию. Если она у вас будет отличаться от фона стандартной, то сначала добавьте свое изображение.
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
🤖 На iOS все проще. С приходом iOS 18 придет еще 2 типа иконок: для темного режима (Dark) и окрашенные (Tinted).
Лучше всего попросить дизайнера сделать эти 2 типа иконок и изменить их размер, чтобы вставить в Xcode. Сейчас это делается через Xcode Beta. Для темной темы и окраски можно обойтись прозрачными изображениями в отличии от светлой темы.
Всем хорошего кода! Пишите в чате, как вы кастомизируете иконки на Flutter?
🔥10👍5❤2🤩1
Hola, Amigos!
На связи Павел Гершевич, Mobile Team Lead агентства продуктовой разработки Amiga. Сегодня рассмотрим плагин local_auth. Он помогает добавить в приложение вход через биометрию — отпечаток пальца или лицо.
Для начала работы нужно указать, что приложение использует эту функциональность, и пользователь может дать разрешение на нее. Для Android в AndroidManifest.xml:
Для iOS в info.plist:
Когда пользователь доходит до момента включения биометрии, то нужно проверить доступна ли она. Если всё работает, то можно выбрать, что показать на экране: иконку отпечатка или иконку FaceID. На некоторых Android смартфонах могут быть доступны оба типа.
Чтобы запросить биометрию, выполним следующий код:
Но у этого плагина также есть и минусы, о которых мы поговорим на конференции «Стачка» 27-28 сентября в Санкт-Петербурге.
Промокод«спикер_10» подарит вам скидку 10% на билет 🎁
До встречи на конференции!
На связи Павел Гершевич, Mobile Team Lead агентства продуктовой разработки Amiga. Сегодня рассмотрим плагин local_auth. Он помогает добавить в приложение вход через биометрию — отпечаток пальца или лицо.
Для начала работы нужно указать, что приложение использует эту функциональность, и пользователь может дать разрешение на нее. Для Android в AndroidManifest.xml:
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
Для iOS в info.plist:
<key>NSFaceIDUsageDescription</key>
<string>Причина использования</string>
Когда пользователь доходит до момента включения биометрии, то нужно проверить доступна ли она. Если всё работает, то можно выбрать, что показать на экране: иконку отпечатка или иконку FaceID. На некоторых Android смартфонах могут быть доступны оба типа.
final LocalAuthentication auth = LocalAuthentication();
final canAuthenticateWithBiometrics = await auth.canCheckBiometrics;
final isDeviceSupported = await auth.isDeviceSupported();
if (canAuthenticateWithBiometrics || isDeviceSupported) {
final availableBiometrics = await auth.getAvailableBiometrics();
if (availableBiometrics.contains(BiometricType.face)) {
... // Показываем иконку с лицом
} else if (availableBiometrics.contains(BiometricType.fingerprint)) {
... // Показываем иконку с отпечатком пальца
}
... // Другие действия для выполнения биометрии
}
Чтобы запросить биометрию, выполним следующий код:
try {
final didAuthenticate = await auth.authenticate(
localizedReason: 'Зачем пользователю ',
options: const AuthenticationOptions(biometricOnly: true),
);
... // Другие действия
} catch (e) {
... // Обработка ошибок
}
Но у этого плагина также есть и минусы, о которых мы поговорим на конференции «Стачка» 27-28 сентября в Санкт-Петербурге.
Промокод
До встречи на конференции!
👍15🔥4🎉2👏1
Hola, Amigos! Рассказываем и показываем в карточках, как прошел BOOST для нас в 2024 году.
А еще раскрываем интригу, кто такая Лидочка! Знакомьтесь с нашим виртуальным менеджером по вашим нецелевым лидам. Переходите в чат, там все подробности⚙️
Проводили лето со всем IT-комьюнити и встретили осень легендарным треком «третье сентября» на афтепати.
А еще раскрываем интригу, кто такая Лидочка! Знакомьтесь с нашим виртуальным менеджером по вашим нецелевым лидам. Переходите в чат, там все подробности
Проводили лето со всем IT-комьюнити и встретили осень легендарным треком «третье сентября» на афтепати.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥3🍾1
Hola, Amigos! На связи Михаил Чернецов, Flutter Dev в Amiga. Сегодня разберем пакет bloc_concurrency, который позволяет манипулировать обработкой событий в BLoC и содержит в себе набор трансформеров 🙂
Трансформеры позволяют изменять поток событий внутри BLoC, чтобы они обрабатывались в нужном порядке или не попадали в обработку в определенных случаях.
Трансформеры передаются через поле transformer в методе on. Для каждого отдельного события (event) можно задать свой трансформер. Если нужно применить один трансформер ко всем событиям, создайте абстрактный класс событий и назначьте его трансформеру.
🔴
🔴
🔴
🔴
Ставьте 🔥, если было полезно и делитесь в чате, пользуетесь ли данным пакетом?
Трансформеры позволяют изменять поток событий внутри BLoC, чтобы они обрабатывались в нужном порядке или не попадали в обработку в определенных случаях.
MyBloc() : super(MyState()) {
on<MyEvent>(
_myEvent,
transformer: concurrent(),
);
}
Трансформеры передаются через поле transformer в методе on. Для каждого отдельного события (event) можно задать свой трансформер. Если нужно применить один трансформер ко всем событиям, создайте абстрактный класс событий и назначьте его трансформеру.
abstract class MyAbstractEvent {}
class OtherEvent extends MyAbstractEvent {}
MyBloc() : super(MyState()) {
on<MyAbstractEvent>(
…,
transformer: concurrent(),
);
}
bloc_concurrency
включает четыре типа трансформеров:concurrent
— обрабатывает все события одновременно; используется в bloc по умолчанию.sequential
— обрабатывает события последовательно, применяя asyncMap. Подходит для случаев, когда требуется поочередная обработка, например, при добавлении товара в корзину по одному.restartable
— прерывает обработку текущего события, если поступает новое. Полезен, когда каждое новое событие может полностью изменить результат, как при обновлении строки поиска: в этом случае нас не интересует результат обработки предыдущего ввода.droppable
— блокирует добавление новых событий до завершения обработки текущего. Эффективен для предотвращения дублирующих действий, например, при нажатии кнопки входа на странице авторизации, чтобы избежать лишних запросов к серверу.Ставьте 🔥, если было полезно и делитесь в чате, пользуетесь ли данным пакетом?
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍6🥰4❤2🤗1
Hola Amigos! На связи Михаил Чернецов, Flutter Dev, и Павел Гершевич, Mobile Team Lead в Amiga. Сегодня расскажем, как собираем приложения под Android.
Существует два вида собираемых файла под Android: APK (Android Package Kit) и Android App Bundle (AAB). Рассмотрим их особенности.
APK — это исполняемый файл, а App Bundle — формат публикаций.
Сборка APK
Запускаем команду:
Однако такой APK подписан debug-ключом и не подходит для публикации. Чтобы создать релизный ключ, используем инструмент keytool из JDK.
Для Windows:
Для macOS и Linux:
Не забудьте указать правильный путь и имя файла ключа. Затем создаем файл
Теперь APK готов к публикации, но он универсальный и достаточно объемный. Чтобы уменьшить размер, лучше собрать отдельные APK для каждой архитектуры процессора:
На выходе получим несколько APK, которые можно зарелизить. Однако они будут крупнее по сравнению с теми, что пользователи смогут скачать из магазинов приложений с использованием AAB.
Сборка AAB
AAB собирается под определенную конфигурацию девайса пользователя. На устройство устанавливается облегченное APK, оптимизированное под архитектуру процессора, разрешение экрана и выбранные языки. Сборка APK в таком случае происходит на стороне магазина приложений.
Для сборки AAB:
1) Подготовьте файл для подписи приложения.
2) Запустите команду:
Этот файл можно загрузить в магазины приложений, и пользователи смогут скачивать облегченное приложение. При обновлении будет загружаться только измененная часть приложения.
Когда использовать APK?
Сборка APK также важна, например, для тестирования — чтобы не выкладывать каждую сборку в магазины приложений. Или если приложение распространяется вне Google Play, App Gallery или RuStore.
Если вам нужен экспертный взгляд или помощь в сборке и публикации приложения, пишите нам. Будем рады помочь!
Существует два вида собираемых файла под Android: APK (Android Package Kit) и Android App Bundle (AAB). Рассмотрим их особенности.
APK — это исполняемый файл, а App Bundle — формат публикаций.
Сборка APK
Запускаем команду:
flutter build apk
Однако такой APK подписан debug-ключом и не подходит для публикации. Чтобы создать релизный ключ, используем инструмент keytool из JDK.
Для Windows:
keytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks `
-storetype JKS -keyalg RSA -keysize 2048 -validity 10000 `
-alias upload
Для macOS и Linux:
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA \
-keysize 2048 -validity 10000 -alias upload
Не забудьте указать правильный путь и имя файла ключа. Затем создаем файл
/android/key.properties
для подписи:storePassword=<пароль от KeyStore>
keyPassword=<пароль от самого ключа>
keyAlias=upload
storeFile=<местоположение файла с ключом>
Теперь APK готов к публикации, но он универсальный и достаточно объемный. Чтобы уменьшить размер, лучше собрать отдельные APK для каждой архитектуры процессора:
flutter build apk --split-per-abi
На выходе получим несколько APK, которые можно зарелизить. Однако они будут крупнее по сравнению с теми, что пользователи смогут скачать из магазинов приложений с использованием AAB.
Сборка AAB
AAB собирается под определенную конфигурацию девайса пользователя. На устройство устанавливается облегченное APK, оптимизированное под архитектуру процессора, разрешение экрана и выбранные языки. Сборка APK в таком случае происходит на стороне магазина приложений.
Для сборки AAB:
1) Подготовьте файл для подписи приложения.
2) Запустите команду:
flutter build appbundle
Этот файл можно загрузить в магазины приложений, и пользователи смогут скачивать облегченное приложение. При обновлении будет загружаться только измененная часть приложения.
Когда использовать APK?
Сборка APK также важна, например, для тестирования — чтобы не выкладывать каждую сборку в магазины приложений. Или если приложение распространяется вне Google Play, App Gallery или RuStore.
Если вам нужен экспертный взгляд или помощь в сборке и публикации приложения, пишите нам. Будем рады помочь!
❤9🔥7👍4🥰1👏1😱1👨💻1
«Попали в сердечко»🥹
Hola, Amigos! Ради такой обратной связи мы готовы тратить 30 часов на подготовку докладов и 8 часов еще много-много раз.
Множество вопросов от аудитории после лекции — плюс еще одно доказательство, что нам удалось угадать с интересными и актуальными темами. Ес!💪🏼
Напомним, что Паша Гершевич, Flutter Team Lead выступал с докладом «Логирование на Flutter или какие метрики помогут в оптимизации».
А Артем Салеев, CTO Amiga — с темой «Перестройка процессов разработки при масштабировании агентства».
Смотрите фотки и ставьте 🔥, если ждете записи докладов!
Hola, Amigos! Ради такой обратной связи мы готовы тратить 30 часов на подготовку докладов и 8 часов еще много-много раз.
Множество вопросов от аудитории после лекции — плюс еще одно доказательство, что нам удалось угадать с интересными и актуальными темами. Ес!💪🏼
Напомним, что Паша Гершевич, Flutter Team Lead выступал с докладом «Логирование на Flutter или какие метрики помогут в оптимизации».
А Артем Салеев, CTO Amiga — с темой «Перестройка процессов разработки при масштабировании агентства».
Смотрите фотки и ставьте 🔥, если ждете записи докладов!
🔥18👏2🤩1