Hola, amigos! Сегодня разберем подборку Flutter-инструментов, которые прокачивают взаимодействие с пользователем.
1. Dismissible позволяет легко реализовать логику swipe-to-delete.
2. Tooltip показывает краткую подсказку при долгом нажатии (mobile) или наведении (web/desktop).
3. Draggable подходит, чтобы реализовать drag-and-drop, как в Trello или корзине интернет-магазина.
4. ReorderableListView идеально подходит для настроек, плейлистов и любых кастомных списков.
А какими виджетами для UX чаще всего пользуетесь вы? Делитесь в комментариях.
1. Dismissible позволяет легко реализовать логику swipe-to-delete.
Dismissible(
key: Key(item.id),
background: Container(color: Colors.red),
onDismissed: (direction) => deleteItem(item.id),
child: ListTile(
title: Text("Swipe me to delete"),
),
)
2. Tooltip показывает краткую подсказку при долгом нажатии (mobile) или наведении (web/desktop).
Tooltip(
message: 'Download PDF',
child: IconButton(
icon: Icon(Icons.download),
onPressed: () {},
),
)
3. Draggable подходит, чтобы реализовать drag-and-drop, как в Trello или корзине интернет-магазина.
Draggable<Color>(
data: Colors.blue,
feedback: Container(
height: 100,
width: 100,
color: Colors.blue.withOpacity(0.5),
),
childWhenDragging: Container(
height: 100,
width: 100,
color: Colors.grey,
),
child: Container(
height: 100,
width: 100,
color: Colors.blue,
),
);
4. ReorderableListView идеально подходит для настроек, плейлистов и любых кастомных списков.
ReorderableListView(
onReorder: (oldIndex, newIndex) {
setState(() {
if (newIndex > oldIndex) newIndex -= 1;
final item = list.removeAt(oldIndex);
list.insert(newIndex, item);
});
},
children: list
.map(
(item) => ListTile(
key: ValueKey(item),
title: Text(item.toString()),
),
)
.toList(),
);
А какими виджетами для UX чаще всего пользуетесь вы? Делитесь в комментариях.
👍10❤6👀5
Forwarded from Amiga
Hola, Amigos!
Совсем скоро нам исполнится 5 лет, и мы наконец-то создали этот канал. Сначала хотим к юбилею отрефлексировать все взлеты и падения, а позже будем делиться интересными инсайтами, анонсами мероприятий и выступлений, мыслями о продуктах и рынке.
Уже пять лет мы разрабатываем приложения и сайты — от идеи до выхода продукта на рынок и первых пользователей. Работаем со всем циклом: от аналитики и дизайна до разработки, поддержки и усиления команд. Были и удачные запуски, и сложные решения, и, конечно, ошибки, из которых потом вырастали сильные продукты.
Весь февраль будем рассказывать о себе и о том, как мы работаем⚙️
Велкам!
Совсем скоро нам исполнится 5 лет, и мы наконец-то создали этот канал. Сначала хотим к юбилею отрефлексировать все взлеты и падения, а позже будем делиться интересными инсайтами, анонсами мероприятий и выступлений, мыслями о продуктах и рынке.
Уже пять лет мы разрабатываем приложения и сайты — от идеи до выхода продукта на рынок и первых пользователей. Работаем со всем циклом: от аналитики и дизайна до разработки, поддержки и усиления команд. Были и удачные запуски, и сложные решения, и, конечно, ошибки, из которых потом вырастали сильные продукты.
Весь февраль будем рассказывать о себе и о том, как мы работаем
Велкам!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5
Hola, Amigos! Небольшое обновление 🙂
Мы запустили отдельный канал нашей компании. Теперь все новости агентства, анонсы мероприятий и выступлений, кейсы, а также инсайты про рынок разработки будут выходить там.
Этот канал, как и раньше, остается про Flutter❤️
Мы запустили отдельный канал нашей компании. Теперь все новости агентства, анонсы мероприятий и выступлений, кейсы, а также инсайты про рынок разработки будут выходить там.
Этот канал, как и раньше, остается про Flutter
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤3👍2👏1
Hola, Amigos! Async/await и Isolate оба помогают держать UI плавным, но решают разные задачи. Сегодня обсудим, что и в каких ситуациях лучше использовать.
Неправильно: async/await для CPU-тяжелой задачи
Правильно и просто: compute()
Когда нужен полный контроль, подойдет Raw Isolate
Разберем по ситуации:
- Блокирует main thread > ~300 мс → compute()
- Просто ждет (network/db) → async/await
- Нужен worker с диалогом → raw Isolate
А ты пользуешься Isolate/compute или решаешь через async/await? Делись опытом⚙️
Неправильно: async/await для CPU-тяжелой задачи
Future<String> processBigData() async {
final raw = await fetchHugeJson(); // ← I/O — ок
final data = jsonDecode(raw); // ← блокирует UI ~1с
final result = heavyMath(data); // ← ещё ~1с
return result;
}
Правильно и просто: compute()
import 'package:flutter/foundation.dart';
Future<String> processBigData() async {
final raw = await fetchHugeJson(); // сеть — ок
return compute(_heavyWork, raw); // ← выполняется в Isolate
}
String _heavyWork(String json) {
final data = jsonDecode(json);
return heavyMath(data);
}
Когда нужен полный контроль, подойдет Raw Isolate
Future<void> startWorker() async {
final receivePort = ReceivePort();
isolate = await Isolate.spawn(_worker, receivePort.sendPort);
sendPort = await receivePort.first as SendPort;
}
Future<String> doHeavyTask(String input) async {
final response = ReceivePort();
sendPort.send([input, response.sendPort]);
return await response.first as String;
}
static void _worker(SendPort mainPort) async {
final port = ReceivePort();
mainPort.send(port.sendPort);
await for (final msg in port) {
final input = msg[0] as String;
final replyTo = msg[1] as SendPort;
replyTo.send("processed: $input"); // heavy work here
}
}
Разберем по ситуации:
- Блокирует main thread > ~300 мс → compute()
- Просто ждет (network/db) → async/await
- Нужен worker с диалогом → raw Isolate
А ты пользуешься Isolate/compute или решаешь через async/await? Делись опытом
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥4🤝2
Запланируйте 2026 год вместе с Merge
В 2025 году под эгидой Merge прошло сразу четыре события для профессионального IT-сообщества, Мероприятия объединили более 6000 участников и свыше 500 спикеров.
Сейчас Merge строит планы на 2026 год. И приглашает всех присоединиться.
Merge Innopolis | 17–18 апреля
В 2026 году инновационный центр Поволжья, город Иннополис, готовится принять Merge в пятый раз. Все ключевые направления IT на одной площадке. 200+ спикеров, 2000+ участников, 10 потоков докладов по 7 ключевым трекам: «Разработка», «Управление», «Маркетинг», «Аналитика», «HR», «1С», «Карьера в IT».
Summer Merge | 3–5 июля
Самая летняя IT-тусовка на берегу Волги, неформальный нетворкинг и лучший палаточный уикенд для IT-специалистов.
Merge Baltic | 25–27 сентября
Профессиональная конференция Merge соберет представителей всех направлений сферы IT на берегу Балтийского моря. Здесь привычную деловую программу и нетворкинг расширит тревел-трек и экскурсии по удивительным местам Калининградской области.
По промокоду AMIGA действует скидка 10% на билеты. Успейте присоединиться до повышения цены.
Присоединяйтесь!
В 2025 году под эгидой Merge прошло сразу четыре события для профессионального IT-сообщества, Мероприятия объединили более 6000 участников и свыше 500 спикеров.
Сейчас Merge строит планы на 2026 год. И приглашает всех присоединиться.
Merge Innopolis | 17–18 апреля
В 2026 году инновационный центр Поволжья, город Иннополис, готовится принять Merge в пятый раз. Все ключевые направления IT на одной площадке. 200+ спикеров, 2000+ участников, 10 потоков докладов по 7 ключевым трекам: «Разработка», «Управление», «Маркетинг», «Аналитика», «HR», «1С», «Карьера в IT».
Summer Merge | 3–5 июля
Самая летняя IT-тусовка на берегу Волги, неформальный нетворкинг и лучший палаточный уикенд для IT-специалистов.
Merge Baltic | 25–27 сентября
Профессиональная конференция Merge соберет представителей всех направлений сферы IT на берегу Балтийского моря. Здесь привычную деловую программу и нетворкинг расширит тревел-трек и экскурсии по удивительным местам Калининградской области.
По промокоду AMIGA действует скидка 10% на билеты. Успейте присоединиться до повышения цены.
Присоединяйтесь!
❤4👍4🔥4
Hola, Amigos! Наш Flutter Team Lead Павел Гершевич примет участие в круглом столе на FlutterConf 🙂
Запускаешь новый проект — и снова тот же вопрос: какой state manager выбрать? Проверенный временем? Популярный в комьюнити? Или тот, который сейчас чаще всего советуют?
На FlutterConf вынесли тему на открытое обсуждение с аргументами и практическим опытом. Обсудим реальные кейсы, плюсы и минусы подходов, гибкость Flutter и попробуют понять, возможен ли тот самый «золотой стандарт».
В обсуждении участвуют:
— Павел Гершевич, Team Lead Flutter Amiga
— Анна Жаркова, руководитель группы разработки Usetech
— Олег Скирюк, Frontend Team Lead билайн
— Станислав Чернышев, доцент СПбГУАП, автор книги «Основы Dart»
— Николай Омётов, руководитель Flutter-отдела Mad Brains
— Андрей Смирнов, Dart Dependant Overthinking Specialist Яндекс
— Федор Благодырь, разработчик Яндекс
⚙️ Билеты уже в продаже. Круглый стол «Я твой State Manager труба шатал»
⚙️ Москва, 3-я ул. Ямского Поля, 26А
⚙️ 27 февраля, 18:05–19:20
⚙️ Зал 1
А с промокодом FLUTTER_MNOGO вас ждет скидка 20%
Запускаешь новый проект — и снова тот же вопрос: какой state manager выбрать? Проверенный временем? Популярный в комьюнити? Или тот, который сейчас чаще всего советуют?
На FlutterConf вынесли тему на открытое обсуждение с аргументами и практическим опытом. Обсудим реальные кейсы, плюсы и минусы подходов, гибкость Flutter и попробуют понять, возможен ли тот самый «золотой стандарт».
В обсуждении участвуют:
— Павел Гершевич, Team Lead Flutter Amiga
— Анна Жаркова, руководитель группы разработки Usetech
— Олег Скирюк, Frontend Team Lead билайн
— Станислав Чернышев, доцент СПбГУАП, автор книги «Основы Dart»
— Николай Омётов, руководитель Flutter-отдела Mad Brains
— Андрей Смирнов, Dart Dependant Overthinking Specialist Яндекс
— Федор Благодырь, разработчик Яндекс
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥4🥰4😍1
Hola, Amigos! Сегодня обсудим pattern matching. Он сокращает boilerplate, улучшает код и повышает безопасность работы со state.
1. Деструктуризация с помощью паттернов
Пример с Records:
2. Деструктуризация объектов
Есть класс:
Можно извлечь свойства так:
Это эквивалентно:
3. Pattern Matching в switch
Традиционный подход:
Подход с pattern matching
4. Сопоставление коллекций
Паттерны умеют анализировать списки и map:
5. Guard-условия
А вы используете pattern matching?
1. Деструктуризация с помощью паттернов
Пример с Records:
var user = ('Naman', 29);
var (name, age) = user;
print(name);
print(age);
2. Деструктуризация объектов
Есть класс:
class User {
final String name;
final int age;
User(this.name, this.age);
}
Можно извлечь свойства так:
var User(:name, :age) = user;
Это эквивалентно:
var name = user.name;
var age = user.age;
3. Pattern Matching в switch
Традиционный подход:
if (state is Success) {
final data = state.data;
}
Подход с pattern matching
switch (state) {
case Success(data: var data):
render(data);
case Loading():
showLoader();
case Error(message: var msg):
showError(msg);
}
4. Сопоставление коллекций
Паттерны умеют анализировать списки и map:
switch(list) {
case []:
print("Empty");
case [first, second]:
print(first);
}
switch(json) {
case {'status': 'ok', 'data': var d}:
process(d);
case {'status': 'error', 'message': var m}:
showError(m);
}
5. Guard-условия
switch(user) {
case User(age: var age) when age > 18:
print("Adult");
case _:
print("Minor");
}
А вы используете pattern matching?
🔥14👍11❤6💯1
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. Сегодня мы поговорим про то, как лучше всего кешировать картинки и в каком качестве их выводить на экран.
Часто случается ситуация, что сервер отдает слишком большую картинку. А уж если их несколько на одном экране - могут возникнуть проблемы с производительностью, да и размер кеша может значительно вырасти.
Как и все, для кеширования и отображения картинок с интернета, мы используем хорошо знакомую всем библиотеку
Давайте разберемся с ними:
Теперь давайте рассмотрим, как их использовать. Для того, чтобы правильно подобрать размер, нам нужны: ширина и высота виджета и Device Pixel Ratio - характеристика устройства, которая показывает плотность пикселей. Если размер нам неизвестен либо высчитывается автоматически, то можно прибегнуть к получению
Делитесь в комментариях, пробовали ли вы такой способ оптимизации производительности приложения?
Часто случается ситуация, что сервер отдает слишком большую картинку. А уж если их несколько на одном экране - могут возникнуть проблемы с производительностью, да и размер кеша может значительно вырасти.
Как и все, для кеширования и отображения картинок с интернета, мы используем хорошо знакомую всем библиотеку
cached_network_image. Но не все знают, что при помощи нее можно настроить максимальный размер изображения, который будет закеширован и показан на экране. Для этого есть 4 свойства:
maxHeightDiskCache: 300,
maxWidthDiskCache: 300,
memCacheHeight: 300,
memCacheWidth: 300,
Давайте разберемся с ними:
maxHeightDiskCache и maxWidthDiskCache отвечают за кеш, который хранится в постоянной памяти. Уменьшая его размер, мы уменьшаем количество данных на устройстве пользователя. memCacheHeight и memCacheWidth отвечают за изображение, которое хранится в ОЗУ и выводится пользователю. Делается это при помощи встроенного в Flutter виджета - ResizeImage. Похожие свойства есть и в Image.network - cacheHeight и cacheWidth. Тут мы указываем именно размер виджета, а не изображения.Теперь давайте рассмотрим, как их использовать. Для того, чтобы правильно подобрать размер, нам нужны: ширина и высота виджета и Device Pixel Ratio - характеристика устройства, которая показывает плотность пикселей. Если размер нам неизвестен либо высчитывается автоматически, то можно прибегнуть к получению
constraints через LayoutBuilder. В итоге у нас получается такой код:
LayoutBuilder((context, constraints) {
final devicePixelRatio = MediaQuery.devicePixelRatioOf(context);
final cacheHeight = constraints.maxHeight * devicePixelRatio;
final cacheWidth = constraints.maxWidth * devicePixelRatio;
return CachedNetworkImage(
…
maxHeightDiskCache: cacheHeight,
maxWidthDiskCache: cacheWidth,
memCacheHeight: constraints.maxHeight,
memCacheWidth: constraints.maxWidth,
…
);
});
Делитесь в комментариях, пробовали ли вы такой способ оптимизации производительности приложения?
❤7🔥6👍4
Hola, Amigos! Сегодня мы посмотрим, каким образом мы можем грузить и показывать данные пользователям при помощи пагинации.
Пагинация - способ, который используется для разделения больших данных на небольшие группы (страницы) вместо загрузки всего сразу.
Например, для API в 10000 объектов, вместо огромного массива данных, мы будем запрашивать потихоньку: страница 1 (объекты 1-10), страница 2 (объекты 11-20) и т. д.
Это помогает нам:
• Уменьшить нагрузку на сеть. Меньше данных в запросе - выше скорость его выполнения на сервере и быстрее передача ответа;
• Оптимизировать производительность. Меньше объем данных - меньше занимаемой оперативной памяти, быстрее обработка;
• Улучшить UX. Пользователи будут видеть новые данные практически, а не когда мы получим и распарсим все объекты.
Для того, чтобы правильно сделать пагинацию в мобильном приложении, нужно знать, как она делается на сервере. Тут существует 3 способа:
Page-based (стандартный способ)
Тут мы запрашиваем данные, передавая
Offset-based (гибкий способ)
Тут запрос осуществляется с указанием сколько элементов нужно пропустить -
Cursor-based (профессиональный способ)
Самый расширяемый метод. Мы запрашиваем через курсор (обычно ID или timestamp последнего полученного объекта) и получаем данные, которые были добавлены в БД после тех данных, которые мы уже знаем.
Последний способ применяется редко, так как он может не подойти под некоторые случаи. Но у первых двух тоже есть недостаток - может возникнуть дублирование или пропажа данных.
С тем, как запрашивать данные, мы определились, теперь нужно понять, какая страница последняя? Тут есть 2 варианта - либо API вернет нам номер последней страницы при запросе, либо на последней странице придет число меньше указанного нами лимита.
Теперь поработаем с нашим State Manager. Нам нужны состояния - загрузки, успеха и ошибки. И обязательно хранить в них - список полученных данных, страницу (если применяем page-based или offset-based) и при возможности номер последней страницы. Кто-то делает отдельное состояние для загрузки новой страницы, но можно обойтись и без него. И нам нужно 2 функции - для инициализации экрана, чтобы подгрузить первые данные, и для подгрузки во время пагинации. Для BLoC советуем отбрасывать событие подгрузки, если мы находимся в состоянии загрузки.
В следующей части расскажем, как привязать это все к UI. А вы делитесь в комментариях, какой способ пагинации чаще всего используете на своих проектах?
Пагинация - способ, который используется для разделения больших данных на небольшие группы (страницы) вместо загрузки всего сразу.
Например, для API в 10000 объектов, вместо огромного массива данных, мы будем запрашивать потихоньку: страница 1 (объекты 1-10), страница 2 (объекты 11-20) и т. д.
Это помогает нам:
• Уменьшить нагрузку на сеть. Меньше данных в запросе - выше скорость его выполнения на сервере и быстрее передача ответа;
• Оптимизировать производительность. Меньше объем данных - меньше занимаемой оперативной памяти, быстрее обработка;
• Улучшить UX. Пользователи будут видеть новые данные практически, а не когда мы получим и распарсим все объекты.
Для того, чтобы правильно сделать пагинацию в мобильном приложении, нужно знать, как она делается на сервере. Тут существует 3 способа:
Page-based (стандартный способ)
Тут мы запрашиваем данные, передавая
page, страницу, и limit - количество элементов. Запрос будет выглядеть примерно так:
GET /posts?page=1&limit=10
Offset-based (гибкий способ)
Тут запрос осуществляется с указанием сколько элементов нужно пропустить -
offset.
GET /posts?offset=20&limit=10
Cursor-based (профессиональный способ)
Самый расширяемый метод. Мы запрашиваем через курсор (обычно ID или timestamp последнего полученного объекта) и получаем данные, которые были добавлены в БД после тех данных, которые мы уже знаем.
GET /posts?cursor=50&limit=10
Последний способ применяется редко, так как он может не подойти под некоторые случаи. Но у первых двух тоже есть недостаток - может возникнуть дублирование или пропажа данных.
С тем, как запрашивать данные, мы определились, теперь нужно понять, какая страница последняя? Тут есть 2 варианта - либо API вернет нам номер последней страницы при запросе, либо на последней странице придет число меньше указанного нами лимита.
Теперь поработаем с нашим State Manager. Нам нужны состояния - загрузки, успеха и ошибки. И обязательно хранить в них - список полученных данных, страницу (если применяем page-based или offset-based) и при возможности номер последней страницы. Кто-то делает отдельное состояние для загрузки новой страницы, но можно обойтись и без него. И нам нужно 2 функции - для инициализации экрана, чтобы подгрузить первые данные, и для подгрузки во время пагинации. Для BLoC советуем отбрасывать событие подгрузки, если мы находимся в состоянии загрузки.
В следующей части расскажем, как привязать это все к UI. А вы делитесь в комментариях, какой способ пагинации чаще всего используете на своих проектах?
👍9❤4🔥4🥰1
Hola, Amigos! Продолжаем разбираться с пагинацией. Сегодня рассмотрим, как подключить логику работы к пользовательскому интерфейсу.
Для того, чтобы мы могли вызывать подгрузку новой страницы, нам нужен триггер. В зависимости от функционала можно рассмотреть как навигацию по страницам, в таком случае необходимо будет сбрасывать предыдущие данные, так и реализацию бесконечного списка, который мы и разберем подробнее.
В бесконечном списке страницы грузятся в момент, когда пользователь практически доходит до конца. Для этого нам понадобится
Тут мы получаем текущее и максимальное положение скролла и сравниваем их. Совет - не нужно дожидаться, пока пользователь дойдет до самого конца списка, лучше начинать грузить пораньше, например, когда до максимума осталось 200 пикселей. Тут все зависит от высоты элементов списка и их количества на экране.
Следующий момент - виджет загрузки первой страницы. Каким он будет, зависит от вас. Часто используют
И в самом конце, нужно сделать отображение загрузки новой страницы. Для этого мы манипулируем количеством элементов в списке и его последним элементом:
Как и в случае с первоначальной загрузкой, вы можете выбрать то, что вам удобно и подходит.
Делитесь в комментариях, а каким виджетом вы показываете состояние загрузки на ваших проектах?
Для того, чтобы мы могли вызывать подгрузку новой страницы, нам нужен триггер. В зависимости от функционала можно рассмотреть как навигацию по страницам, в таком случае необходимо будет сбрасывать предыдущие данные, так и реализацию бесконечного списка, который мы и разберем подробнее.
В бесконечном списке страницы грузятся в момент, когда пользователь практически доходит до конца. Для этого нам понадобится
ScrollController, который мы подцепляем к виджету списка, это может быть ListView.builder или ListView.separated. Далее нужно добавить прослушку:
_scrollController.addListener(() {
final currentScroll = _scrollController.position.pixels;
final maxScroll = _scrollController.position.maxScrollExtent;
if (currentScroll >= (maxScroll - 200) && !isLoading) {
… // Вызов функции для подгрузки
}
});
Тут мы получаем текущее и максимальное положение скролла и сравниваем их. Совет - не нужно дожидаться, пока пользователь дойдет до самого конца списка, лучше начинать грузить пораньше, например, когда до максимума осталось 200 пикселей. Тут все зависит от высоты элементов списка и их количества на экране.
Следующий момент - виджет загрузки первой страницы. Каким он будет, зависит от вас. Часто используют
CircularProgressIndicator или какой-либо скелет, например, с Shimmer эффектом. Показываем мы его, если находимся в состоянии загрузки данных и у нас пока нет элементов списка:
if (isLoading && items.isEmpty) {
return …
}
И в самом конце, нужно сделать отображение загрузки новой страницы. Для этого мы манипулируем количеством элементов в списке и его последним элементом:
ListView.builder(
conroller: _scrollController,
…
itemCount: items.length + (isLoading && !isLastPage ? 1 : 0),
itemBuilder: (context, index) {
if (index < items.length) {
return … // Ваш элемент списка
}
return … // Ваш индикатор загрузки
},
);
Как и в случае с первоначальной загрузкой, вы можете выбрать то, что вам удобно и подходит.
Делитесь в комментариях, а каким виджетом вы показываете состояние загрузки на ваших проектах?
👍10❤🔥4❤3
Hola, Amigos! На связи Павел Гершевич, Mobile TeamLead в Amiga. В каждом приложении мы авторизуем пользователей, но не все встраивают механизмы обновления токенов.
Поэтому мы написали статью о том, как это делается, и поделились нашим опытом. Из нее вы узнаете:
Как работает авторизация запросов на сервере
🔵 Что хранит в себе JWT и как узнать, когда он закончит действовать
🔵 Как работает QueryInterceptor в Dio и чем он отличается от обычного
🔵 3 способа обработки токенов с завершившимся сроком действия
Ссылка на статью на Хабре
Делитесь в комментариях, а как вы поступаете при получении ошибки 401 Unauthorized?
Поэтому мы написали статью о том, как это делается, и поделились нашим опытом. Из нее вы узнаете:
Как работает авторизация запросов на сервере
Ссылка на статью на Хабре
Делитесь в комментариях, а как вы поступаете при получении ошибки 401 Unauthorized?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤3🔥3
Hola, Amigos! На связи Павел Гершевич, Mobile TeamLead в Amiga. Для того, чтобы наши приложения работали лучше, можно отслеживать их жизненный цикл, чтобы не совершалось лишних действий. Для этого нам нужен
Рассказывайте в комментариях, а что вы делаете при изменении жизненного цикла приложения?
AppLifecycleState, который предоставляет добавление обратных вызовов для изменения состояния. Давайте посмотрим, какие состояния есть у Flutter-приложений:resumed - стандартное состояние, когда приложение находится в foreground. При переходе в него можно запускать остановленные потоки данных (Stream) и анимации, а также обновлять устаревшие данные.inactive - наше приложение видно, но пользователь не может с ним работать. Его можно увидеть, когда мы смотрим на все свернутые приложения. Также, например, открытие системного диалогового окна для выдачи разрешения переведет в это состояние. Тут можно остановить анимации. Но учитывайте, это состояние - временное.hidden - еще одно временное состояние. Наше приложение не видно, но оно еще не полностью на паузе. Оно добавлено в Flutter 3.13 чтобы мы могли сохранить состояние, пока операционная система не порезала ресурсы.paused - наше приложение полностью в фоне. Основной isolate еще работает, но Flutter Engine уже не занимается рендерингом. В этом состоянии можно отключиться от WebSockets, отменить работу таймеров, прослушку потоков данных. Но из этого состояния ОС может закрыть приложение.detached - крайнее состояние нашего приложения. Оно показывает, что приложение закрывается либо открывается (холодный запуск).Рассказывайте в комментариях, а что вы делаете при изменении жизненного цикла приложения?
1🔥11❤6👍5
Hola, Amigos! Мы все любим ускорять и упрощать написание шаблонного кода. Один из таких методов - Snippets.
Snippet - аббревиатура, которую IDE может преобразовать в код.
Показываем, как это сделать в Android Studio. А в следующей части расскажем про VS Code.
Рассказывайте в комментариях, используете snippets в работе?
Snippet - аббревиатура, которую IDE может преобразовать в код.
Показываем, как это сделать в Android Studio. А в следующей части расскажем про VS Code.
Рассказывайте в комментариях, используете snippets в работе?
1❤9👍8🔥5