Media is too big
VIEW IN TELEGRAM
В перерывах между докладами поймали Стаса Ильина, Lead Flutter developer и автора канала @frezycode. Поставили его перед сложным выбором — Flutter или Kotlin. Шутка… Все вопросы, конечно, были про Flutter. Ответы — в нашем ролике
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍4❤3👨💻1
This media is not supported in your browser
VIEW IN TELEGRAM
#пакет_недели — Hugeicons. Коллекция из 4000+ иконок для мобильных приложений.
Главное о пакете Hugeicons
🔸 Он предлагает иконки в разных стилях и вариантах. Например, rounded или sharp.
🔸 Он позволяет изменять цвет и размер иконок, а также анимировать их.
🔸 Он дает настраивать иконки по размеру и масштабировать их под любые экраны.
🔸 Он относительно легкий по весу. Это круто, потому что не перегружает приложение.
🔸 Иконки загружаются и компилируются вместе с приложением. Это удобно для приложений, которые работают автономно.
Как использовать
Импортируем пакет и вызываем иконку с помощью виджета HugeIcon.
❗️ Если у вас простой проект с минимальным набором иконок, Hugeincons может оказаться слишком массивным.
🔥Мне это нужно
🎨Рисую иконки в Paint с душой
Главное о пакете Hugeicons
Как использовать
Импортируем пакет и вызываем иконку с помощью виджета HugeIcon.
import 'package:hugeicons/hugeicons.dart';
HugeIcon(
icon: HugeIcons.strokeRoundedHome01, // Выбор иконки
color: Colors.red, // Цвет иконки
size: 30.0, // Размер иконки
),
icon:
HugeIcons.strokeRoundedHome01
— здесь указываем иконку, которая будет отображаться. У нас — дом с закругленными углами.color: Colors.red
задает цвет иконки. Наш дом будет красным.size: 30.0
задает размер иконки в пикселях. 🔥Мне это нужно
🎨Рисую иконки в Paint с душой
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5❤2👍2👎2🎄1
This media is not supported in your browser
VIEW IN TELEGRAM
Привет, это Екатерина, Flutter-разработчик в команде Friflex
Сегодня расскажу еще про один инструмент, который может принести больше проблем, чем пользы —
Если вы сталкивались с проблемой неограниченного размера ListView, то могли наткнуться на советы установить этот виджет. Это и правда решит проблему красного экрана:
Но теперь при переходе на экран с этим виджетом приложение зависает на несколько секунд. Высота виджета становится определенной для фреймворка, но ради этого мы сильно жертвуем производительностью.
Как сделать лучше?
Самый простой способ — использовать Expanded или Flexible.
❗️ Если проблема возникла из-за использования ListView внутри другого ScrollView (к примеру, ListView внутри SingleChildScrollView), то поможет замена этих виджетов на CustomScrollView и SliverList.
Сегодня расскажу еще про один инструмент, который может принести больше проблем, чем пользы —
shrinkWrap: true
.Если вы сталкивались с проблемой неограниченного размера ListView, то могли наткнуться на советы установить этот виджет. Это и правда решит проблему красного экрана:
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: [
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: 10000,
itemBuilder: (_, __) => const Text('Hello World!'),
),
],
),
);
}
Но теперь при переходе на экран с этим виджетом приложение зависает на несколько секунд. Высота виджета становится определенной для фреймворка, но ради этого мы сильно жертвуем производительностью.
Как сделать лучше?
Самый простой способ — использовать Expanded или Flexible.
@override
Widget build(BuildContext context) {
return Column(
children: [
Flexible(
child: ListView.builder(
itemCount: 10000,
itemBuilder: (_, __) => const Text('Hello World!'),
),
),
],
);
}
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14👍3🔥2🤔1💯1🤝1
Вспомним структуру. Обычная ссылка для оплаты отправляет пользователя на сайт СБП, где из нее формируется QR-код, который нужно сканировать. Это не очень удобно, потому что код нужно сканировать в приложении банка. После этого открывается окно оплаты и появляются данные о приемщике платежа.
Если мы возьмем поле schema из этой ссылки со списком банков и вставим его в ссылку оплаты вместо https, то получим диплинк, который сразу будет открывать приложение нужного банка.
Переходим к созданию приложения:
Шаг 1
Получаем список банков.
Шаг 2
Формируем список банков. Для этого достаточно трех полей: bankName, logoURL и schema.
Шаг 3
Вставляем эти поля в объект. Создаем список, в котором отображаются все банки на экране.
Шаг 4
Меняем в ссылках оплаты https на schema соответствующего банка и открываем через url_launcher.
Шаг 5
Прослушиваем жизненный цикл приложения с помощью AppLifecycleListener. Используем коллбек onRestart, в нем ставим флаг. Второй флаг ставим после перехода в приложение банка.
Шаг 6
После возвращения из приложения банка отправляем запрос на проверку статуса оплаты.
В проекте нам понадобится всего два пакета. В pubspec.yaml указываем:
dependencies:
http: any
url_launcher: any
В следующих постах расскажем о каждом из шагов подобнее.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥25👍8❤1
This media is not supported in your browser
VIEW IN TELEGRAM
#пакет_недели — Patrol. Он помогает писать интеграционные тесты. Например, такие, которые требуют взаимодействия с настоящими устройствами или эмуляторами.
Главное о Patrol
🔴 Он строится на основе flutter_test и integration_test.
🔴 Он поддерживает нативные функции. Это очень кстати, когда тестируешь что-то, связанное с системными уведомлениями или настройками устройства.
🔴 Его нужно использовать вместе с patrol_cli.
Как использовать
Две главные функции Patrol — нативная автоматизация и кастомный поиск. Здесь мы разберем только первую, а подробно про кастомный поиск можно почитать в документации.
Используем Patrol в тесте, который проверяет, как ведет себя приложение, когда взаимодействует с кнопками Home, Recent Apps и панелью уведомлений.
❤️ Это мне надо
🤷♂️ Нажму кнопки «Назад» и «Домой» руками
Главное о Patrol
Как использовать
Две главные функции Patrol — нативная автоматизация и кастомный поиск. Здесь мы разберем только первую, а подробно про кастомный поиск можно почитать в документации.
Используем Patrol в тесте, который проверяет, как ведет себя приложение, когда взаимодействует с кнопками Home, Recent Apps и панелью уведомлений.
import 'package:example/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';
void main() {
patrolTest(
'состояние счетчика сохраняется после перехода на домашний экран и возврата',
($) async {
await $.pumpWidgetAndSettle(const MyApp());
await $(FloatingActionButton).tap();
expect($(#counterText).text, '1');
await $.native.pressHome();
await $.native.pressDoubleRecentApps();
expect($(#counterText).text, '1');
await $(FloatingActionButton).tap();
expect($(#counterText).text, '2');
await $.native.openNotifications();
await $.native.pressBack();
},
);
}
patrolTest
— обертка, которая заменяет стандартные тестовые функции Flutter. Внутри нее можно взаимодействовать и с виджетами Flutter, и с нативными элементами платформы. $.native.pressHome()
— эмулирует нажатие кнопки Home. Очень полезно, чтобы проверить, как ведет себя приложение, когда его сворачивают.$.native.pressDoubleRecentApps()
— имитирует двойное нажатие на кнопку списка последних приложений (Recent Apps). Можно использовать, чтобы проверить, как ведет себя приложение при возврате из других программ.$.native.openNotifications()
— эмулирует открытие панели уведомлений. Позволяет проверить, как приложение реагирует на системные события и взаимодействие с другими элементами ОС.❤️ Это мне надо
🤷♂️ Нажму кнопки «Назад» и «Домой» руками
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤4🔥1
Создаем Flutter-приложение для оплаты через СБП
В предыдущем посте рассказали о главных шагах, теперь разберем их подробнее. Начинаем с настройки получения списка банков.
🔸 Создаем объект для полей bankName, logoURL и schema. (Для безопасного парсинга данных рекомендуем использовать паттерн проектирования DTO):
*Здесь используем utf8 из-за проблем с кодировкой. Если у банка нет схемы, имени или картинки, не считаем его валидным.
🔸 Создаем абстрактный репозиторий
Реализованный метод можно вызывать на любом этапе бизнес-логики, где нужно получить список банков.
Для управления состояниями можно использовать любой стейт-менеджер, который вам нравится (например flutter_bloc, riverpod).
Мы рассмотрим вариант без сторонних библиотек, используем FutureBuilder и InheritedWidget.
🔸 Создаем экран для оплаты, который будет при инициализации запрашивать список банков из репозитория:
В предыдущем посте рассказали о главных шагах, теперь разберем их подробнее. Начинаем с настройки получения списка банков.
```dart
class BankItem {
const BankItem({
required this.bankName,
required this.logoURL,
required this.schema,
});
final String bankName;
final String logoURL;
final String schema;
static BankItem? fromJson(Map<String, dynamic> json) {
final bankName = json['bankName'] as String?;
final logoURL = json['logoURL'] as String?;
final schema = json['schema'] as String?;
if (bankName == null || logoURL == null || schema == null) {
return null;
}
return BankItem(
bankName: utf8.decode(bankName.codeUnits),
logoURL: logoURL,
schema: schema,
);
}
}
```
*Здесь используем utf8 из-за проблем с кодировкой. Если у банка нет схемы, имени или картинки, не считаем его валидным.
SbpRepository
для управления запросами СБП и реализуем метод getBankList
в NewtorkSbpRepository,
чтобы получить список банков-участников СБП: class NewtorkSbpRepository implements SbpRepository {
Future<Iterable<BankItem>> getBankList() async {
try {
final response = await http.get(
Uri.parse('https://qr.nspk.ru/proxyapp/c2bmembers.json'),
);
final decodedMap = jsonDecode(response.body) as Map<String, dynamic>;
final rawBanks = decodedMap['dictionary'] as List;
final banks = rawBanks.map((e) => BankItem.fromJson(e)).whereNotNull();
return banks;
} catch (error, trace) {
/// Добавить обработку особых ошибок
rethrow;
}
}
}
Реализованный метод можно вызывать на любом этапе бизнес-логики, где нужно получить список банков.
Для управления состояниями можно использовать любой стейт-менеджер, который вам нравится (например flutter_bloc, riverpod).
Мы рассмотрим вариант без сторонних библиотек, используем FutureBuilder и InheritedWidget.
class SbpPayScreen extends StatefulWidget {
const SbpPayScreen({super.key});
@override
State<SbpPayScreen> createState() => _SbpPayScreenState();
}
class _SbpPayScreenState extends State<SbpPayScreen> {
late final Future<Iterable<BankItem>> bankList;
@override
void initState() {
bankList = SbpController.of(context).repository.getBankList();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Оплата СБП'),
),
body: FutureBuilder(
future: bankList,
builder: (context, snapshot) {
if (snapshot.hasData) {
final data = snapshot.data!;
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) => ListTile(
title: Text(data.elementAt(index).bankName),
),
);
}
if (snapshot.hasError) {
return const Text('Произошла ошибка');
}
return const Center(child: CircularProgressIndicator());
},
),
);
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤7👍5
Как оперативно проверить приложение в AppStore?
Своим способом поделился Сергей, Team Lead Flutter-команды Friflex. Если нужно быстро выпустить обновление приложения (например, чтобы исправить критическую ошибку или добавить сборку с важным событием), можно воспользоваться процедурой срочной проверки.
Как действовать:
1️⃣ Выгрузите сборку приложения на ревью в App Store.
2️⃣ Отправьте запрос на срочную проверку. Для этого используйте форму по ссылке.
3️⃣ Дождитесь ответа. Обычно это занимает от 15 минут до 4 часов.
4️⃣ Радуйтесь одобрению.
P.S не балуемся этим способом слишком часто. Злоупотребление может привести к отказам в срочной проверке в будущем.
Своим способом поделился Сергей, Team Lead Flutter-команды Friflex. Если нужно быстро выпустить обновление приложения (например, чтобы исправить критическую ошибку или добавить сборку с важным событием), можно воспользоваться процедурой срочной проверки.
Как действовать:
P.S не балуемся этим способом слишком часто. Злоупотребление может привести к отказам в срочной проверке в будущем.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥4❤2👌1
This media is not supported in your browser
VIEW IN TELEGRAM
#пакет_недели — font_awesome_flutter. Это обертка для популярного набора иконок Font Awesome.
Главное о font_awesome_flutter
➡️ Он меняет основные параметры иконок, такие как размер и цвет.
➡️ Он применяет разные стили: solid, regular, light, и brands. В Pro версии стилей еще больше, включая duotone.
➡️ Он поддерживает иконки брендов. Например, логотипы социальных сетей или известных компаний.
Как использовать
Добавляем зависимость и используем все стандартные иконки с помощью виджета Falcon:
Настраиваем иконки, задаем цвет и стили:
Можно исключить ненужные стили иконок из процесса генерации, чтобы уменьшить размер пакета:
Иконки можно получить динамически по их имени — используйте faIconNameMapping.
🔥 Беру в работу
🤔 Слишком заморочено
Главное о font_awesome_flutter
Как использовать
Добавляем зависимость и используем все стандартные иконки с помощью виджета Falcon:
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
IconButton(
icon: FaIcon(FontAwesomeIcons.thumbsUp), // Иконка "пальцы вверх"
onPressed: () {
print("Liked!");
},
),
Настраиваем иконки, задаем цвет и стили:
FaIcon(
FontAwesomeIcons.heart, // Иконка "сердце"
color: Colors.red,
size: 50.0,
),
Можно исключить ненужные стили иконок из процесса генерации, чтобы уменьшить размер пакета:
$ ./configurator.sh --exclude solid
$ ./configurator.sh --exclude solid,brands
Иконки можно получить динамически по их имени — используйте faIconNameMapping.
import 'package:font_awesome_flutter/name_icon_mapping.dart';
...
FaIcon(faIconNameMapping['solid abacus']);
...
🔥 Беру в работу
🤔 Слишком заморочено
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3❤2🤔2🥰1
Открываем рубрику #flutter_heroe — про людей из сообщества, за которыми интересно и полезно следить каждому, кто пишет на Flutter. Сегодня расскажем про Реми Русселе. Пользуетесь пакетами riverpod или provider? Это он их автор.
Вклад
🔴 riverpod и provider: Реми разработал и поддерживает два из самых популярных пакетов для управления состоянием. Если provider стал стандартом для новичков, то riverpod предложил более гибкий и мощный подход.
🔴 flutter_hooks: Этот пакет стал отличным инструментом для сокращения количества шаблонного кода и улучшения организации Flutter-компонентов.
Совет начинающим
«Не читайте слишком много кода. Сначала пишите код. Вы становитесь лучше не от чтения книг, а от практики. Но обязательно читайте исходный код того, что используете. Не до конца понимаете, как что-то работает? Прочтите его исходный код»
Где следить
🔗 Github
🔗 X
🔗 Stack Overflow
Вклад
Совет начинающим
«Не читайте слишком много кода. Сначала пишите код. Вы становитесь лучше не от чтения книг, а от практики. Но обязательно читайте исходный код того, что используете. Не до конца понимаете, как что-то работает? Прочтите его исходный код»
Где следить
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥4❤3
Flutter обновился, но вы уже наверняка это знаете. Спросили Юру, нашего Tech Lead, про самые полезные улучшения, а он ответил:
Хабр
Переходите на Flutter 3.27, тут быстрее и плавнее (и Dart тоже обновите)
Привет, Хабр! Меня зовут Юра Петров, я Tech Lead в Friflex и автор канала «Мобильный разработчик» . Flutter обновился — вышла версия 3.27 . Улучшений много, от рендеринга и оптимизации...
❤4🔥4👍1
This media is not supported in your browser
VIEW IN TELEGRAM
#пакет_недели — google_sign_in. Он помогает аутентифицировать пользователей через их аккаунт Google в приложениях на Flutter.
Главное о google_sign_in
🔸 Он использует OAuth 2.0 для аутентификации и управления сессиями. Это позволяет безопасно идентифицировать пользователей и получать доступ к их данным (с их разрешения).
🔸 Он сохраняет состояние входа, и если пользователь уже авторизован, приложение может получать его данные автоматически.
🔸 Он работает на iOS, Android и Web, но настройка для каждой платформы может отличаться. Например, для Web нужно отдельно настроить OAuth.
Как использовать
Погрузиться во все детали можно с примером на Github.
❗️ Приложение будет зависеть от того, есть ли у пользователя учетная запись в Google, и это может стать проблемой.
❤️ Точно в цель
🤔 Без аккаунта Google — не полетит
Главное о google_sign_in
Как использовать
Погрузиться во все детали можно с примером на Github.
❤️ Точно в цель
🤔 Без аккаунта Google — не полетит
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍4🔥3
Anonymous Poll
21%
528 виджетов доступно в стандартной библиотеке Flutter
4%
475 контрибьюторов только в 2024
8%
Сообщество включает 92 000 участников в 64 странах
33%
Больше миллиона разработчиков каждый день используют Flutter
83%
28% новых приложений в App Store созданы на Flutter
👍4❤3🔥3
Как создать эффективный BDUI-фреймворк?
Делимся ключевыми выводами из доклада Никиты Синявина из BetBoom. На CrossConf он поделился опытом использования DUIT. На карточках — ключевые требования к фреймворку, его преимущества и сравнение с DivKit от Яндекса🖱
Делимся ключевыми выводами из доклада Никиты Синявина из BetBoom. На CrossConf он поделился опытом использования DUIT. На карточках — ключевые требования к фреймворку, его преимущества и сравнение с DivKit от Яндекса
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🔥3👍2
Юра, Tech Lead Flutter-команды Friflex, поделился новой подробной инструкцией, как установить все необходимое для написания приложения для Aurora на Flutter
Смотреть:
📎 на YouTube
📎 в VK
Смотреть:
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10🔥4👌3