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

Новости Flutter-разработки, дайджесты мероприятий, личный опыт.
Download Telegram
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. Продолжаем разбираться с Flavors. Сегодня посмотрим, как это делать в iOS.

Нам нужно сделать несколько шагов:

1) Создать копию Target у приложения.

2) Переименовать все схемы запуска через Runner -> Manage Schemes.

3) Дублировать конфигурации в проекте и переименовать их.

После этого мы сможем менять Bundle ID, логотип, название приложения и многое другое.

Смотрите в карточках, как это делается, и делитесь в чате, пробовали так на своих проектах?
👍13🔥3👏2
Hola, Amigos! На связи Михаил Чернецов, Flutter Dev в Amiga. Сегодня мы расскажем о возможности импортов во Flutter.

Классы для экспорта

Часто случается, когда при импорте нескольких файлов из одной папки увеличивается количество строк:

import “class_a.dart”;
import “class_b.dart”;
import “class_c.dart”;
import “class_d.dart”;


Вместо этого мы можем создать в этой же папке специальный файл для экспорта. Например, my_imports.dart. После чего внесем наши файлы с ключевым словом export в начале:

export “class_a.dart”;
export “class_b.dart”;
export “class_c.dart”;
export “class_d.dart”;


Теперь подключение будет занимать всего одну строку:

import “my_imports.dart”;


Еще одна возможность, которая появляется — использовать любой класс из тех, что мы экспортировали, без необходимости импортировать их еще раз.

Ключевые слова as, hide и show

Наверное, вы уже видели такую запись:

import “dart:math” as math;


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

Допустим, у нас в 2 пакетах есть класс MyClass, и нам нужно использовать оба. В таком случае мы можем добавить ключевое слово as к импортам и использовать их вместе:

import 'my_package.dart' as package1;
import 'other_package.dart' as package2;

package1.MyClass();
package2.MyClass();


Также этот способ подходит, если в пакете присутствуют методы, и вы хотите знать, что они оттуда. Например, это используется при работе с пакетами math, http и dio.

Есть еще 2 ключевых слова, которые позволяют изолировать видимость классов, методов, переменных, расширений и миксинов из импортов:

1. hide. Скрывает, что нам не понадобится. Например, если нам не нужен какой-то определенный класс или его имя дублируется.

2. show. Отображает только то, что нам необходимо. Это позволяет нам использовать что-то определенное, без доступа к остальному.

import “my_model.dart” hide ModelA;
import “my_sevice.dart” show MyService;


Пишите в чате, как вы организовываете импорты на своих проектах?
7👏6🔥4👍2
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. Мы уже поговорили про импорты, но вы подсказали, что есть еще пару лайфхаков, связанных с ними.

Механизм Part Of

Все наши файлы на Dart это небольшие библиотеки, но иногда они становятся настолько большими, что их хочется поделить. В этом случае можно применить ключевые слова part и part of.

Этот механизм часто используется библиотеками для генерации кода. Думаю, вы видели файлы my_class.g.dart, если такими пользуетесь.

Давайте рассмотрим как работать с данным механизмом на примере BLoC. У нас есть файл my_bloc.dart, который будет основным, и файлы my_event.dart и my_state.dart, которые будут его частями.

В my_bloc.dart мы пропишем:

part ‘my_event.dart’;
part ‘my_state.dart;


И уже в файлах-частях вместо импортов будет строчка:

part of ‘my_bloc.dart’;


Таким образом эти 3 файла будут распознаваться как один и тем самым импорты мы можем писать только в my_bloc.dart, и он же будет импортироваться в другие файлы.

Part of имеет смысл применять, только если это неотделимые друг от друга классы. Например, события и состояния для BLoC или обработка JSON для моделей, в остальных случаях лучше использовать export.

Выбор импорта в зависимости от условий

Допустим, вы делаете приложение и на мобильные платформы, и на веб, но некоторые импорты нужно менять в зависимости от платформы. Это бывает при использовании dart:io и dart:web Тут к нам на выход приходит использование if.

Для этого нужно будет подготовить 3 файла — один под МП, второй под веб, третий если ни один из них не подходит. И создать третий файл для экспорта:

export ‘my_none.dart’
if (dart.library.io) ‘my_mobile.dart’
if (dart.library.js_interop) ‘my_web.dart’;


Импортируя уже этот файл, мы точно получим нужный нам инстанс, который будет работать.

Делитесь в чате, пробовали ли вы использовать эти 2 механики на своих проектах? И пишите, что еще хотели бы узнать, а мы соберем информацию об этом❤️
👍11🔥42
Дайджест ноября

Hola, Amigos! Собрали в одну подборку все полезные посты ноября, которые вы могли пропустить. Выбирайте, что вам интересно, и переходите по ссылкам.

⚪️ Chopper

⚪️ Retrofit

⚪️ Chopper или Retrofit

⚪️ 3 способа хранения ключей и различных переменных

⚪️ Flavors во Flutter. Android. iOS

⚪️ Команда Flutter. Михаил Чернецов

⚪️ Импорты во Flutter

⚪️ Лайфхаки в импортах во Flutter

Всем хорошего кода! 🙂
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥74👏3👍1
Hola, Amigos! На связи Михаил Чернецов, Flutter Dev в Amiga. Сегодня поговорим об одном из плагинов из набора plus_pluginsconnectivity_plus.

Connectivity Plus — простой плагин для проверки сети, позволяющий использовать асинхронную функцию для определения соединений. Например:

final List<ConnectivityResult> connectivityResult = await Connectivity().checkConnectivity();


Однако лучшим способом будет прослушивание потока данных и сохранение в отдельный Singleton — тогда доступ к подключениям можно получить синхронно:

Connectivity().onConnectivityChanged.listen(
(List<ConnectivityResult> result) {
MyConnectivitySingleton.instance.setValue(result);
}
);


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

AppLifecycleListener(
onShow: () async {
await MyConnectivitySingleton.instance.refresh();
},
);


А как вы работаете с изменением состояния сети? Делитесь в чате.
👍11🔥52
Hola, Amigos! Хотим поделиться с вами классной новостью. 6 декабря прошла церемония награждения премии Tagline Awards 2024 — главной награды за достижения в digital-сфере.

В премии участвует 500+ известных брендов и агентств, а награды вручаются за уровень работ, качество их исполнения и эффективность решения коммерческих задач🔥

Делимся победами! В этом году мы заняли:

🏆 2 место в номинации «Лучшее мобильное MVP-приложение» с кейсом разработки мобильного приложения для сети «Аптека Ваша №1»

🏆 3 место в номинации «Лучший маркетплейс» с кейсом создания первого маркетплейса горного оборудования в России

Спасибо команде за работу и заказчикам за доверие❤️ Такие достижения мотивируют расти и не останавливаться!

Читайте кейсы по ссылкам и пишите свое мнение в чате, мы будем рады вашему фидбеку)
🔥83👍3
Hola, Amigos! На связи мобильная команда агентства продуктовой разработки Amiga. Сегодня вышли Dart 3.6 и Flutter 3.27, но эти обновления совсем небольшие, поэтому делимся с вами в карточках самым важным:

- Обновленная работа с монорепозиториями;
- Отступы между виджетами в Row и Column;
- Разделители в больших числах
Pub.dev теперь показывает количество скачиваний пакетов;
- Много-много других небольших новинок.

Делитесь в чате, успели уже попробовать данное обновление?
🔥21❤‍🔥73
Hola, Amigos! На связи мобильная команда агентства продуктовой разработки Amiga. Вчера прошла презентация FlutterInProduction, где рассмотрели всю десятилетнюю историю нашего любимого фреймворка Flutter.

Да, мы ничего не перепутали, Flutter в этом году исполнилось 10 лет, хотя в самом начале он назывался по-другому и работал только на Android. Весь этот срок Google разделили на 3 фазы:

▫️2014-2018 — экспериментальная фаза

▫️2018-2022 — фаза роста

▫️2022-наст.время — фаза работы в продакшене

Наш Mobile Team Lead Павел Гершевич застал все 3 фазы, поэтому делимся его комментарием:

Так как я начал заниматься Flutter в конце экспериментальной фазы, могу сказать, что за это время он очень изменился.
Во-первых, он стал намного быстрее, этому помогают различные изменения внутри самого фреймворка, особенно новый движок Impeller.
Во-вторых, сообщество вокруг Flutter создает множество прекрасных и помогающих в работе библиотек и продуктов.
Думаю, что за следующие несколько лет Flutter превратится в одно из основных средств разработки под любые устройства и станет еще лучше


Кроме истории самого фреймворка и историй разработчиков, которые его используют, Google поделились некоторыми планами на наступающий 2025 год:

- Выпуск Impeller для десктопа;
- Появление Preview для виджетов, чтобы видеть верстку до запуска приложения;
- Прямой запуск нативных функций операционных систем без надобности писать Platform Channel;
- Упрощение написания виджетов при помощи добавления декораторов;
- Полный переход на Swift Package Manager для iOS.

Делитесь в чате, когда вы пришли в Flutter и как, по-вашему, он изменился с тех пор.
🔥6👍42
Hola Amigos! Мы так долго ждали и наконец можем поделиться с вами классной новостью😍

🔥Вышел свежий выпуск Flutter Dev Podcast с участием руководителя нашей команды мобильной разработки Павла Гершевича, в котором он вместе с коллегами по рынку обсудил, что нужно знать о многомодульности во Flutter.

В выпуске:

⚙️ Когда и зачем переходить на многомодульность

⚙️ Как правильно подготовить архитектуру приложения

⚙️ Какие инструменты, например Melos, помогут на этом пути

Если вы хотите сделать разработку масштабируемой и разобраться, как модули помогут упростить поддержку больших приложений, обязательно слушайте на любимой платформе:

Слушать на сайте | Яндекс.Музыка | Spotify | YouTube | Звук | Apple Podcasts | Deezer | CastBox | Overcast | Pocket Casts | Podcast Addict | VK | Саундстрим | Mave-плеер

Делитесь впечатлениями и задавайте вопросы в чате ❤️
Please open Telegram to view this post
VIEW IN TELEGRAM
75🔥5👌1
Hola, Amigos! На связи команда агентства продуктовой разработки Amiga.

Павел Гершевич, наш Mobile Team Lead написал подробную статью для тех, кто работает с BLoC. В ней вы найдете:

⚙️ Разбор встроенных трансформеров — concurrent, sequential, droppable, restartable.

⚙️ Пример создания кастомного трансформера с debounce для оптимизации работы с событиями.

⚙️ Идеи для разработки сложных трансформеров для объединения и обработки нескольких потоков событий.

Ссылка на статью на Habr ⬅️

Делитесь в чате, кто уже создавал свои трансформеры?
Please open Telegram to view this post
VIEW IN TELEGRAM
9🔥6👍5🥰2
Hola, Amigos! С наступающим Новым годом🎄

2024 год подходит к концу — быстрый, шумный и полный интересных задач и открытий! Мы вместе с вами писали тысячи строк кода и учились новому. А сейчас отличное время, чтобы сделать паузу и набраться сил для будущих свершений🥂

Желаем, чтобы в 2025 у вас все легко складывалось: код работал стабильно, проекты вдохновляли, а идеи приходили сами собой❤️

Не забывайте находить баланс, отдыхать и наполняться энергией, и до встречи в Новом году!
🎉95🔥4🎄2
Hola, Amigos! Сегодня поговорим о подходах к проектированию состояний в BLoC. В Flutter существует два основных подхода для создания состояний: single state и state machine.

📍 Single state
Это класс, содержащий все возможные поля, описывающие состояние BLoC. При изменении любого из этих полей мы создаем новое состояние, полностью обновляя текущий state.

Пример:

class MyBlocState{
final List<Todo> todos;
final bool loading;
final String? failure;

}

Использование метода emit для изменения состояния:

emit(MyBlocState.copyWith(
loading: true,
));


📍 State machine
В этом подходе каждое состояние представлено отдельным классом, унаследованным от общего родительского. Похожим способом в BLoC обычно создают события:

abstract class MyBlocState{}

class LoadingState extends MyBlocState{}
class LoadedState extends MyBlocState{
final List<Todo> todos;

}
class FailureState extends MyBlocState{
final String failure;

}


Для использования такого подхода в BLoC можно эмитить конкретные состояния:

emit(LoadingState());


Какой из этих подходов выбрать — зависит от сложности логики вашего приложения. State machine лучше подходит для сложных сценариев с разными типами состояний, тогда как single state — для простых случаев с минимальными изменениями.

Какой подход вам ближе? Пишите в комментариях!
👍95🔥5