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

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

На связи Михаил Чернецов, 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.
👍113🔥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:

<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👍52🤩1
Hola, Amigos!

На связи Павел Гершевич, 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 сентября в Санкт-Петербурге.

Промокод «спикер_10» подарит вам скидку 10% на билет 🎁

До встречи на конференции!
👍15🔥4🎉2👏1
Hola, Amigos! Рассказываем и показываем в карточках, как прошел BOOST для нас в 2024 году.

А еще раскрываем интригу, кто такая Лидочка! Знакомьтесь с нашим виртуальным менеджером по вашим нецелевым лидам. Переходите в чат, там все подробности⚙️

Проводили лето со всем 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, чтобы они обрабатывались в нужном порядке или не попадали в обработку в определенных случаях.

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🥰42🤗1
Hola Amigos! На связи Михаил Чернецов, Flutter Dev, и Павел Гершевич, Mobile Team Lead в Amiga. Сегодня расскажем, как собираем приложения под Android.

Существует два вида собираемых файла под 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 — с темой «Перестройка процессов разработки при масштабировании агентства».

Смотрите фотки и ставьте 🔥, если ждете записи докладов!
🔥18👏2🤩1