Flutter Friendly – Telegram
Flutter Friendly
1.04K subscribers
165 photos
71 videos
1 file
145 links
Канал Friflex о разработке на Flutter. Обновления, плагины, полезные материалы — превращаем знания в реальный опыт, доступный каждому разработчику.

🔗 Наш канал для разработчиков: @friflex_dev
🔗 Канал о продуктовой разработке: @friflex_product
Download Telegram
Media is too big
VIEW IN TELEGRAM
Юра, Tech Lead Flutter-команды Friflex, вновь на связи!

Как установить Aurora SDK, я уже рассказал. Переходим к настройке эмулятора для Flutter. Просто, как дважды с два, с этой видеоинструкцией🖱
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥4👍2🤩1
Какой канал про Flutter без рубрики #пакет_недели, подумали мы, и вот первый выпуск!

Сегодня рассказываем про Skeletonizer. Этот пакет позволяет создавать скелетоны — упрощенные версии интерфейса, которые пользователь видит, пока контент загружается.

Главное про Skeletonizer:

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

🔸Он поддерживает кастомизацию. Skeletonizer позволяет настроить анимацию, цвет и форму скелетона.

🔸Его легко интегрировать. Можно просто обернуть виджет в Skeletonizer и сразу получить эффект анимации.

🔸Он поддерживает большинство стандартных виджетов. Например, Container, Text, или ListView.

Как использовать

Создадим анимацию загрузки для карточки профиля:
import 'package:flutter/material.dart';
import 'package:skeletonizer/skeletonizer.dart';

class ProfileSkeletonDemo extends StatelessWidget {
final bool isLoading = true;

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(noscript: Text('Skeleton Profile Example')),
body: Center(
child: Skeletonizer(
enabled: isLoading,
child: Card(
child: ListTile(
leading: CircleAvatar(radius: 30),
noscript: Text('John Doe'),
subnoscript: Text('Flutter Developer'),
),
),
),
),
);
}
}

void main() => runApp(MaterialApp(home: ProfileSkeletonDemo()));


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

backgroundColor: задает основной цвет скелетона.
highlightColor: задает цвет блика.
duration: продолжительность одного цикла анимации.
borderRadius: радиус закругления углов.

Например:
Skeletonizer(
enabled: true,
duration: Duration(seconds: 1), // Продолжительность анимации
backgroundColor: Colors.grey[200], // Цвет фона скелетона
highlightColor: Colors.grey[100], // Цвет анимированной заливки
child: YourWidget(),
);


Режим скелетона можно включать и выключать в зависимости от состояния загрузки данных:
Skeletonizer(
enabled: isLoading, // Условие включения скелетона
child: isLoading ? Placeholder() : ContentWidget(),
);


❗️Если виджетов много, Skeletonizer может привести к проблемам с производительностью, особенно на слабых устройствах.

🔥— попробуем красивые скелеты Skeletonizer
🙅— вставим из старых проектов
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍3🤩2
Привет, это Анна, Team Lead Flutter-команды Friflex

Я уже рассказала, как подключить библиотеку yandex_mapkit, чтобы внедрить карту в мобильное приложение, и как создать список точек, которые будут отображаться маркерами на карте.

Библиотека yandex_mapkit предлагает виджет карты, YandexMap, и разные инструменты для работы с ней. Сегодня покажу, как отобразить карту и добавить маркеры объектов на нее.

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

1️⃣ nightModeEnabled включает темную тему
2️⃣ zoomGesturesEnabled разрешает масштабировать карту
3️⃣ onCameraPositionChanged обрабатывает перемещения положения карты
4️⃣ onUserLocationAdded позволяет получить местоположение пользователя

Чтобы отобразить маркеры объектов на карте, нужно передать их список в поле mapObjects виджета YandexMap.

 YandexMap(
mapObjects: mapObjects,
zoomGesturesEnabled: true,
nightModeEnabled: true,
onMapCreated: (controller) {
// действие при создании карты
},
onCameraPositionChanged: (cameraPosition, reason, finished) {
// действие при изменении положения камеры
},
onUserLocationAdded: (view) {
// действие при определении местоположения пользователя средствами Яндекс карты
},
),


Готово! В следующий раз рассмотрим, как и зачем использовать кластеризацию объектов.

#howtoflutter
Please open Telegram to view this post
VIEW IN TELEGRAM
5🔥3👍2
Media is too big
VIEW IN TELEGRAM
Переходим к установке и настройке Aurora-CLI

На связи Юра, Tech Lead Flutter-команды Friflex, с подробной инструкцией, как это сделать.

📎Как установить Aurora SDK
📎Как настроить эмулятор для Flutter
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥53
Наш словарь: фича, легаси, костыль, песочница, ветка, ревью.

Наш стартер-пак: 🖱

Что бы еще добавили?
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥63👍3
Привет, это Анна, Team Lead Flutter-команды Friflex

Это четвертый пост из серии о том, как интегрировать карты в мобильные приложения. В прошлый раз я рассказывала, как отобразить маркеры объектов на карте. Сегодня поговорим про кластеризацию объектов.

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

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

Для реализации кластеризации в yandex_mapkit существует специальный класс — ClusterizedPlacemarkCollection. У него есть обязательные параметры:

🔴mapId — уникальный идентификатор объекта

🔴placemarks — список маркеров, которые в случае изменения масштаба объединяются в кластеры

🔴radius — минимальное расстояние между точками на карте, которые остаются разделенными и не входят в кластеры

🔴minZoom — минимальный уровень масштабирования, при котором отображаются кластеры

Изменить внешний вид кластера можно через обратный вызов onClusterAdded(). Он вызывается каждый раз, когда после изменения масштаба карты создаются новые кластеры или удаляются старые.

Cluster — объект кластера, который хранит в себе данные об объединенных маркерах, их количестве и своем внешнем виде.

Класс Cluster реализует метод copyWith(), который обеспечивает иммутабельность текущему объекту кластера. С помощью этого метода можно вернуть новый экземпляр класса. От текущего он будет отличаться параметрами, которые заданы в copyWith().

Чтобы изменить внешний вид в onClusterAdded(), нужно вернуть экземпляр Cluster с измененным через copyWith() параметром appearance.

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

Чтобы отобразить маркеры с кластеризацией на карте, объект ClusterizedPlacemarkCollection нужно передать в поле mapObjects виджета YandexMap.

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

#howtoflutter
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥83👍2
Media is too big
VIEW IN TELEGRAM
Продолжаем устанавливать Flutter Aurora вместе с Юрой, Tech Lead Flutter-команды Friflex.

📎Как установить Aurora SDK
📎Как настроить эмулятор для Flutter
📎Как установить и настроить Aurora-CLI
Please open Telegram to view this post
VIEW IN TELEGRAM
5🔥5👍3👎1
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
6🔥3👍1😁1🤣1
Привет, это Анна, Team Lead Flutter-команды Friflex

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

Библиотека yandex_mapkit предлагает такую возможность при помощи метода setMapStyle у контроллера карты YandexMapController. Метод принимает строку json-массива с заданными параметрами стилей карты.

Каждый вложенный json в массиве должен формироваться по ключам:
🔸 tags — набор тегов объектов
🔸 types — типы объектов, к которым должны применяться стили, например, линии, точки, зоны
🔸 elements — составляющие объекта, например, подпись объекта, иконка или текст, и его область
🔸 stylers — параметры стиля объекта, например, видимость, цвет, размер

Чтобы получить нужный стиль, комбинируйте параметры объектов. Например, можно скрыть все объекты торговли и общественного питания и подсветить названия дорог красным цветом.
await mapController.setMapStyle('''
[
{
"tags": {
"any": ["shopping", "food_and_drink"]
},
"stylers": {
"visibility": "off"
}
},
{
"tags": {
"all": ["road"]
},
"elements": ["label.text"],
"stylers": {
"color": "0xFF5757"
}
}
]
''');

Больше параметров стилизации описано в документации.

В следующий раз разберем, как построить пешеходный маршрут от точки А до точки Б и отобразить его на карте.

#howtoflutter
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍53
#пакет_неделиin_app_review. Он помогает показывать окошки с просьбой поставить оценку или написать отзыв.

Главное про in_app_review

🔸Он вызывает нативные окна запроса отзывов и оценок. Окна появляются прямо в приложении и не нарушают пользовательский опыт.

🔸Разработчик отправляет запрос на показ окна для оценки, но все решает система. Она учитывает разные факторы, такие как частота предыдущих запросов или активность пользователя. Гарантии, что окно покажут, нет.

Например
import 'package:in_app_review/in_app_review.dart';

class MyApp extends StatelessWidget {
final InAppReview inAppReview = InAppReview.instance;

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
noscript: Text('In-App Review Example'),
),
body: Center(
child: ElevatedButton(
onPressed: () async {
if (await inAppReview.isAvailable()) {
inAppReview.requestReview();
} else {
print("In-App Review is not available");
}
},
child: Text('Rate App'),
),
),
),
);
}
}


Как работает этот код
1. Импорт библиотеки и создание экземпляра.

2. В интерфейсе приложения создается кнопка (через ElevatedButton), на которую можно нажать, чтобы запросить у пользователя оценку.

3. Когда пользователь нажимает кнопку Rate App, приложение проверяет, доступно ли окно с запросом оценки через функцию isAvailable().

4. Если да, вызывается метод requestReview(), который открывает окно с предложением поставить оценку.

5. Если нет, приложение выводит сообщение в консоль, что запрос оценки сейчас недоступен.

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

🔥 — классный пакет
🙅 — моему приложению и так оставляют отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍2💯21🆒1
Привет, это Анна, Team Lead Flutter-команды Friflex

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

Чтобы построить маршрут, добавим точки его начала и конца:
static const startPoint = Point(latitude: 55.745797, longitude: 37.605862);
static const endPoint = Point(latitude: 55.752754, longitude: 37.604188);


Библиотека yandex_mapkit предоставляет доступ к классу YandexPedestrian. Его асинхронный метод requestRoutes позволяет получить список возможных пешеходных маршрутов между заданными точками.

Поле points принимает набор точек RequestPoint, которые должны быть включены в маршрут. Начальную и конечную точку необходимо помечать типом RequestPointType.wayPoint.

Помимо этих двух точек можно добавить несколько промежуточных, тогда маршрут будет построен с учетом их посещения. Им следует задавать тип RequestPointType.viaPoint.

Кроме того, можно задать временные параметры timeOptions, такие как время отправления и время прибытия. Также метод принимает параметр avoidSteep, который отвечает за исключение крутых поворотов на пути.
var resultWithSession = await YandexPedestrian.requestRoutes(
timeOptions: TimeOptions(departureTime: DateTime.now()),
avoidSteep: true,
points: [
RequestPoint(
point: startPoint,
requestPointType: RequestPointType.wayPoint,
),
RequestPoint(
point: endPoint,
requestPointType: RequestPointType.wayPoint,
),
]);


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

#howtoflutter
5🔥3👍2
This media is not supported in your browser
VIEW IN TELEGRAM
#пакет_недели — flutter_barcode_scanner. Он позволяет интегрировать сканирование штрихкодов и QR-кодов в кроссплатформенные приложения.

Главное о flutter_barcode_scanner
🔴Поддерживает штрихкоды (UPC,EAN, Code128) и QR-коды

🔴Позволяет настраивать цвет подсветки для области сканирования и текст для кнопки отмены

🔴Сканирование работает локально и не требует подключения к интернету

Как использовать
Запускаем сканирование штрихкодов с помощью метода scanBarcode:
String barcodeScanRes = await FlutterBarcodeScanner.scanBarcode(
COLOR_CODE,
CANCEL_BUTTON_TEXT,
isShowFlashIcon,
scanMode);


🔸COLOR_CODE — задает цвет линии в интерфейсе сканирования. Можно передать любой цвет по вашему выбору в формате hex.

🔸CANCEL_BUTTON_TEXT — текст для кнопки отмены на экране. Вы можете задать любой текст на любом языке.

🔸isShowFlashIcon — булевое значение (true/false). Оно позволяет отображать или скрывать иконки вспышки.

🔸scanMode — перечисление, в котором можно передать одно из значений: QR, BARCODE, или DEFAULT. По умолчанию scanMode использует QR.

На Android ничего дополнительно делать не нужно, а на iOS требуется поддержка Swift и добавить описание использования камеры в файл Info.plist.

🔥 — классный пакет, обязательно попробую
🔧 — предпочитаю собственное решение
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9
This media is not supported in your browser
VIEW IN TELEGRAM
Привет, это Екатерина. Я Flutter-разработчик в команде Friflex.

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

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

Кажется, что было бы здорово использовать его в проекте. Добавляем следующие зависимости в pubspec:
dependencies:
flutter:
sdk: flutter

# Для получения данных о погоде
http: ^1.2.2
# Для иконок погоды
weather_icons: ^3.0.0


Теперь с пакетом иконок нам не нужно самостоятельно добавлять ассеты для разных состояний погоды. Кажется, что мы освободили себя от значительного объема работы. Вот только:

🔴Библиотека содержит в себе более 200 ассетов, когда нам нужны условные 15

🔴Она, неожиданно, усложняет онбординг новых разработчиков, потому что с ней никто раньше не сталкивался

🔴Пакет обновлялся в последний раз больше года назад, а это всегда риск остановки поддержки библиотеки и последующего рефакторинга приложения

Как быть?
Свести зависимость от чужих решений в проекте к минимуму. Особенно если речь идет о решении небольших задач, которые можно сделать самостоятельно.

В нашем примере можно убрать библиотеку для иконок и добавить ассеты в проект в том количестве, в котором они нужны именно в нем.
dependencies:
flutter:
sdk: flutter
# Для получения данных о погоде
http: ^1.2.2

flutter:
assets:
- assets/icons/


Итог: подстраиваем инструменты под приложение, а не создаем приложение под инструменты.

💬 Делитесь, какие паттерны в разработке на Flutter — личная боль?
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍5👏2