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

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

Hola, Amigos! Completer — это вспомогательный класс, который позволяет нам создавать Future объекты. Как вы знаете, Future — это тип данных, который представляет собой результат асинхронной операции. Все асинхронные функции в Flutter возвращают Future и позволяют вам работать с результатами операции, когда они становятся доступными.

Completer приходит на помощь, когда вы хотите создать собственную синхронную функцию, которая также возвращает Future. Это может быть полезно, когда вам необходимо выполнить какие-то операции внутри функции и предоставить результат для будущего использования.

Примеры создания Completer объектов:

final stringCompleter = Completer<String>();
final voidCompleter = Completer<void>();
final dynamicCompleter = Completer();
final nullableStringCompleter = Completer<String?>();


Completer используется для представления значения будущему объекту и для запуска всех ожидающих обратных вызовов. Вы можете завершить Completer, как показано ниже:

stringCompleter.complete('foo');

Или, если вы хотите получить результат из функции обратного вызова, вы можете использовать его future свойство:

final valueFuture = stringCompleter.future;
final value = await valueFuture;


Также, Completer предоставляет метод isCompleted, который позволяет вам узнать, завершился ли Completer:

final isCompleted = stringCompleter.isCompleted;

⚠️ Важно помнить, что Completer — это односторонний процесс, и его нельзя перезапустить после завершения.

Рассмотрим работу и использование Completer на двух примерах.

1️⃣ Пример

Нам нужно получить значения переменной из функции обратного вызова.

См. скриншот 1: мы имитируем асинхронную операцию и желанием получить значение переменной time, но как нам это сделать вне функции?

См. скриншот 2: на помощь приходит Completer, благодаря которому мы можем получить значение переменной вне зоны видимости функции обратного вызова после завершения асинхронной операции:

final valueFuture = stringCompleter.future;
final value = await valueFuture;


2️⃣ Пример

Если вам доводилось разрабатывать клиент-серверные приложения, то вы, скорее всего, сталкивались с проблемой отправки нескольких запросов. Например, при авторизации в системе пользователю требуется заполнить поля логина и пароля, затем отправить запрос на сервер тапом на кнопку «Войти». Но что, если пользователь нажмёт на неё более 1 раза? В данном случае на сервер пойдут конкурентные запросы, что не является хорошей практикой.

См. скриншот 3: эту проблему можно решить как на стороне Flutter, используя Debouncer, но это также решает Completer с помощью вышеупомянутого. Мы дополним пример выше и имитируем несколько нажатий пользователем с помощью цикла for. Добавив условие управления Future, в котором мы проверяем закончил ли Completer свою работу, мы выходим из цикла и получаем нужное нам значение единожды.

Таким образом, Completer можно использовать как своеобразную защиту от дублирующих запросов на сервер или создания пользователем дублирующих асинхронных операций.

Успешной вам разработки! Отправляйте реакцию, если было полезно😉
Please open Telegram to view this post
VIEW IN TELEGRAM
Камера и Flutter

Hola, Amigos! На связи Александр Чаплыгин, Flutter-dev в Amiga. Недавно я выступал на конференции для разработчиков DevFest в Омске с докладом «Камера и Flutter». Решил поделиться с вами впечатлениями о своем первом выступлении и для тех, кого не было на конференции, рассказать про проект, в котором использовалась библиотека Google ML Kit Barcode Scanning.

Переходите по ссылке, там все подробности⬆️ Обязательно дайте знать в комментариях, понравилась ли вам статья!
Please open Telegram to view this post
VIEW IN TELEGRAM
Пакет geolocator

Hola, Amigos! Сегодня мы поговорим о пакете geolocator, который поможет вам интегрировать геолокацию в ваши Flutter приложения. Эта функция полезна различным приложениям и бизнесам, которые зависят от геолокации или могут использовать ее в своих преимуществах: доставка, соцсети и знакомства, логистика, медицина др.

Что такое geolocator?
geolocator позволяет получать информацию о текущем местоположении, следить за изменениями координат, а также определять расстояния между точками.

Пример использования
1️⃣ Добавьте зависимость: Сначала добавьте geolocator в файл pubspec.yaml вашего проекта.

dependencies:
geolocator: ^7.7.0


2️⃣ Импортируйте пакет:

import 'package:geolocator/geolocator.dart';

3️⃣ Используйте geolocator:

// Инициализируем Geolocator
final geolocator = Geolocator();

// Получаем текущее местоположение
Position position = await geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);

// Используем полученные данные
print('Широта: ${position.latitude}, Долгота: ${position.longitude}');


Готово!⚙️

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

А пока делитесь в комментариях, кто уже использовал в своих приложениях пакет geolocator. Расскажите, что это был за проект? Нам интересно узнать, о вашем опыте ⚙️
Please open Telegram to view this post
VIEW IN TELEGRAM
Запрос разрешений

Hola, Amigos! В посте выше мы делали обзор пакета geolocator. Сегодня уделим внимание пользовательскому разрешению для доступа к геолокации, ведь без него использование пакета невозможно.

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

На платформе Android вам потребуется запросить следующие разрешения:

🟡ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION: Эти разрешения используются для получения точного местоположения на устройстве.
🟡INTERNET: Для доступа к сети, например, для получения данных о местоположении с использованием GPS.
🟡ACCESS_BACKGROUND_LOCATION: Если ваше приложение должно иметь доступ к местоположению в фоновом режиме.

На iOS разрешения работают следующим образом:

🔵NSLocationWhenInUseUsageDescription: Разрешение на использование местоположения, когда приложение активно.
🔵NSLocationAlwaysUsageDescription: Разрешение на использование местоположения даже в фоновом режиме.
🔵NSLocationAlwaysAndWhenInUseUsageDescription: Разрешение на использование местоположения и в активном, и в фоновом режиме.

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

При работе с разрешениями в Flutter, вы также можете использовать пакет permission_handler, чтобы упростить процесс запроса и проверки разрешений на разных платформах.

Разрабатывайте приложения с заботой о пользователях ⚙️

Поделитесь в комментариях, над каким проектом работаете сейчас? Мы вот ковыряемся в ecom проекте, победили наконец-то видеоплеер. Но это уже совсем другая история…
Please open Telegram to view this post
VIEW IN TELEGRAM
Подход к легаси проектам

Hola, Amigos! Нам часто приходится сталкиваться с легаси проектами. Это настоящая боль проблема, когда нужно:

🟡несколько версий Flutter SDK на одной машине.
🟡«потрогать» (Beta channel) версии Flutter.
🟡проверить гипотезу на другой версии Flutter SDK.
🟡разрабатывать пару проектор на разных версиях Flutter SDK.
🟡проверить работу проекта на новой версии Flutter SDK.
🟡и т.д.

Есть путь самурая, т.е. устанавливать разные версии Flutter SDK и как-то ими «жонглировать».

Есть путь рабочего человека, т.е. использовать решение Flutter Version Management (FVM).

Рекомендуем воспользоваться последним.

Из плюсов:
1️⃣ быстрая установка.
2️⃣ легко переключаться между версиями Flutter SDK — fvm use 3.13.6
3️⃣ легко установить нужную версию Flutter SDK — fvm install 3.7.12

Всем удачного кода! Делитесь в комментариях своими лайфхаками работы с проектами, которые достались вам по наследству от других разработчиков.
Please open Telegram to view this post
VIEW IN TELEGRAM
Sliver во Flutter

Hola, Amigos! Sliver — мощный инструмент для настройки и создания эффектов прокрутки в вашем приложении Flutter. Он идеально подходит для обработки множества дочерних виджетов, которые могут меняться при прокрутке.

Разновидности Sliver:

➡️ SliverAppBar: Плавающий или изменяющийся при прокрутке заголовок.
➡️ SliverList: Список элементов в прокручиваемой области.
➡️ SliverGrid: Элементы в 2D-сетке.
➡️ SliverPersistentHeader: Фиксированный заголовок при прокрутке.
➡️ SliverFixedExtentList: Фиксированный список элементов с одинаковой высотой.

Перед использование Sliver нужно ознакомиться с CustomScrollView. Это виджет типа ScrollView, который позволяет создавать различные эффекты прокрутки: сетка, списки и др. Он имеет свойство sliver, которое принимает список виджетов:

CustomScrollView(slivers: [
SliverAppBar(...),
SliverPadding(...),
SliverList(...),
SliverGrid(...),
]


Типичные сценарии реализации Slivers:

🔴Плавающий заголовок с изменением цвета и размера при прокрутке.
🔴Прокрутка списка или сетки элементов.
🔴Прокрутка списка с фиксированным заголовком.

Для немедленного отображения списка элементов мы используем SliverChildDelegate, тогда как для отложенной загрузки itemListSliverChildBuilderDelegate.

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

В следующем посте расскажем, как работать с гридами. Ставьте реакцию, если ждете!
Please open Telegram to view this post
VIEW IN TELEGRAM
Responsive_framework

Hola, Amigos! На связи Ярослав Цемко, Flutter-разработчик Amiga. Рад со всеми познакомиться и поделиться своей первой статьей на Habr, в которой я рассказал о крутом плагине Responsive_framework в контексте одного из наших проектов ⚙️

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

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

Буду рад вашим комментариям! И если у кого-то из наших подписчиков есть инвайт на Habr, то напишите, пожалуйста, нашей амиговке Арине @arina_na_na ⚙️
Please open Telegram to view this post
VIEW IN TELEGRAM
SliverGrid: Как работать с Гридами

Hola, Amigos! SliverGrid — это инструмент для создания двумерных массивов элементов для прокрутки и отображения данных.

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

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

🦋 Конструктор-счетчик: Используется для указания количества элементов на горизонтальной оси. Это позволяет контролировать, сколько элементов помещается в строке.

SliverGrid.count(
children: scrollItems, // Ваши элементы
crossAxisCount: 3, // Количество элементов в строке
)


🦋 Конструктор экстента: Позволяет указать максимальную ширину элементов, чтобы определить, сколько элементов должно поместиться в сетке.

SliverGrid.extent(
children: scrollItems, // Ваши элементы
maxCrossAxisExtent: 75.0, // Максимальная ширина элемента
)


🦋 Конструктор по умолчанию: Этот конструктор принимает дополнительный параметр gridDelegate. Данный параметр принимает класс SliverGridDelegateWithFixedCrossAxisCount, который, помогает зафиксировать количество элементов на горизонтальной оси.

SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, // Количество элементов в строке
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return scrollItem(); // Вставьте сюда свой виджет
}
)
)

С SliverGrid в вашем арсенале Flutter вы сможете легко и красочно оживить свой интерфейс сеток. Успехов в разработке!

Ставьте реакцию, если было полезно ⚙️ В следующем посте расскажем про динамические Slivers.
Please open Telegram to view this post
VIEW IN TELEGRAM
Динамические Slivers

Hola, Amigos! После того, как мы изучили фундаментальные примеры Slivers, давайте перейдем к более продвинутым функциям и посмотрим на Slivers в действии ⚙️

Чтобы сделать прокрутку более отзывчивой и адаптивной к действиям пользователей, рассмотрим возможность использования «динамических» Slivers — SliverFillViewport.

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

CustomScrollView(
slivers: [
SliverFillViewport(
delegate: SliverChildListDelegate(
[
Container(color: Colors.red, height: 150.0),
Container(color: Colors.purple, height: 150.0),
Container(color: Colors.green, height: 150.0),
]
),
viewportFraction: 0.3
),
]
)


SliverFillViewport использует свойство viewportFraction, чтобы определить, какую часть экрана каждый дочерний виджет будет заполнять. В приведенном выше коде каждый виджет будет заполнять треть (0,3) экрана.

Slivers легко настраиваются, это качество распространяется и на их дочек. Такие виджеты как SliverChildBuilderDelegate и SliverChildListDelegate могут присваивать уникальные идентификаторы каждому дочернему элементу, что открывает двери для креативных анимаций и переходов ⚙️

Успехов в разработке! Пишите в комментариях о вашем опыте использования Slivers в проектах.
Please open Telegram to view this post
VIEW IN TELEGRAM
Обзор пакета flutter_blue_plus

Hola, Amigos! Сегодня начнем с вами рассматривать многогранную тему Bluetooth во Flutter.

Один из самых популярных пакетов flutter_blue_plus позволяет сканировать устройства и устанавливать с ними соединение благодаря Bluetooth Low Energy (BLE).

⚙️ Важно: перед использованием убедитесь, что вы попросили пользователя предоставить разрешение на использование Bluetooth (пакет permission_handler).

Давайте рассмотрим основные возможности пакета.

Сканирование Bluetooth-устройств:

FlutterBluePlus flutterBlue = FlutterBluePlus.instance;
// прослушиваем найденные девайсы
flutterBlue.scanResults.listen((results){
// производим действия с найденными устройствами
});


Подключение к устройствам:

После обнаружения устройств можно установить с ними соединение.

void connectToDevice(BluetoothDevice device) async{
await device.connect();
}


Получение списка услуг от устройства:

Каждое Bluetooth-устройство предоставляет список услуг, которые оно поддерживает. Чтобы получить этот список, используйте:

final services await device.discoverServices();


Характеристики BLE-устройств:

Каждая услуга на BLE-устройствах содержит набор характеристик, которые используются для взаимодействия с устройством. Например, у сервиса Generic Access Service есть характеристики, такие как имя устройства и MAC-адрес:

for(var service in services){
List<BlueToothCharacterictic> characteristics = service.characteristics;
}


Считывание характеристик в устройствах BLE:

Для считывания данных с Bluetooth-устройства используйте метод read(), обязательно используйте await, так как read() асинхронный.

BlueToothCharacterictic characteristics;
List<int> value = await characteristics.read();
print(value.toString());


Запись характеристик в устройства BLE:

Для отправки данных на устройства BLE используйте метод write(), также обязательно используйте await. Перед отправкой нужно подготовить данные в виде списка целых чисел. После выполнения операции записи, можно прослушивать уведомления, подтверждающие, что запись прошла успешно.

List<int> dataToSend = [0x01,0x02,0x03];
await characteristics.write(dataToSend);


С Bluetooth во Flutter множество подводных камней. Ставьте реакцию, если тема инересна! И делитесь в чате разработчиков своим опытом, вместе обсудим ⚙️
Please open Telegram to view this post
VIEW IN TELEGRAM
Заметки мобильного разработчика

Hola, Amigos! Меня зовут Вова Зевеке, я Flutter-разработчик в Amiga. Недавно мы тут с ребятами вскользь упомянули e-com проект, в котором «победили видеоплеер». Я решил немного подробнее поделиться с вами этой историей ⚙️

Перед нами стояла задача — интегрировать видеоплеер в приложение, чтобы смотреть видео с YouTube. Мы подключили пакет youtube_player_flutter, и кажется, задача решена.

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

Мы переключили у контроллера видеоплеера флаг «autoPlay» в состояние «true». Видео перестало буферизоваться, и время ожидания загрузки видео сильно уменьшилось. Однако возникла новая проблема: с включенным флагом «autoPlay» видео нельзя ни промотать, ни поставить на паузу, можно только переключать полноэкранный режим.

Казалось, это тупик, ограничения пакета не позволяли решить задачу. Начали копаться в пакете и обнаружили, что у контроллера при включенном «autoPlay» остаётся возможность воздействовать на поле controller.value. Сделав отдельный метод, который ставил контроллеру настройки playerState: PlayerState.paused, isPlaying: false, нам удалось добиться возможности ставить видео на паузу даже с включенным «autoPlay». Но редактировать плеерную кнопку «играть/пауза» мы всё ещё не могли, поэтому сделали свою.

Позже мы столкнулись с проблемой проматывания видео. Воспользовались тем, что у контроллера можно задавать флаг «startAt». Он определяет, с какого момента видео начинает проигрываться. На основе этого сделали метод, который пересоздает плеер с новой точкой старта видео при попытке проматывания видео.

В итоге постепенно мы заменили весь интерфейс видеоплеера своим, спрятав старый. Получился всё тот же плеер, что и дефолтный YoutubePlayer, но с куда меньшей задержкой загрузки видео. Вынесли все изменения в форк репозитория пакета.

Пишите в чате, интересны ли вам такие истории из практики? Стоит ли продолжать? Если у вас есть релевантный опыт, будем рады обсудить ⬆️
Please open Telegram to view this post
VIEW IN TELEGRAM
Отличие Flutter Isolates и Compute

Hola, Amigos! Перед тем, как перейти к основной теме, освежим знания. Вместо потоков весь код в Dart выполняется внутри изолятов. Каждый изолят обладает собственной кучей памяти, что гарантирует изоляцию состояния между ними. Изоляты позволяют выполнять ресурсоемкие задачи: сложные вычисления, обработка изображений или синтаксический анализ данных в фоновом режиме.

⚠️ Важно помнить, что изоляты взаимодействуют между собой посредством передачи сообщений с использованием SendPort и ReceivePort.

Для создания изолята мы используем .spawn():

// создаем изолят
Isolate isolate = await Isolate.spawn(ownFunction, 'Created');
// отправляем сообщение изоляту
isolate.sendPort.send('From main isolate');
// получаем сообщение из изолята
ReceivePort receivePort = ReceivePort();
isolate.addOnExitListener(receivePort.sendPort);
receivePort.listen((dynamic message) {
print('Received message in main isolate: $message');
});


Flutter Compute — это простая альтернатива изолятам, предназначенная для выполнения ресурсоемких вычислительных задач в отдельном потоке в пределах одного изолята. Одним из преимуществ Compute является автоматическое создание изолята для выполнения функции параллельно с пользовательским интерфейсом.

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

Future<int> computeFunction(int value) {
return compute(_ownFunction, value);
}


Используйте Flutter Isolates и Flutter Compute, чтобы повысить производительность и скорость отклика в приложении Flutter ⚙️

Удачи в разработке! Оставляйте реакцию, если было полезно ⚙️
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Что такое shimmer?

Hola, Amigos! На связи Ярослав Цемко, Flutter dev Amiga. Сегодня затрону тему shimmer, так как работал над ним недавно в нашем проекте Bravo.

Shimmer — это анимация загружающихся элементов. Она нужна во время ожидания загрузки контента в мобильном приложении. Чаще всего вы, наверное, встречаете в таких случаях вращающийся кружок. Так вот shimmer является его альтернативой.

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

Анимацию можно использовать при загрузке:

⭕️изображений;
⭕️элементов типа Card, ListTile;
⭕️текста;
⭕️и любых других элементов, благо есть возможность его тонкой настройки.

Реализацию shimmer можно посмотреть здесь.

В следующем посте расскажу, как я настроил этот виджет на нашем проекте и с какими сложностями столкнулся. Ставьте реакцию, если ждете и делитесь своим опытом в чате!
Please open Telegram to view this post
VIEW IN TELEGRAM
Анимация загрузки картинок во Flutter

Hola, Amigos! Как и обещали, делимся с вами туториалом, как настроить shimmer в мобильном приложении. Опыт нашего Flutter dev, Ярослава Цемко в проекте Bravo.

Ловите статью на Habr и ставьте ⬆️ на карму🥰
Please open Telegram to view this post
VIEW IN TELEGRAM
Интеграция Flutter в Native iOS (Часть 1)

Hola, Amigos! На связи Саша Чаплыгин, Flutter dev компании заказной разработки Amiga. Нашел интересную статью, решил поделиться с вами переводом. Автор материала рассказывает, как добавить Flutter в новый или существующий проект Native iOS и протестировать его на Codemagic ⚙️

Всю статью пришлось разделить на 3 части для упрощения восприятия, поэтому сегодня мы рассмотрим создание приложения на iOS и интеграцию Flutter в это приложение.

Вторая часть посвящена реализации экрана Flutter в приложение для iOS и использованию platform channel для отправки данных из Native во Flutter.

И третья часть будет про использование «Hot Reload», «Hot Restart» и тестирование на Codemagic.

Читайте первую статью по ссылке на Habr. Пишите комментарии и ставьте реакции, если было интересно и ждете продолжения! ⚙️
Please open Telegram to view this post
VIEW IN TELEGRAM
Channel photo updated