Принцип подстановки Барбары Лисков: основа правильного полиморфизма в программировании 🌟
Привет, друзья! Сегодня мы поговорим о третьей букве в акрониме SOLID - L, которая означает принцип подстановки Лисков 🤔. Этот принцип гласит, что объекты подклассов должны быть взаимозаменяемы с объектами их базового класса без нарушения корректности работы программы 💻.
Почему это важно? 🤔 Нарушение LSP приводит к непредсказуемому поведению программы, код начинает проверять типы объектов с помощью if/else или is, что противоречит принципу открытости/закрытости и делает систему хрупкой 🌪. Соблюдение LSP гарантирует, что полиморфизм работает правильно и подклассы действительно являются специализацией базового класса 🔩.
Давайте рассмотрим пример нарушения LSP 🚫:
Здесь функция, принимающая Bird, ожидает, что любой потомок сможет летать. Но при подстановке пингвина код валится с ошибкой, значит, иерархия нарушает принцип Лисков 🚫.
А теперь пример правильного использования LSP 🌟:
Ключевые правила LSP 📝:
✔️ Предусловия не могут быть усилены в подклассе — подкласс не должен требовать больше, чем базовый класс
✔️ Постусловия не могут быть ослаблены в подклассе — подкласс должен гарантировать как минимум то, что гарантирует базовый класс
✔️ Инварианты должны сохраняться — свойства, которые истинны для базового класса, должны оставаться истинными для подклассов
✔️ Исключения — подкласс не должен выбрасывать новые типы исключений, которые не ожидаются от базового класса
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly
Привет, друзья! Сегодня мы поговорим о третьей букве в акрониме SOLID - L, которая означает принцип подстановки Лисков 🤔. Этот принцип гласит, что объекты подклассов должны быть взаимозаменяемы с объектами их базового класса без нарушения корректности работы программы 💻.
Почему это важно? 🤔 Нарушение LSP приводит к непредсказуемому поведению программы, код начинает проверять типы объектов с помощью if/else или is, что противоречит принципу открытости/закрытости и делает систему хрупкой 🌪. Соблюдение LSP гарантирует, что полиморфизм работает правильно и подклассы действительно являются специализацией базового класса 🔩.
Давайте рассмотрим пример нарушения LSP 🚫:
class Bird {
void fly() {
print("Flying");
}
}
class Penguin extends Bird {
@override
void fly() {
throw Exception("Cannot fly"); // Нарушение LSP
}
}
Здесь функция, принимающая Bird, ожидает, что любой потомок сможет летать. Но при подстановке пингвина код валится с ошибкой, значит, иерархия нарушает принцип Лисков 🚫.
А теперь пример правильного использования LSP 🌟:
abstract class Bird {
void move();
}
class Sparrow extends Bird {
@override
void move() {
print("Flying");
}
}
class Penguin extends Bird {
@override
void move() {
print("Swimming");
}
}
Ключевые правила LSP 📝:
✔️ Предусловия не могут быть усилены в подклассе — подкласс не должен требовать больше, чем базовый класс
✔️ Постусловия не могут быть ослаблены в подклассе — подкласс должен гарантировать как минимум то, что гарантирует базовый класс
✔️ Инварианты должны сохраняться — свойства, которые истинны для базового класса, должны оставаться истинными для подклассов
✔️ Исключения — подкласс не должен выбрасывать новые типы исключений, которые не ожидаются от базового класса
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly
🔥2
🪙 Жизненный цикл Flutter-приложения: как отслеживать изменения состояний 📱
Каждое мобильное приложение проходит через ряд состояний, определяемых перечислением
Существует пять основных состояний:
-
-
-
-
-
Чтобы отслеживать изменения этих состояний, мы используем
Пример работы с
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #mobiledevelopment #appdevelopment
Каждое мобильное приложение проходит через ряд состояний, определяемых перечислением
AppLifecycleState. Чтобы корректно реагировать на эти события, нам нужно понимать, какие состояния существуют и как на них реагировать. Существует пять основных состояний:
-
resumed: приложение находится на переднем плане и готово к взаимодействию с пользователем 📈-
inactive: приложение временно неактивно, например, при поступлении звонка 📞-
paused: приложение уходит в фон и не реагирует на действия пользователя 📊-
hidden: приложение скрыто от пользователя, но процесс остается в памяти и готов к быстрому возобновлению 🔒-
detached: приложение больше не активно и готовится к завершению 🔴Чтобы отслеживать изменения этих состояний, мы используем
WidgetsBindingObserver и его метод didChangeAppLifecycleState, который вызывается каждый раз, когда система переводит приложение между состояниями. Пример работы с
didChangeAppLifecycleState:
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
setState(() {
if (state == AppLifecycleState.resumed) {
appState = 'Возобновлено';
} else if (state == AppLifecycleState.inactive) {
appState = 'Неактивно';
} else if (state == AppLifecycleState.paused) {
appState = 'Приостановлено';
} else if (state == AppLifecycleState.detached) {
appState = 'Отключено';
} else if (state == AppLifecycleState.hidden) {
appState = 'Скрыто';
}
});
}
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #mobiledevelopment #appdevelopment
👍3🔥1
💎 Выбор аккаунта разработчика: индивидуальный или корпоративный?
Привет, друзья! 💬 Сегодня мы поговорим о важном этапе перед публикацией приложения в Google Play и AppStore - создании аккаунта разработчика. 📈 Этот аккаунт может быть двух видов: индивидуальный и корпоративный. 🤔
Индивидуальный аккаунт - это аккаунт физического лица, который регистрируется на конкретного человека. 📝 Преимущества такого аккаунта включают быстрый процесс регистрации, минимальное количество документов и проверок, отсутствие необходимости наличия официально зарегистрированного юридического лица, меньше бюрократии и более низкие затраты на содержание. 💸 Однако, есть и недостатки: ограничения в доступах, даже для администраторов, указание имени владельца аккаунта в карточке приложения, что может повлиять на репутацию продукта, доход поступает как доход физического лица и требуются особые условия для публикации. 📊
Корпоративный аккаунт регистрируется на официальное юридическое лицо. 📈 Преимущества включают более высокое доверие клиентов, поскольку они видят перед собой целую компанию, а не одного человека, огромный выбор ролевых моделей в управлении проектом, возможность делегирования ключевых прав и удобное ведение бизнеса. 📈 Однако, есть и недостатки: сложный процесс регистрации, требующий много документов и времени, более строгие требования к соответствию внутренним правилам и возможные ограничения для разработчиков из определенных стран. 🚫
Итак, какой аккаунт выбрать? 🤔 Если вы работаете над pet-проектом, стартапом или экспериментальным продуктом, индивидуальный аккаунт может быть оптимальным вариантом. 🌟 Однако, если ваше приложение является частью полноценного бизнеса или у вас большая команда разработчиков, лучше выбрать аккаунт юридического лица. 📈
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #mobiledevelopment #appdevelopment
Привет, друзья! 💬 Сегодня мы поговорим о важном этапе перед публикацией приложения в Google Play и AppStore - создании аккаунта разработчика. 📈 Этот аккаунт может быть двух видов: индивидуальный и корпоративный. 🤔
Индивидуальный аккаунт - это аккаунт физического лица, который регистрируется на конкретного человека. 📝 Преимущества такого аккаунта включают быстрый процесс регистрации, минимальное количество документов и проверок, отсутствие необходимости наличия официально зарегистрированного юридического лица, меньше бюрократии и более низкие затраты на содержание. 💸 Однако, есть и недостатки: ограничения в доступах, даже для администраторов, указание имени владельца аккаунта в карточке приложения, что может повлиять на репутацию продукта, доход поступает как доход физического лица и требуются особые условия для публикации. 📊
Корпоративный аккаунт регистрируется на официальное юридическое лицо. 📈 Преимущества включают более высокое доверие клиентов, поскольку они видят перед собой целую компанию, а не одного человека, огромный выбор ролевых моделей в управлении проектом, возможность делегирования ключевых прав и удобное ведение бизнеса. 📈 Однако, есть и недостатки: сложный процесс регистрации, требующий много документов и времени, более строгие требования к соответствию внутренним правилам и возможные ограничения для разработчиков из определенных стран. 🚫
Итак, какой аккаунт выбрать? 🤔 Если вы работаете над pet-проектом, стартапом или экспериментальным продуктом, индивидуальный аккаунт может быть оптимальным вариантом. 🌟 Однако, если ваше приложение является частью полноценного бизнеса или у вас большая команда разработчиков, лучше выбрать аккаунт юридического лица. 📈
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #mobiledevelopment #appdevelopment
💭 Реализация перетаскивания файлов в Flutter с помощью пакета desktop_drop 📁💻
Привет, друзья! Сегодня я хочу рассказать вам о пакете desktop_drop, который позволяет реализовать перетаскивание файлов в ваших десктоп- или веб-приложениях на Flutter. 🌟
Пакет предоставляет виджет
Основные свойства
✔️
✔️
✔️
✔️
✔️
Пример использования
Также можно визуально показывать, что область готова принять файл, используя состояния, отслеживаемые через
При работе с
▪️ Разные платформы могут по-разному обрабатывать события перетаскивания
▪️ С помощью
▪️ Для безопасной работы всегда проверяйте тип, размер и количество файлов
❕ Для полноценного функционала работы с файлами
❤️ — если было полезно
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly
Привет, друзья! Сегодня я хочу рассказать вам о пакете desktop_drop, который позволяет реализовать перетаскивание файлов в ваших десктоп- или веб-приложениях на Flutter. 🌟
Пакет предоставляет виджет
DropTarget, который определяет область, на которую можно перетаскивать файлы. Этот виджет невидим, но он позволяет вам определять область для перетаскивания вокруг своего child. 📈Основные свойства
DropTarget включают:✔️
onDragEntered — вызывается, когда файл входит в область виджета✔️
onDragExited — вызывается, когда файл покидает область виджета✔️
onDragDone — вызывается после того, как файл был отпущен внутри области✔️
onDragUpdated — вызывается при движении файла внутри области✔️
child — виджет, который отображается внутри области DropTargetПример использования
DropTarget:
DropTarget(
onDragDone: (detail) {
for (final file in detail.files) {
print(file.path);
}
},
onDragEntered: (detail) => print('Файл в области'),
onDragExited: (detail) => print('Файл вне области'),
child: // some child
)
Также можно визуально показывать, что область готова принять файл, используя состояния, отслеживаемые через
onDragEntered и onDragExited.При работе с
desktop_drop есть несколько нюансов, о которых стоит помнить:▪️ Разные платформы могут по-разному обрабатывать события перетаскивания
▪️ С помощью
DropDoneDetails можно получать пути к файлам и обрабатывать их без необходимости загружать весь файл в память▪️ Для безопасной работы всегда проверяйте тип, размер и количество файлов
❕ Для полноценного функционала работы с файлами
desktop_drop можно комбинировать с file_picker и другими пакетами.❤️ — если было полезно
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly
👍3
Принцип инверсии зависимостей в Flutter: как сделать код более гибким и поддерживаемым 🌟
Привет, друзья! Сегодня мы поговорим о последнем принципе SOLID — принципе инверсии зависимостей (Dependency Inversion Principle) 🤔. Этот принцип помогает нам сделать код более гибким, поддерживаемым и легким для тестирования 🌈.
Итак, что же такое принцип инверсии зависимостей? 🤔 Он говорит о том, что высокоуровневые модули не должны зависеть от низкоуровневых, а оба должны зависеть от абстракций 📚. Абстракции, в свою очередь, не должны зависеть от деталей, а детали должны зависеть от абстракций 🔄.
По-простому, это означает, что «верх» приложения (экран, бизнес-логика) не должен быть привязан к конкретным реализациям «низа» (HTTP-клиент, база данных, SharedPreferences и т.д.) 🚫. Вместо этого, он должен зависеть только от интерфейсов 📝.
Но почему это так важно? 🤔 Когда высокоуровневый код напрямую знает о конкретных классах нижнего уровня, это приводит к проблемам 🚨:
- Любое изменение реализации «внизу» требует правок в бизнес-логике 📝
- Код сложно тестировать 🤯
- Система становится хрупкой 🌪️
- Нарушаются другие принципы SOLID 🚫
Принцип инверсии зависимостей как раз про то, чтобы «перевернуть» направление зависимости 🔄. Не высокоуровневый модуль зависит от деталей, а детали зависят от контракта, который описывает высокоуровневый модуль 📜.
Давайте рассмотрим пример с авторизацией 🔒. Мы можем создать абстракцию
Тогда наш
Итак, если вы видите в коде
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #SOLID #DependencyInversionPrinciple #cleanCode #programmingPrinciples
Привет, друзья! Сегодня мы поговорим о последнем принципе SOLID — принципе инверсии зависимостей (Dependency Inversion Principle) 🤔. Этот принцип помогает нам сделать код более гибким, поддерживаемым и легким для тестирования 🌈.
Итак, что же такое принцип инверсии зависимостей? 🤔 Он говорит о том, что высокоуровневые модули не должны зависеть от низкоуровневых, а оба должны зависеть от абстракций 📚. Абстракции, в свою очередь, не должны зависеть от деталей, а детали должны зависеть от абстракций 🔄.
По-простому, это означает, что «верх» приложения (экран, бизнес-логика) не должен быть привязан к конкретным реализациям «низа» (HTTP-клиент, база данных, SharedPreferences и т.д.) 🚫. Вместо этого, он должен зависеть только от интерфейсов 📝.
Но почему это так важно? 🤔 Когда высокоуровневый код напрямую знает о конкретных классах нижнего уровня, это приводит к проблемам 🚨:
- Любое изменение реализации «внизу» требует правок в бизнес-логике 📝
- Код сложно тестировать 🤯
- Система становится хрупкой 🌪️
- Нарушаются другие принципы SOLID 🚫
Принцип инверсии зависимостей как раз про то, чтобы «перевернуть» направление зависимости 🔄. Не высокоуровневый модуль зависит от деталей, а детали зависят от контракта, который описывает высокоуровневый модуль 📜.
Давайте рассмотрим пример с авторизацией 🔒. Мы можем создать абстракцию
IAuthRepository и две реализации: NetworkAuthRepository и FakeAuthRepository 📈. Тогда наш
LoginViewModel будет зависеть только от интерфейса IAuthRepository 📝, и мы сможем легко подменить реализацию в тестах или при изменении механизма авторизации 🔩. Итак, если вы видите в коде
new внутри бизнес-логики или ViewModel, создающий конкретные репозитории, сервисы и клиенты, — это хороший сигнал задуматься: не пора ли ввести интерфейс и развернуть зависимость? 🤔Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #SOLID #DependencyInversionPrinciple #cleanCode #programmingPrinciples
👍2
⏰ Приготовьтесь к проверке в AppStore! 📈
Сегодня мы поговорим о том, как увеличить вероятность успеха при отправке приложения на проверку в AppStore 📊.
Первая проверка нового приложения может занять около 7 дней, но повторные проверки проходят быстрее - обычно в течение 1-2 суток 🕒.
При подготовке приложения к проверке обратите внимание на следующие моменты:
- Совместимость: приложение должно быть совместимо с последними версиями iOS 📱.
- Стабильность: приложение не должно вылетать 🚫.
- Отсутствие вывода отладочной информации: перед публикацией стоит почистить все вызовы методов вывода отладочной информации 📝.
- Разрешения: приложение не должно запрашивать неиспользуемые разрешения, и каждое разрешение должно иметь четкое обоснование 📝.
- Нативные интеграции: обязательно обратите особое внимание на соблюдение всех этапов подключения и досконально проверьте работоспособность 📈.
- Интерактивность: при проверке всегда обращается внимание на реагирование приложения на действия пользователя 📊.
- Описание и оформление: особое внимание стоит уделить заполнению карточки приложения, описание должно быть достоверным и не должно содержать оценивающих суждений 📄.
- Сбор информации: перед публикацией вам требуется заполнить несколько форм с описанием того, какие данные собирает/передает ваше приложение 📊.
- Тестовые данные и контактная информация: если ваше приложение содержит какое-то ограничение в доступе, вам обязательно необходимо приложить инструкцию, контактные данные и тестовый аккаунт 📝.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly 📈💻📊
Сегодня мы поговорим о том, как увеличить вероятность успеха при отправке приложения на проверку в AppStore 📊.
Первая проверка нового приложения может занять около 7 дней, но повторные проверки проходят быстрее - обычно в течение 1-2 суток 🕒.
При подготовке приложения к проверке обратите внимание на следующие моменты:
- Совместимость: приложение должно быть совместимо с последними версиями iOS 📱.
- Стабильность: приложение не должно вылетать 🚫.
- Отсутствие вывода отладочной информации: перед публикацией стоит почистить все вызовы методов вывода отладочной информации 📝.
- Разрешения: приложение не должно запрашивать неиспользуемые разрешения, и каждое разрешение должно иметь четкое обоснование 📝.
- Нативные интеграции: обязательно обратите особое внимание на соблюдение всех этапов подключения и досконально проверьте работоспособность 📈.
- Интерактивность: при проверке всегда обращается внимание на реагирование приложения на действия пользователя 📊.
- Описание и оформление: особое внимание стоит уделить заполнению карточки приложения, описание должно быть достоверным и не должно содержать оценивающих суждений 📄.
- Сбор информации: перед публикацией вам требуется заполнить несколько форм с описанием того, какие данные собирает/передает ваше приложение 📊.
- Тестовые данные и контактная информация: если ваше приложение содержит какое-то ограничение в доступе, вам обязательно необходимо приложить инструкцию, контактные данные и тестовый аккаунт 📝.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly 📈💻📊
👍1
Создаем стеклянные интерфейсы в Flutter с помощью BackdropFilter! 🐈
Вы помните, как обновление дизайна от Apple с активным использованием glass effect вызвало у многих споры? Кому-то понравилось, а кто-то был просто в ужасе. Чуть позже к этому тренду подтянулись и другие продукты, и в итоге мы внезапно оказались в мире стеклянных интерфейсов.
А теперь давайте представим, что мы ТОЖЕ ХОТИМ ТАК ЖЕ! Как же быть? Есть 2 решения: воспользоваться готовыми библиотеками или реализовать все самостоятельно.
Для самостоятельной реализации нам понадобится виджет BackdropFilter. Он работает не с самим виджетом, а с тем, что находится под ним. BackdropFilter берет уже отрисованный фон и применяет к нему фильтр, в нашем случае — размытие.
Простейшая реализация может выглядеть так:
Если хочется воспользоваться готовыми решениями, можно присмотреться, например, к пакету glass_kit — внутри он более глубоко работает с BackdropFilter и помогает добиться аккуратного эффекта размытия.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly
Вы помните, как обновление дизайна от Apple с активным использованием glass effect вызвало у многих споры? Кому-то понравилось, а кто-то был просто в ужасе. Чуть позже к этому тренду подтянулись и другие продукты, и в итоге мы внезапно оказались в мире стеклянных интерфейсов.
А теперь давайте представим, что мы ТОЖЕ ХОТИМ ТАК ЖЕ! Как же быть? Есть 2 решения: воспользоваться готовыми библиотеками или реализовать все самостоятельно.
Для самостоятельной реализации нам понадобится виджет BackdropFilter. Он работает не с самим виджетом, а с тем, что находится под ним. BackdropFilter берет уже отрисованный фон и применяет к нему фильтр, в нашем случае — размытие.
Простейшая реализация может выглядеть так:
class GlassContainer extends StatelessWidget {
final double width;
final double height;
final Widget child;
const GlassContainer({
Key? key,
required this.width,
required this.height,
required this.child,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(25),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 18, sigmaY: 18),
child: Container(
width: width,
height: height,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.15),
borderRadius: BorderRadius.circular(25),
border: Border.all(
color: Colors.white.withOpacity(0.2),
width: 1.2,
),
),
child: child,
),
),
);
}
}
Если хочется воспользоваться готовыми решениями, можно присмотреться, например, к пакету glass_kit — внутри он более глубоко работает с BackdropFilter и помогает добиться аккуратного эффекта размытия.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly
❤3
Подойдут и для Android, и для iOS 🎄
Представьте, что вы можете настроить свой телефон новогодней заставкой, созданной с помощью технологии Flutter! 🎅️
Теперь это стало возможным! Для всех любителей вайба разработки на Flutter созданы специальные новогодние заставки, которые можно установить как на Android, так и на iOS.
Это отличный способ добавить немного праздничного настроения на ваш экран и поделиться им с друзьями или коллегами в рабочем чате.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly 🎄⬇️
Представьте, что вы можете настроить свой телефон новогодней заставкой, созданной с помощью технологии Flutter! 🎅️
Теперь это стало возможным! Для всех любителей вайба разработки на Flutter созданы специальные новогодние заставки, которые можно установить как на Android, так и на iOS.
Это отличный способ добавить немного праздничного настроения на ваш экран и поделиться им с друзьями или коллегами в рабочем чате.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly 🎄⬇️
Революция в создании интерфейсов: GenUI SDK для Flutter! 🚀
Привет, друзья! Сегодня я хочу рассказать вам о невероятном инструменте, который изменит способ создания динамических пользовательских интерфейсов в ваших приложениях Flutter - GenUI SDK! 🤩
Этот инструмент использует генеративный ИИ для создания адаптивных визуальных компонентов, таких как выпадающие списки, слайдеры, карусели товаров и формы с выбором даты. И все это меняется в реальном времени, в зависимости от намерений пользователя! 🔮
Но как это работает? 🤔 Процесс устроен как интерактивный цикл. Пользователь вводит запрос, а приложение отправляет его ИИ-агенту вместе с описанием доступных виджетов. Дальше ИИ-агент генерирует не только текст, но и описание интерфейса с помощью инструментов GenUI SDK. Обычно это структура в формате JSON, которую приложение десериализует и превращает в соответствующие Flutter-виджеты. 📈
GenUI SDK может отрисовывать стандартные компоненты постепенно, по мере генерации ответа большой языковой моделью (LLM). Так интерфейс появляется быстрее, и пользователю не нужно ждать, пока придет ответ целиком! 🕒
Что еще может GenUI SDK? 🤔
🔴 Генерировать UI из структурированных данных
🔴 Работать с настраиваемым каталогом виджетов
🔴 Обрабатывать события и поддерживать интерактивный диалог
Каталог виджетов задает словарь Flutter-компонентов, которые ИИ может использовать. Каждый CatalogItem содержит имя виджета, JSON-схему его свойств и builder-функцию для рендеринга. 📚
Реактивная система автоматически перестраивает виджеты при изменении данных в клиентской модели. А обработка событий позволяет фиксировать действия пользователя (клики, ввод текста) и отправлять обновленное состояние обратно ИИ для следующего шага. 🔄
Практическое применение GenUI SDK? 🤔 Подходит для AI-нативных приложений, где вместо текстового списка продуктов можно показать кликабельную карусель, а при планировании поездки — сгенерировать форму с полями ввода и слайдерами. 🗺
Полную новость читайте здесь и в блоге.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #AI #GenUI #SDK
Привет, друзья! Сегодня я хочу рассказать вам о невероятном инструменте, который изменит способ создания динамических пользовательских интерфейсов в ваших приложениях Flutter - GenUI SDK! 🤩
Этот инструмент использует генеративный ИИ для создания адаптивных визуальных компонентов, таких как выпадающие списки, слайдеры, карусели товаров и формы с выбором даты. И все это меняется в реальном времени, в зависимости от намерений пользователя! 🔮
Но как это работает? 🤔 Процесс устроен как интерактивный цикл. Пользователь вводит запрос, а приложение отправляет его ИИ-агенту вместе с описанием доступных виджетов. Дальше ИИ-агент генерирует не только текст, но и описание интерфейса с помощью инструментов GenUI SDK. Обычно это структура в формате JSON, которую приложение десериализует и превращает в соответствующие Flutter-виджеты. 📈
GenUI SDK может отрисовывать стандартные компоненты постепенно, по мере генерации ответа большой языковой моделью (LLM). Так интерфейс появляется быстрее, и пользователю не нужно ждать, пока придет ответ целиком! 🕒
Что еще может GenUI SDK? 🤔
🔴 Генерировать UI из структурированных данных
🔴 Работать с настраиваемым каталогом виджетов
🔴 Обрабатывать события и поддерживать интерактивный диалог
Каталог виджетов задает словарь Flutter-компонентов, которые ИИ может использовать. Каждый CatalogItem содержит имя виджета, JSON-схему его свойств и builder-функцию для рендеринга. 📚
Реактивная система автоматически перестраивает виджеты при изменении данных в клиентской модели. А обработка событий позволяет фиксировать действия пользователя (клики, ввод текста) и отправлять обновленное состояние обратно ИИ для следующего шага. 🔄
Практическое применение GenUI SDK? 🤔 Подходит для AI-нативных приложений, где вместо текстового списка продуктов можно показать кликабельную карусель, а при планировании поездки — сгенерировать форму с полями ввода и слайдерами. 🗺
Полную новость читайте здесь и в блоге.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #AI #GenUI #SDK
👎1
💠 Версионирование Flutter-приложений: простая, но важная тема! 🤔
Привет, друзья! Сегодня мы поговорим про версионирование Flutter-приложений 📱. Это тема простая, но часто вызывает вопросы у начинающих разработчиков 🤔.
Во Flutter-приложениях версия указывается в
Для удобства восприятия можно использовать буквенное представление:
Сочетание
Когда повышать каждый уровень версии приложения? 🤔
*
*
*
При повышении версии важно помнить: оно выполняется по уровню наиболее значимых изменений 📊.
А что с версией сборки? 🤔
*
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly 📱💻🔥
Привет, друзья! Сегодня мы поговорим про версионирование Flutter-приложений 📱. Это тема простая, но часто вызывает вопросы у начинающих разработчиков 🤔.
Во Flutter-приложениях версия указывается в
pubspec.yaml с ключом version. Например:
version: 1.2.3+4
Для удобства восприятия можно использовать буквенное представление:
version: A.B.C+D
Сочетание
A.B.C отвечает за версию приложения, а значение D — за версию сборки 📈.Когда повышать каждый уровень версии приложения? 🤔
*
A — мажорные изменения 🚀. Повышать этот уровень нужно, если ваше приложение сильно менялось, например, если вы полностью изменили дизайн, переработали пользовательские пути или радикально изменили ключевые функции 🔄.*
B — минорные изменения 📈. Сюда обычно относятся новые функционал и масштабирование старого, новые пользовательские пути без критичного изменения старых 📊.*
C — мелкие фиксы и доработки 🛠️. Стоит повысить уровень C, когда вы вносите правки по багам или верстке, повышаете производительность приложения или выполняете рефакторинг без влияния на ранее реализованные функции 📈.При повышении версии важно помнить: оно выполняется по уровню наиболее значимых изменений 📊.
А что с версией сборки? 🤔
*
D — версия конкретного билда 📈. Стандартно это значение инкрементируется в каждый новый билд вашего приложения, независимо от изменений внутри 📊.Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly 📱💻🔥
🔥3
🎅 Важные нюансы in-app покупок в Flutter-приложениях через App Store 📱💸
Привет, друзья! Сегодня мы поговорим о процессе покупки и получения информации о них в Flutter-приложениях через App Store 📈. Это важно знать, если вы создаете приложение с контентом, доступным только пользователям с подпиской 📊.
Мы рассмотрим три участника процесса: приложение, бэкенд и App Store 🤝. Итак, начнем!
1️⃣ Приложение: пользователь знакомится с доступными продуктами для покупки и осуществляет in-app покупку через определенные элементы интерфейса 🛍. Для этого необходимо интегрировать in_app_purchase в проект 📈.
2️⃣ App Store: выполняет процесс списания средств с привязанного счета и передает данные о транзакции дальше 📊. Здесь два варианта развития событий:
✔️ данные о транзакции возвращаются колбэком в приложение
✔️ данные о транзакции получает сам сервер через технологию Server-to-Server Notifications 📣
3️⃣ Бэкенд: получает колбэк от App Store с данными о транзакции и проверяет покупку перед выдачей прав пользователю 🔒.
4️⃣ Приложение: стучится на бэкенд, просит данные для конкретного авторизованного пользователя и отображает полученные данные 📊.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly
Привет, друзья! Сегодня мы поговорим о процессе покупки и получения информации о них в Flutter-приложениях через App Store 📈. Это важно знать, если вы создаете приложение с контентом, доступным только пользователям с подпиской 📊.
Мы рассмотрим три участника процесса: приложение, бэкенд и App Store 🤝. Итак, начнем!
1️⃣ Приложение: пользователь знакомится с доступными продуктами для покупки и осуществляет in-app покупку через определенные элементы интерфейса 🛍. Для этого необходимо интегрировать in_app_purchase в проект 📈.
2️⃣ App Store: выполняет процесс списания средств с привязанного счета и передает данные о транзакции дальше 📊. Здесь два варианта развития событий:
✔️ данные о транзакции возвращаются колбэком в приложение
✔️ данные о транзакции получает сам сервер через технологию Server-to-Server Notifications 📣
3️⃣ Бэкенд: получает колбэк от App Store с данными о транзакции и проверяет покупку перед выдачей прав пользователю 🔒.
4️⃣ Приложение: стучится на бэкенд, просит данные для конкретного авторизованного пользователя и отображает полученные данные 📊.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly
Понимать код, а не копировать 🤖💻
Привет, друзья! Сегодня мы хотим поговорить о понимании кода 🤓. Мы часто сталкиваемся с ситуациями, когда нам нужно использовать сторонние библиотеки или компоненты, но не всегда понимаем, как они работают 🤔. Это может привести к багам, неожиданным побочным эффектам и уязвимостям 🚨.
Почему это критично? 🤔
Непонимание контракта поля/метода может привести к багам и неожиданным побочным эффектам 🐜. Непроверенные апдейты зависимости могут сломать сборки и привести к runtime-ошибкам 🚧. Понимание реализации помогает правильно тестировать, оптимизировать и писать корректную миграцию при изменениях 📈.
Куда смотреть? 🗺
Мы можем найти информацию о библиотеках и компонентах на pub.dev, GitHub и в исходных кодах 📊. Мы должны читать README, CHANGELOG, примеры и отслеживать issues и PR 📝.
На что обращать внимание в поле/компоненте? 🔍
Мы должны понимать контракт, эффекты, производительность и депрексации 📊. Мы должны читать документацию и исходные коды, чтобы понять, как работает компонент 📚.
Практики по версиям и апдейтам 📈
Мы должны понимать major = breaking changes и читать CHANGELOG перед апдейтом 📝. Мы должны использовать pubspec.lock для воспроизводимости билдов и команды flutter pub outdated и flutter pub deps --style=compact 📊.
Краткий процесс обновления зависимости 📝
Мы должны исследовать пакет, обновить зависимость, прогнать тесты и развернуть на стейдже 🚀.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #mobiledevelopment #programming
Привет, друзья! Сегодня мы хотим поговорить о понимании кода 🤓. Мы часто сталкиваемся с ситуациями, когда нам нужно использовать сторонние библиотеки или компоненты, но не всегда понимаем, как они работают 🤔. Это может привести к багам, неожиданным побочным эффектам и уязвимостям 🚨.
Почему это критично? 🤔
Непонимание контракта поля/метода может привести к багам и неожиданным побочным эффектам 🐜. Непроверенные апдейты зависимости могут сломать сборки и привести к runtime-ошибкам 🚧. Понимание реализации помогает правильно тестировать, оптимизировать и писать корректную миграцию при изменениях 📈.
Куда смотреть? 🗺
Мы можем найти информацию о библиотеках и компонентах на pub.dev, GitHub и в исходных кодах 📊. Мы должны читать README, CHANGELOG, примеры и отслеживать issues и PR 📝.
На что обращать внимание в поле/компоненте? 🔍
Мы должны понимать контракт, эффекты, производительность и депрексации 📊. Мы должны читать документацию и исходные коды, чтобы понять, как работает компонент 📚.
Практики по версиям и апдейтам 📈
Мы должны понимать major = breaking changes и читать CHANGELOG перед апдейтом 📝. Мы должны использовать pubspec.lock для воспроизводимости билдов и команды flutter pub outdated и flutter pub deps --style=compact 📊.
Краткий процесс обновления зависимости 📝
Мы должны исследовать пакет, обновить зависимость, прогнать тесты и развернуть на стейдже 🚀.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #mobiledevelopment #programming
🪙 dart_amqp: полнофункциональный клиент для работы с протоколом AMQP 📚
Сегодня Катя из Flutter Dev Friflex хочет рассказать вам о библиотеке dart_amqp — полнофункциональном клиенте для работы с протоколом AMQP (Advanced Message Queue Protocol). Эта библиотека позволяет приложениям взаимодействовать с брокерами сообщений, такими как RabbitMQ 🐰.
Что такое dart_amqp?
dart_amqp — это клиентская библиотека для работы с AMQP-серверами, которая предоставляет удобный API для создания распределенных систем обмена сообщениями. Она поддерживает все основные возможности протокола AMQP, включая очереди, обменники, подтверждения сообщений и транзакции 📝.
Создание клиента
Для тонкой настройки подключения используется класс ConnectionSettings, который позволяет переопределить параметры по умолчанию:
Аутентификация
Библиотека поставляется с двумя провайдерами аутентификации:
▫️ PlainAuthenticationProvider — для простой аутентификации по логину и паролю
▫️ AmqPlainAuthenticationProvider — альтернативный вариант Plain-аутентификации
▫️ Можно создать собственный провайдер, реализовав интерфейс Authenticator
Работа с TLS
Для защищенных соединений можно передать SecurityContext:
Heartbeat
Heartbeat позволяет клиенту и серверу отслеживать активность соединения. Если обе стороны указывают ненулевой период (> 1 секунды), механизм активируется автоматически:
Работа с каналами
Каналы (Channels) — это виртуальные соединения внутри одного TCP-подключения:
Работа с очередями
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #amqp #rabbitmq
Сегодня Катя из Flutter Dev Friflex хочет рассказать вам о библиотеке dart_amqp — полнофункциональном клиенте для работы с протоколом AMQP (Advanced Message Queue Protocol). Эта библиотека позволяет приложениям взаимодействовать с брокерами сообщений, такими как RabbitMQ 🐰.
Что такое dart_amqp?
dart_amqp — это клиентская библиотека для работы с AMQP-серверами, которая предоставляет удобный API для создания распределенных систем обмена сообщениями. Она поддерживает все основные возможности протокола AMQP, включая очереди, обменники, подтверждения сообщений и транзакции 📝.
Создание клиента
Для тонкой настройки подключения используется класс ConnectionSettings, который позволяет переопределить параметры по умолчанию:
Client client = Client(
settings: ConnectionSettings(
host: "127.0.0.1",
port: 5672,
virtualHost: "/",
authProvider: PlainAuthenticationProvider("guest", "guest"),
maxConnectionAttempts: 1,
reconnectWaitTime: Duration(milliseconds: 1500),
),
);
Аутентификация
Библиотека поставляется с двумя провайдерами аутентификации:
▫️ PlainAuthenticationProvider — для простой аутентификации по логину и паролю
▫️ AmqPlainAuthenticationProvider — альтернативный вариант Plain-аутентификации
▫️ Можно создать собственный провайдер, реализовав интерфейс Authenticator
Работа с TLS
Для защищенных соединений можно передать SecurityContext:
Client client = Client(
settings: ConnectionSettings(
tlsContext: SecurityContext()
..setTrustedCertificates(path/to/cert.pem),
onBadCertificate: (certificate) => false,
),
);
Heartbeat
Heartbeat позволяет клиенту и серверу отслеживать активность соединения. Если обе стороны указывают ненулевой период (> 1 секунды), механизм активируется автоматически:
Client client = Client(
settings: ConnectionSettings(
tuningSettings: TuningSettings(
heartbeatPeriod: const Duration(seconds: 60),
),
),
);
Работа с каналами
Каналы (Channels) — это виртуальные соединения внутри одного TCP-подключения:
Channel channel = await client.channel();
Работа с очередями
// Создание очереди
Queue queue = await channel.queue("my_queue");
// Публикация сообщения
queue.publish("Flutter Friendly");
// Потребление сообщений
Consumer consumer = await queue.consume();
consumer.listen((AmqpMessage message) {
print("Получено: ${message.payloadAsString}");
message.ack(); // Подтвердить обработку
});
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #amqp #rabbitmq
💭 Ограничение доступа объектов в Dart: варианты и лучшие практики 🤔
Привет, друзья! Сегодня мы поговорим о механизмах ограничения доступа объектов в Dart 📚. Это важно для поддержания архитектурной дисциплины и предотвращения непредвиденного использования кода 🚫.
Есть несколько вариантов ограничения доступа объектов:
1️⃣ Использование символа
2️⃣ Аннотация
3️⃣ Аннотация
Важно понимать, что хотя реальное ограничение всего одно, аннотации тоже не стоит списывать со счетов 📝. Они подсвечивают намерение разработчика, обозначают границы ответственности и помогают поддерживать архитектурную дисциплину 🚀.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly 💻📱🔥
Привет, друзья! Сегодня мы поговорим о механизмах ограничения доступа объектов в Dart 📚. Это важно для поддержания архитектурной дисциплины и предотвращения непредвиденного использования кода 🚫.
Есть несколько вариантов ограничения доступа объектов:
1️⃣ Использование символа
_ в начале названия объекта. Это самый известный и эффективный способ ограничить доступ к объекту, поскольку он не позволяет использовать объект вне текущей библиотеки 🚫.
final String _privateData;
void _doExample() {}
2️⃣ Аннотация
@protected. Она указывает, что объект доступен только внутри класса и в классах-наследниках 👪. Однако, она не ограничивает компиляцию и работу программы, а только выдает предупреждение анализатора 📝.
class Parent {
@protected
void doProtected() {}
}
3️⃣ Аннотация
@visibleForTesting. Она позволяет сделать объект доступным только для тестов 📊. Это полезно для тех, кто покрывает проект тестами 📈.
class Parent {
@visibleForTesting
void doExample() {}
}
Важно понимать, что хотя реальное ограничение всего одно, аннотации тоже не стоит списывать со счетов 📝. Они подсвечивают намерение разработчика, обозначают границы ответственности и помогают поддерживать архитектурную дисциплину 🚀.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly 💻📱🔥
💭 Понимание параметра dirty в Flutter 🤔
Привет, друзья! Сегодня мы поговорим о параметре
Согласно официальной документации Flutter, виджет представляет собой конфигурацию, которая описывает, как именно должен выглядеть интерфейс. А вот элемент представляет конкретный виджет в определенном положении в дереве и отвечает за его жизненный цикл и состояние. 🌟
А
По умолчанию
После ряда проверок выполняется вызов метода
И здесь очень хорошо видно — на самом деле
Со Stateful-виджетами в целом понятно, а что с Stateless? Тут тоже ничего сложного. Хотя у виджета и нет своего состояния, но он все же может быть перестроен по ряду причин.
Например, если обновился непосредственный родитель: его метод build() выполнится заново и создаст новые конфигурации дочерних виджетов. Если конфигурация Stateless-виджета изменилась, его элемент будет обновлен и отмечен, как требующий перестроения.
Другой вариант — если виджет зависит от InheritedWidget, который обновился. В этом случае соответствующий элемент также будет помечен как dirty и перестроен.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly 💻📊👍
Привет, друзья! Сегодня мы поговорим о параметре
dirty у элемента во Flutter. 📱Согласно официальной документации Flutter, виджет представляет собой конфигурацию, которая описывает, как именно должен выглядеть интерфейс. А вот элемент представляет конкретный виджет в определенном положении в дереве и отвечает за его жизненный цикл и состояние. 🌟
А
dirty представляет собой индикатор состояния элемента. Он явно говорит — тут требуется перестроение. 🔄По умолчанию
dirty всегда false. Изменение значения флага наглядно можно увидеть на примере StatefulWidgeta. Допустим, нам надо обновить его состояние, и мы вызываем метод setState(). Посмотрим, что он делает под капотом.
@protected
void setState(VoidCallback fn) {
...
_element!.markNeedsBuild();
}
После ряда проверок выполняется вызов метода
markNeedsBuild(). Внутри него выполняется проверка: помечался ли ранее элемент для ребилда. Если не был, то он помечается и помещается в список dirty элементов.
void markNeedsBuild() {
...
if (dirty) {
return;
}
_dirty = true;
owner!.scheduleBuildFor(this);
}
И здесь очень хорошо видно — на самом деле
setState() не запускает моментальное перестроение виджета. Он лишь ставит элемент в очередь. А уже в следующем кадре Flutter обработает список dirty-элементов и перестроит их точечно. 📈Со Stateful-виджетами в целом понятно, а что с Stateless? Тут тоже ничего сложного. Хотя у виджета и нет своего состояния, но он все же может быть перестроен по ряду причин.
Например, если обновился непосредственный родитель: его метод build() выполнится заново и создаст новые конфигурации дочерних виджетов. Если конфигурация Stateless-виджета изменилась, его элемент будет обновлен и отмечен, как требующий перестроения.
Другой вариант — если виджет зависит от InheritedWidget, который обновился. В этом случае соответствующий элемент также будет помечен как dirty и перестроен.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly 💻📊👍
👍1
⭐ Раскрываем секреты BuildContext в Flutter! 🤔
Привет, друзья! Сегодня мы поговорим о чем-то действительно важном в Flutter — BuildContext. 📚
Это специальный объект, который представляет собой ссылку на конкретное место виджета в дереве элементов. По сути, это идентификатор позиции виджета в иерархии приложения. 🗺️
Каждый виджет при построении получает свой уникальный BuildContext. Именно через него виджет может взаимодействовать с другими частями дерева: получать доступ к родительским виджетам, темам, навигации и многому другому. 🌐
Давайте посмотрим, как это работает на практике:
Этот context и есть BuildContext. Он связывает наш виджет с конкретным элементом в дереве. Через него Flutter понимает, где именно находится виджет и как с ним работать. 📈
Но почему BuildContext так важен? 🤔
Возьмем простой пример — доступ к теме приложения:
Метод Theme.of(context) использует BuildContext, чтобы подняться вверх по дереву виджетов и найти ближайший ThemeData. Без context это было бы невозможно — Flutter просто не знал бы, откуда начинать поиск. 🔍
То же самое происходит с навигацией:
Navigator ищет ближайший Navigator в дереве, используя переданный BuildContext как отправную точку. 📍
Но есть одна распространенная ошибка, которую стоит избегать: использование BuildContext до того, как виджет добавили в дерево, или после того, как его удалили. 🚫
Например:
Если виджет удалят из дерева за эти две секунды, использование context приведет к ошибке. Для таких случаев стоит проверять mounted в StatefulWidget или использовать более безопасные подходы. 🚨
BuildContext играет особую роль при работе с InheritedWidget. Именно через context виджеты подписываются на изменения:
При таком вызове Flutter регистрирует зависимость текущего виджета от MyInheritedWidget через BuildContext. Когда InheritedWidget обновится, все зависимые от него виджеты будут автоматически перестроены. 🔄
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #BuildContext #InheritedWidget
Привет, друзья! Сегодня мы поговорим о чем-то действительно важном в Flutter — BuildContext. 📚
Это специальный объект, который представляет собой ссылку на конкретное место виджета в дереве элементов. По сути, это идентификатор позиции виджета в иерархии приложения. 🗺️
Каждый виджет при построении получает свой уникальный BuildContext. Именно через него виджет может взаимодействовать с другими частями дерева: получать доступ к родительским виджетам, темам, навигации и многому другому. 🌐
Давайте посмотрим, как это работает на практике:
@override
Widget build(BuildContext context) {
return Container(
child: Text('Привет'),
);
}
Этот context и есть BuildContext. Он связывает наш виджет с конкретным элементом в дереве. Через него Flutter понимает, где именно находится виджет и как с ним работать. 📈
Но почему BuildContext так важен? 🤔
Возьмем простой пример — доступ к теме приложения:
final theme = Theme.of(context);
Метод Theme.of(context) использует BuildContext, чтобы подняться вверх по дереву виджетов и найти ближайший ThemeData. Без context это было бы невозможно — Flutter просто не знал бы, откуда начинать поиск. 🔍
То же самое происходит с навигацией:
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => NextScreen()),
);
Navigator ищет ближайший Navigator в дереве, используя переданный BuildContext как отправную точку. 📍
Но есть одна распространенная ошибка, которую стоит избегать: использование BuildContext до того, как виджет добавили в дерево, или после того, как его удалили. 🚫
Например:
@override
Widget build(BuildContext context) {
Future.delayed(Duration(seconds: 2), () {
// Опасно! Context может быть уже невалидным
showDialog(context: context, builder: (_) => AlertDialog());
});
return Container();
}
Если виджет удалят из дерева за эти две секунды, использование context приведет к ошибке. Для таких случаев стоит проверять mounted в StatefulWidget или использовать более безопасные подходы. 🚨
BuildContext играет особую роль при работе с InheritedWidget. Именно через context виджеты подписываются на изменения:
final data = MyInheritedWidget.of(context);
При таком вызове Flutter регистрирует зависимость текущего виджета от MyInheritedWidget через BuildContext. Когда InheritedWidget обновится, все зависимые от него виджеты будут автоматически перестроены. 🔄
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #BuildContext #InheritedWidget
👍2
Понимание Keys во Flutter: зачем они нужны и как их использовать 🦋
Привет, друзья! Сегодня мы поговорим о Keys во Flutter, которые помогают сопоставлять новые виджеты с уже существующими элементами при обновлении дерева. Но для чего же они нужны и как их использовать? 🤔
Когда Flutter получает новый список виджетов при ребилде, он пытается сопоставить их с существующими элементами по позиции и типу. Но если порядок элементов изменился или виджеты одного типа поменялись местами, состояние может перескочить на другой элемент. Это происходит потому, что Flutter повторно использовал элемент по индексу. 📝
Давайте рассмотрим пример проблемы без ключей:
При перестановке элементов состояния могут перепутаться. Чтобы избежать этого, мы можем использовать Keys. 🚀
Существует несколько типов ключей:
▫️ ValueKey<T> — ключ по значению (идеален для id-модели).
▫️ ObjectKey — сравнение по == объекта.
▫️ UniqueKey — каждый раз новый ключ (заставляет создать новый Element; сбрасывает состояние).
▫️ GlobalKey — глобальная уникальность + доступ к State/Context; использовать экономно (дорогой).
Итак, когда использовать Keys?
▫️ Динамические списки с добавлением/удалением/реордером — ValueKey(id).
▫️ Формы, доступ к State извне — GlobalKey (только при необходимости).
А когда не нужен Key?
В статичных списках и простых элементах без внутреннего состояния. Не ставьте ключи на всякий — если они лишние, то усложняют и могут ухудшать производительность.
Рекомендации:
▫️ Для сущностей с постоянным id — ValueKey(id).
▫️ Если хотите сбросить состояние — UniqueKey.
▫️ GlobalKey — только для специфических задач (формы, навигация, тесты).
▫️ Если состояние перескакивает — сначала добавьте ключи, а не перестраивайте архитектуру.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly
Привет, друзья! Сегодня мы поговорим о Keys во Flutter, которые помогают сопоставлять новые виджеты с уже существующими элементами при обновлении дерева. Но для чего же они нужны и как их использовать? 🤔
Когда Flutter получает новый список виджетов при ребилде, он пытается сопоставить их с существующими элементами по позиции и типу. Но если порядок элементов изменился или виджеты одного типа поменялись местами, состояние может перескочить на другой элемент. Это происходит потому, что Flutter повторно использовал элемент по индексу. 📝
Давайте рассмотрим пример проблемы без ключей:
import 'package:flutter/material.dart';
class ItemWidget extends StatefulWidget {
final String title;
ItemWidget(this.title);
@override
_ItemWidgetState createState() => _ItemWidgetState();
}
class _ItemWidgetState extends State<ItemWidget> {
int counter = 0;
@override
Widget build(BuildContext context) {
return ListTile(
title: Text('${widget.title} ($counter)'),
trailing: IconButton(
icon: Icon(Icons.add),
onPressed: () => setState(() => counter++),
),
);
}
}
При перестановке элементов состояния могут перепутаться. Чтобы избежать этого, мы можем использовать Keys. 🚀
Существует несколько типов ключей:
▫️ ValueKey<T> — ключ по значению (идеален для id-модели).
▫️ ObjectKey — сравнение по == объекта.
▫️ UniqueKey — каждый раз новый ключ (заставляет создать новый Element; сбрасывает состояние).
▫️ GlobalKey — глобальная уникальность + доступ к State/Context; использовать экономно (дорогой).
Итак, когда использовать Keys?
▫️ Динамические списки с добавлением/удалением/реордером — ValueKey(id).
▫️ Формы, доступ к State извне — GlobalKey (только при необходимости).
А когда не нужен Key?
В статичных списках и простых элементах без внутреннего состояния. Не ставьте ключи на всякий — если они лишние, то усложняют и могут ухудшать производительность.
Рекомендации:
▫️ Для сущностей с постоянным id — ValueKey(id).
▫️ Если хотите сбросить состояние — UniqueKey.
▫️ GlobalKey — только для специфических задач (формы, навигация, тесты).
▫️ Если состояние перескакивает — сначала добавьте ключи, а не перестраивайте архитектуру.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly
❤1
Добавляем биометрическую аутентификацию в наше Flutter-приложение с помощью плагина local_auth 🚀
Привет, друзья! 👋 Сегодня мы поговорим о том, как добавить аутентификацию по биометрии в наше Flutter-приложение. Для этого мы будем использовать плагин local_auth. Этот плагин позволяет проводить локальную аутентификацию с помощью настроек, которые есть на устройстве, таких как пин-код, сканирование отпечатка пальца или идентификация по лицу (FaceID) 📊.
Плагин работает очень просто: он не проверяет код или лицо и отпечаток пальца самостоятельно, а обращается в систему, запрашивает проверку, и возвращает в приложение простое булево значение. Давайте разберем методы плагина подробнее ⬇️.
Для начала нужно создать экземпляр класса
Метод
Еще можно получить список всех доступных на устройстве способов аутентификации по биометрии. Если на устройстве не настроен вход по отпечатку пальца или по лицу, то список придет пустым.
А здесь внимательно:
Дальше самое интересное — проверка. Она выполняется с помощью метода
Когда будете интегрировать этот плагин в проект, уделите особое внимание обработке разных сценариев. Потому что смартфонов на рынке много, и важно, чтобы у каждого пользователя был доступ.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #биометрическаяаутентификация #local_auth
Привет, друзья! 👋 Сегодня мы поговорим о том, как добавить аутентификацию по биометрии в наше Flutter-приложение. Для этого мы будем использовать плагин local_auth. Этот плагин позволяет проводить локальную аутентификацию с помощью настроек, которые есть на устройстве, таких как пин-код, сканирование отпечатка пальца или идентификация по лицу (FaceID) 📊.
Плагин работает очень просто: он не проверяет код или лицо и отпечаток пальца самостоятельно, а обращается в систему, запрашивает проверку, и возвращает в приложение простое булево значение. Давайте разберем методы плагина подробнее ⬇️.
Для начала нужно создать экземпляр класса
LocalAuthentication. Через него будут выполняться все операции.
final localAuth = LocalAuthentication();
Метод
isDeviceSupported() проверит наличие любого способа аутентификации на устройстве. А canCheckBiometrics() ответит, доступна ли аутентификация именно по биометрии.
final isDeviceSupported = await localAuth.isDeviceSupported();
final canAuthenticate = await localAuth.canCheckBiometrics;
Еще можно получить список всех доступных на устройстве способов аутентификации по биометрии. Если на устройстве не настроен вход по отпечатку пальца или по лицу, то список придет пустым.
final list = await localAuth.getAvailableBiometrics();
А здесь внимательно:
getAvailableBiometrics вернет список только тех биометрических функций, которые настроены пользователем на устройстве. А флаг canAuthenticate просто покажет их наличие.Дальше самое интересное — проверка. Она выполняется с помощью метода
authenticate(). В него можно добавить строку с описанием причины запроса аутентификации. Этот текст пользователь увидит на экране. Также можно задавать ограничения. Например, установить true флаг biometricOnly. Тогда ввод системного пин-кода не будет запрашиваться.
final successAuth = await localAuth.authenticate(
localizedReason: 'ВОЙДИТЕ',
biometricOnly: true,
);
Когда будете интегрировать этот плагин в проект, уделите особое внимание обработке разных сценариев. Потому что смартфонов на рынке много, и важно, чтобы у каждого пользователя был доступ.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly #биометрическаяаутентификация #local_auth
🪙 Получаем информацию от аппаратных датчиков движения во Flutter! 🤩
Знаете, как во Flutter-приложении получать информацию от аппаратных датчиков движения? 🤔 Сейчас узнаете! 😊
В этой задаче вам поможет плагин sensors_plus. Как описывают его разработчики — он дает возможность вашему Flutter-приложению обращаться к сенсорам устройства, таким как:
▪️ акселерометр
▪️ гироскоп
▪️ барометр
▪️ магнитометр
Как это работает? Через плагин приложение обращается в платформу. Натив считывает данные с сенсоров и полученные данные передает во Flutter посредством Streams (потоков). В приложении же вам достаточно подписаться на необходимый поток с данными.
Библиотека дает возможность отслеживать данные по пяти основным событиям:
✔️
✔️
✔️
✔️
✔️
Использовать очень просто. Достаточно подписаться на поток данных по необходимому событию.
Не забывайте закрывать подписки
Для чего может быть полезно? Представим, вам нужно сделать реализацию как в банках — при перевороте экрана требуется скрывать или открывать данные на экране. Или при тряске устройства небходимо выполнять перезапрос данных. Для всех этих задач sensors_plus точно будет полезен.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly
Знаете, как во Flutter-приложении получать информацию от аппаратных датчиков движения? 🤔 Сейчас узнаете! 😊
В этой задаче вам поможет плагин sensors_plus. Как описывают его разработчики — он дает возможность вашему Flutter-приложению обращаться к сенсорам устройства, таким как:
▪️ акселерометр
▪️ гироскоп
▪️ барометр
▪️ магнитометр
Как это работает? Через плагин приложение обращается в платформу. Натив считывает данные с сенсоров и полученные данные передает во Flutter посредством Streams (потоков). В приложении же вам достаточно подписаться на необходимый поток с данными.
Библиотека дает возможность отслеживать данные по пяти основным событиям:
✔️
AccelerometerEvent — ускорение устройства. ✔️
UserAccelerometerEvent — в отличие от AccelerometerEvent отражает только фактическое ускорение устройства. ✔️
GyroscopeEvent — вращение устройства✔️
MagnetometerEvent — данные окружающего магнитного поля. ✔️
BarometerEvent — текущее атмосферное давлениеИспользовать очень просто. Достаточно подписаться на поток данных по необходимому событию.
late StreamSubscription<AccelerometerEvent> _accelerometerSubscription;
...
_accelerometerSubscription = accelerometerEventStream().listen((event) {
print(x: ${event.x}, y: ${event.y}, z: ${event.z});
});
Не забывайте закрывать подписки
_accelerometerSubscription.cancel();
Для чего может быть полезно? Представим, вам нужно сделать реализацию как в банках — при перевороте экрана требуется скрывать или открывать данные на экране. Или при тряске устройства небходимо выполнять перезапрос данных. Для всех этих задач sensors_plus точно будет полезен.
Полную новость читайте здесь.
FlutterPulse — канал о мире Flutter!
#flutter #dart #FlutterPulse #FlutterPulseNews #flutterfriendly
❤1