🚀 Нас уже больше 400! 🎉
Спасибо каждому, кто читает, комментирует и заряжает канал энергией Flutter! 💙
В честь этой мини-юбилейной отметки — пора внести немного свежего воздуха 💨 и объявить о небольших, но важных изменениях 👇
📊 Изменения в новостях о пакетах:
🧠 В недавнем опросе правильными были варианты:
✅ «Уменьшится количество новостей»
✅ «Произойдёт модернизация старой рубрики»
✅ «Добавится новая рубрика»
❌ Конечно, администратор канала, название и направление развития не изменится! 😄
🤔 Почему? Показалось, что слишкоммного контента про обновления пакетов. Было две новости, стало одна — лаконичнее и полезнее!
🕘 Теперь она будет выходить каждый день в 9:00 по Москве
📦 В ней: топ-обновлённые пакеты, changelog и версии (теперь без багов — спасибо новому парсеру 🙌)
📌 Новый хэштег: #FlutterPulseBestPackages
📬 А рубрика про новые пакеты останется на месте — еженедельно, по понедельникам в 18:00
📌 Хэштег: #FlutterPulseBestNewPackages
🆕 Новая рубрика — Flutter-гайды!
Да, теперь на канале будут мои личные советы и гайды по Flutter 🧑🏫
Коротко, чётко, с примерами и по делу!
📅 Каждый день в 13:00 по Москве
📌 Хэштег: #FlutterPulseTips
👉 Первый выпуск уже СЕГОДНЯ!
💬 Очень жду от вас фидбэка:
Что бы вы хотели видеть на канале? Что нравится? Что можно улучшить?
Лайки, комментарии, идеи — всё читаю и ценю 🙏
Спасибо, что вы со мной 💙
#FlutterPulse #FlutterPulseBestPackages #FlutterPulseBestNewPackages #FlutterPulseTips #Flutter #Dart #PubDev
Спасибо каждому, кто читает, комментирует и заряжает канал энергией Flutter! 💙
В честь этой мини-юбилейной отметки — пора внести немного свежего воздуха 💨 и объявить о небольших, но важных изменениях 👇
📊 Изменения в новостях о пакетах:
🧠 В недавнем опросе правильными были варианты:
✅ «Уменьшится количество новостей»
✅ «Произойдёт модернизация старой рубрики»
✅ «Добавится новая рубрика»
❌ Конечно, администратор канала, название и направление развития не изменится! 😄
🤔 Почему? Показалось, что слишком
🕘 Теперь она будет выходить каждый день в 9:00 по Москве
📦 В ней: топ-обновлённые пакеты, changelog и версии (теперь без багов — спасибо новому парсеру 🙌)
📌 Новый хэштег: #FlutterPulseBestPackages
📬 А рубрика про новые пакеты останется на месте — еженедельно, по понедельникам в 18:00
📌 Хэштег: #FlutterPulseBestNewPackages
🆕 Новая рубрика — Flutter-гайды!
Да, теперь на канале будут мои личные советы и гайды по Flutter 🧑🏫
Коротко, чётко, с примерами и по делу!
📅 Каждый день в 13:00 по Москве
📌 Хэштег: #FlutterPulseTips
👉 Первый выпуск уже СЕГОДНЯ!
💬 Очень жду от вас фидбэка:
Что бы вы хотели видеть на канале? Что нравится? Что можно улучшить?
Лайки, комментарии, идеи — всё читаю и ценю 🙏
Спасибо, что вы со мной 💙
#FlutterPulse #FlutterPulseBestPackages #FlutterPulseBestNewPackages #FlutterPulseTips #Flutter #Dart #PubDev
Умный запрос оценки
Не спамите запросом оценки! 🤔
Почему?
• Apple Store ограничивает запрос оценки через нативное всплывающее окно до 2 раз в год 📆
• Google Play Store ограничивает запрос почти 2 раза каждые 3 месяца... 🤷♂️
• Вы не хотите раздражать пользователей и получать плохие оценки 😠
Мы создаем метод, подобный
Вы можете хранить
Также вы можете использовать этот же подход, чтобы открыть страницу приложения в магазине или напрямую запросить оценку. Страница в магазине требует больше усилий от пользователя, но текстовые отзывы более ценны 💬
Оцените новую рубрику! 👍👎
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDev #SmartRating #RatingSystem #UXTips
Не спамите запросом оценки! 🤔
Почему?
• Apple Store ограничивает запрос оценки через нативное всплывающее окно до 2 раз в год 📆
• Google Play Store ограничивает запрос почти 2 раза каждые 3 месяца... 🤷♂️
• Вы не хотите раздражать пользователей и получать плохие оценки 😠
Мы создаем метод, подобный
showDialog
, чтобы можно было запрашивать оценку где угодно в приложении 📱
class RatingSettings {
final Duration delayBeforeAsking;
final Duration delayBeforeAskingAgain;
RatingSettings({
required this.delayBeforeAsking,
required this.delayBeforeAskingAgain,
});
}
class Rating {
final RatingApi _ratingApi;
final RatingSettings settings;
final DateTime? lastAskingDate;
final DateTime userCreationDate;
final DateTime _current;
final bool hasRateApp;
Rating({
required this.settings,
required RatingApi ratingApi,
required this.lastAskingDate,
required this.userCreationDate,
required this.hasRateApp,
}) : _ratingApi = ratingApi,
_current = DateTime.now();
bool shouldAsk() {
// Если пользователь уже оценил приложение или мы не знаем дату создания пользователя, пропустим
if (userCreationDate == null || hasRateApp) {
return false;
}
final appInstallDiff = _current.difference(userCreationDate);
if (appInstallDiff < settings.delayBeforeAsking) {
return false;
}
if (lastAskingDate == null) {
return true;
}
return lastAskingDate!.difference(_current) > settings.delayBeforeAskingAgain;
}
Future<void> openStoreListing() => _ratingApi.openStoreListing();
Future<void> showRatingDialog() => _ratingApi.showRatingDialog();
}
void showRatingPopup(WidgetRef ref) {
final ratingRepository = ref.watch(ratingRepositoryProvider);
final userState = ref.watch(userStateNotifierProvider);
final ratingFuture = ratingRepository.getUserState(user);
ratingFuture.then((rating) {
if (rating.shouldAsk()) {
rating.delay();
showDialog(
context: context,
builder: (context) => AlertDialog.adaptive(
title: const Text('Спасибо за использование ULY'),
content: const Text('У вас есть минута, чтобы оставить отзыв?'),
actions: [
TextButton(
child: const Text('Позже'),
onPressed: () async {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Да, конечно!'),
onPressed: () async {
Navigator.of(context).pop();
rating.rate();
},
),
],
),
);
}
});
}
Вы можете хранить
RatingSettings
в Firebase Remote Config, чтобы регулировать эти настройки без пересборки приложения и находить оптимальные значения 🔧Также вы можете использовать этот же подход, чтобы открыть страницу приложения в магазине или напрямую запросить оценку. Страница в магазине требует больше усилий от пользователя, но текстовые отзывы более ценны 💬
Оцените новую рубрику! 👍👎
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDev #SmartRating #RatingSystem #UXTips
Как показать уведомление Toast с Riverpod
Избавляемся от требования BuildContext
При разработке Flutter-приложений часто возникает необходимость отображать уведомления или сообщения Toast. Использование Riverpod для управления состоянием приложения позволяет упростить этот процесс. В этой статье мы рассмотрим, как показать уведомление Toast, используя Riverpod, и избавимся от необходимости передавать BuildContext.
Для начала нам нужно создать провайдер, который будет отвечать за отображение Toast-уведомлений. Мы будем использовать пакет
Далее, нам нужно создать глобальный ключ навигации, чтобы избавиться от требования BuildContext:
Теперь мы можем использовать наш провайдер
Таким образом, мы можем легко отображать Toast-уведомления в нашем Flutter-приложении, используя Riverpod и пакет
Оцените новую рубрику и напишите в комментариях, что бы вы хотели видеть в следующих выпусках! 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #Riverpod #ToastNotifications #FlutterTips
Избавляемся от требования BuildContext
При разработке Flutter-приложений часто возникает необходимость отображать уведомления или сообщения Toast. Использование Riverpod для управления состоянием приложения позволяет упростить этот процесс. В этой статье мы рассмотрим, как показать уведомление Toast, используя Riverpod, и избавимся от необходимости передавать BuildContext.
Для начала нам нужно создать провайдер, который будет отвечать за отображение Toast-уведомлений. Мы будем использовать пакет
another_flushbar
для отображения уведомлений.
import 'package:another_flushbar/flushbar.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
// Это наш провайдер из riverpod для вызова метода toast из любой функции riverpod
final toastProvider = Provider<ToastBuilder>((ref) => ToastBuilder());
class ToastBuilder {
void success({
required String title,
required String text,
}) {
// Продолжительность показа уведомления
Duration duration = const Duration(seconds: 3);
_showSuccessToast(
context: navigatorKey.currentContext!, // Используем глобальный ключ навигации
title: title,
text: text,
duration: duration,
);
}
void _showSuccessToast({
required BuildContext context,
required String title,
required String text,
required Duration duration,
}) {
// Хак, чтобы предотвратить показ toast во время тестов
if (Platform.environment.containsKey('FLUTTER_TEST')) {
return;
}
if (!context.mounted) {
return; // Проверяем, смонтирован ли контекст
}
// Используем пакет another_flushbar, но есть много других отличных решений
Flushbar(
flushbarPosition: FlushbarPosition.TOP,
title: title,
message: text,
// Здесь можно добавить стили
).show(context);
}
}
Далее, нам нужно создать глобальный ключ навигации, чтобы избавиться от требования BuildContext:
/// Не забудьте создать этот глобальный ключ и добавить его в ваш основной маршрутизатор
final navigatorKey = GlobalKey<NavigatorState>();
Теперь мы можем использовать наш провайдер
toastProvider
в любом месте приложения, где доступен Riverpod, чтобы показать Toast-уведомление:
import 'package:flutter_riverpod/flutter_riverpod.dart';
@Riverpod(keepAlive: false)
class EditAlbumNotifier extends _$EditAlbumNotifier {
// ...
Future<void> save() async {
// ...
// Например, после сохранения альбома
ref.read(toastProvider).success(
title: "Успех",
text: "Журнал архивирован",
);
}
}
Таким образом, мы можем легко отображать Toast-уведомления в нашем Flutter-приложении, используя Riverpod и пакет
another_flushbar
, а также избавиться от необходимости передавать BuildContext, используя глобальный ключ навигации.Оцените новую рубрику и напишите в комментариях, что бы вы хотели видеть в следующих выпусках! 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #Riverpod #ToastNotifications #FlutterTips
Как открыть страницу настроек приложения в системе
Привет, друзья! 👋 Сегодня мы поделимся с вами полезным советом о том, как открыть страницу настроек вашего приложения на устройстве пользователя. 📱💻
Зачем это нужно? 🤔
Например, если пользователь отклонил уведомления, система больше не будет запрашивать разрешение. В этом случае вы можете помочь пользователю перейти в настройки и включить уведомления вручную. 🔔
Используем url_launcher 📲
Или проще с permission_handler 📦
Оцените новую рубрику и напишите в комментариях, что вы думаете о ней! 💬 Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDev #ProgrammingTips #CodingTips
Привет, друзья! 👋 Сегодня мы поделимся с вами полезным советом о том, как открыть страницу настроек вашего приложения на устройстве пользователя. 📱💻
Зачем это нужно? 🤔
Например, если пользователь отклонил уведомления, система больше не будет запрашивать разрешение. В этом случае вы можете помочь пользователю перейти в настройки и включить уведомления вручную. 🔔
Используем url_launcher 📲
import 'package:url_launcher/url_launcher.dart';
Future<void> openSettings() async {
Uri url;
if (defaultTargetPlatform == TargetPlatform.iOS) {
url = Uri.parse('app-settings:');
} else if (defaultTargetPlatform == TargetPlatform.android) {
url = Uri.parse('package:uly.vlog.diary');
} else {
throw Exception('Unsupported platform');
}
if (await canLaunchUrl(url)) {
await launchUrl(url);
} else {
throw 'Could not launch $url';
}
}
Или проще с permission_handler 📦
import 'package:permission_handler/permission_handler.dart';
openAppSettings();
Оцените новую рубрику и напишите в комментариях, что вы думаете о ней! 💬 Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDev #ProgrammingTips #CodingTips
Flutter tips: how to create a responsive layout
Адаптивный макет: советы по Flutter
Привет, разработчики! 👋 Сегодня мы поговорим о создании адаптивного макета в Flutter. 📱💻
Адаптация макета под разные размеры экранов 📐
Чтобы ваше приложение выглядело отлично на разных устройствах, необходимо адаптировать макет под различные размеры экранов. 📊
Пример использования:
Этот код позволяет создать адаптивный макет, который будет корректно отображаться на различных устройствах. 📱💻
Оцените новую рубрику и напишите своё мнение в комментариях! 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDev #UIUX #ProgrammingTips #CodingTips
Адаптивный макет: советы по Flutter
Привет, разработчики! 👋 Сегодня мы поговорим о создании адаптивного макета в Flutter. 📱💻
Адаптация макета под разные размеры экранов 📐
Чтобы ваше приложение выглядело отлично на разных устройствах, необходимо адаптировать макет под различные размеры экранов. 📊
import 'package:flutter/widgets.dart';
// Перечисление типов устройств
enum DeviceType { small, medium, large, xlarge }
// Виджет, который адаптирует свой контент к текущему типу устройства
class ResponsiveLayout extends StatelessWidget {
final Widget? small; // Виджет для маленьких экранов
final Widget? medium; // Виджет для средних экранов
final Widget? large; // Виджет для больших экранов
final Widget? xlarge; // Виджет для очень больших экранов
const ResponsiveLayout({
super.key,
required this.small,
this.medium,
this.large,
this.xlarge,
});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
// Определение типа устройства на основе ширины экрана
switch (getDeviceType(constraints)) {
case DeviceType.small:
return small!; // Возвращаем виджет для маленьких экранов
case DeviceType.medium:
return medium ?? small!; // Возвращаем виджет для средних экранов или fallback к маленькому
case DeviceType.large:
return large ?? medium ?? small!; // Возвращаем виджет для больших экранов или fallback
case DeviceType.xlarge:
return xlarge ?? large ?? medium ?? small!; // Возвращаем виджет для очень больших экранов или fallback
}
},
);
}
// Метод для определения типа устройства на основе ограничений
DeviceType getDeviceType(BoxConstraints constraints) {
return switch (constraints.maxWidth) {
> 1200 => DeviceType.xlarge, // Очень большой экран
> 1024 => DeviceType.large, // Большой экран
> 768 => DeviceType.medium, // Средний экран
_ => DeviceType.small, // Маленький экран
};
}
}
Пример использования:
ResponsiveLayout(
small: SigninForm(), // Форма входа для маленьких экранов
medium: Center( // Центрирование для средних экранов и больше
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 600), // Ограничение максимальной ширины
child: SigninForm(), // Форма входа
),
),
)
Этот код позволяет создать адаптивный макет, который будет корректно отображаться на различных устройствах. 📱💻
Оцените новую рубрику и напишите своё мнение в комментариях! 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDev #UIUX #ProgrammingTips #CodingTips
Flutter tips: Расширения для работы с датами
Привет, подписчики! Сегодня мы поговорим о полезных расширениях для работы с датами в Flutter. Расширения позволяют писать более чистый и читаемый код, что упрощает разработку и поддержку приложений.
Использование расширений для дат
Расширения в Dart позволяют добавлять новые методы к существующим классам. В данном случае мы будем использовать расширение для класса
Пример использования
Теперь давайте рассмотрим пример использования этих расширений. Вместо того, чтобы писать громоздкий код для проверки, является ли дата сегодняшней, мы можем использовать метод
Это намного чище и читаемее, чем:
Оцените новую рубрику! Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #CodingTips #AppDev #FlutterTips
Привет, подписчики! Сегодня мы поговорим о полезных расширениях для работы с датами в Flutter. Расширения позволяют писать более чистый и читаемый код, что упрощает разработку и поддержку приложений.
Использование расширений для дат
Расширения в Dart позволяют добавлять новые методы к существующим классам. В данном случае мы будем использовать расширение для класса
DateTime
, чтобы добавить полезные методы для работы с датами.extension DateExtension on DateTime {
DateTime get firstDayOfWeek {
return subtract(Duration(days: weekday - 1));
}
DateTime get lastDayOfWeek {
return add(Duration(days: 7 - weekday));
}
DateTime get firstDayOfMonth {
return DateTime(year, month);
}
bool isToday() => isSameDay(DateTime.now());
bool isSameDay(DateTime other) {
return day == other.day && month == other.month && year == other.year;
}
bool isAfterDayOrEqual(DateTime other) {
return isAfter(other) || isSameDay(other);
}
bool isBeforeDayOrEqual(DateTime other) {
return isBefore(other) || isSameDay(other);
}
bool isSameWeek(DateTime other) {
final kfirstDayOfTheWeek = firstDayOfWeek;
return other.isAfterDayOrEqual(kfirstDayOfTheWeek) &&
other.isBefore(lastDayOfWeek);
}
}
Пример использования
Теперь давайте рассмотрим пример использования этих расширений. Вместо того, чтобы писать громоздкий код для проверки, является ли дата сегодняшней, мы можем использовать метод
isToday()
:if (!activities.hasActivity(date) && date.isToday()) {
// код
}
Это намного чище и читаемее, чем:
final today = DateTime.now();
if (!activities.hasActivity(date) && date.day == today.day && date.month == today.month && date.year == today.year) {
// код
}
Оцените новую рубрику! Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #CodingTips #AppDev #FlutterTips
Легко направляйте пользователей: наложения туториалов в Flutter с pal_widgets
Хотите улучшить опыт пользователей вашего Flutter-приложения? 🤔 Используйте пакет pal_widgets для создания интерактивных туториалов! 📚
Шаги для реализации туториала:
1. Установите pal-widgets из pub.dev.
2. Добавьте HelperOrchestrator над вашей страницей или приложением.
3. Создайте экран туториала, используя AnchoredHelper.
4. Присвойте уникальный ключ виджету, который хотите показать.
5. Отобразите туториал после загрузки страницы с помощью WidgetsBinding.
Пример кода:
Преимущества:
- Легко создавайте многошаговые туториалы.
- Сохраняйте прогресс пользователя.
- Настройте внешний вид и поведение туториала.
Улучшите опыт пользователей вашего приложения с помощью туториалов! 👍
Все подобные новости можно найти по хэштегу #FlutterPulseTips
Оцените новую рубрику и напишите свое мнение! 🤔💬
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledevelopment #appdevelopment #tutorial #uiux #FlutterTips #coding #programming #userexperience
Хотите улучшить опыт пользователей вашего Flutter-приложения? 🤔 Используйте пакет pal_widgets для создания интерактивных туториалов! 📚
Шаги для реализации туториала:
1. Установите pal-widgets из pub.dev.
2. Добавьте HelperOrchestrator над вашей страницей или приложением.
3. Создайте экран туториала, используя AnchoredHelper.
4. Присвойте уникальный ключ виджету, который хотите показать.
5. Отобразите туториал после загрузки страницы с помощью WidgetsBinding.
Пример кода:
Dart
// Генерация уникального ключа для виджета
Key key = HelperOrchestrator.of(context).generateKey('test1');
// Создание экрана туториала
AnchoredHelper(
helper: AnchoredHelperItem(
// Смещение подсказки
offset: Offset(0, 20),
// Стиль подсказки
style: HelperStyle(
backgroundColor: Colors.blue,
textColor: Colors.white,
),
// Текст подсказки
text: 'Нажмите на эту кнопку, чтобы увеличить счетчик Flutter Demo.',
),
// Фабрика для привязки подсказки к виджету
widgetFactory: (child) => AnchoredHelperWidget(
key: key,
child: child,
),
);
// Отображение туториала после загрузки страницы
WidgetsBinding.instance.addPostFrameCallback((_) {
HelperOrchestrator.of(context).showAnchoredHelper('text2', helper1);
});
Преимущества:
- Легко создавайте многошаговые туториалы.
- Сохраняйте прогресс пользователя.
- Настройте внешний вид и поведение туториала.
Улучшите опыт пользователей вашего приложения с помощью туториалов! 👍
Все подобные новости можно найти по хэштегу #FlutterPulseTips
Оцените новую рубрику и напишите свое мнение! 🤔💬
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledevelopment #appdevelopment #tutorial #uiux #FlutterTips #coding #programming #userexperience
Flutter Tip: Как сделать нижние всплывающие окна точно по размеру контента (без лишнего пространства!)
При создании мобильных приложений на Flutter часто возникает необходимость отображать всплывающие окна снизу. Однако, по умолчанию, высота этих окон может быть больше, чем содержимое, что выглядит не очень эстетично. 🤔
Проблема: По умолчанию высота вашего модального окна будет больше, чем содержимое. 🤷♂️
Решение: Используйте виджет IntrinsicHeight, чтобы установить высоту всплывающего окна точно по размеру контента. 📏
Вот пример кода:
Оцените эту рубрику и напишите в комментариях, насколько она была для вас полезна! 🤗
Все подобные советы вы можете найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #FlutterTips #AppDevelopment #UIUX #CodingTips
При создании мобильных приложений на Flutter часто возникает необходимость отображать всплывающие окна снизу. Однако, по умолчанию, высота этих окон может быть больше, чем содержимое, что выглядит не очень эстетично. 🤔
Проблема: По умолчанию высота вашего модального окна будет больше, чем содержимое. 🤷♂️
Решение: Используйте виджет IntrinsicHeight, чтобы установить высоту всплывающего окна точно по размеру контента. 📏
Вот пример кода:
showCupertinoModalPopup<void>(
context: context,
builder: () => const IntrinsicHeight(
child: RecordChoiceSelector(), // Ваш виджет содержимого
),
);
Что делает IntrinsicHeight? 🔍
- Этот виджет устанавливает размер своего потомка в соответствии с его внутренней высотой. 📐
Результат: 🎉
- Всплывающее окно будет отображаться точно по размеру содержимого, без лишнего пространства. 👍
Оцените эту рубрику и напишите в комментариях, насколько она была для вас полезна! 🤗
Все подобные советы вы можете найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #FlutterTips #AppDevelopment #UIUX #CodingTips
Адаптивный конструктор одного виджета с помощью DeviceSizeBuilder
В этой статье мы рассмотрим, как использовать DeviceSizeBuilder для адаптации небольших частей экрана под разные типы устройств.
Чтобы иметь доступ к методу didChangeMetrics, нам нужно использовать WidgetsBinding:
Мы хотим перестроить дочерний элемент только при изменении типа устройства.
Наши точки останова:
Оцените новую рубрику и напишите нам о своих впечатлениях! 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #ResponsiveDesign #UI #UX #Widgets #CodingTips
В этой статье мы рассмотрим, как использовать DeviceSizeBuilder для адаптации небольших частей экрана под разные типы устройств.
@override
Widget build(BuildContext context) {
return DeviceSizeBuilder(
builder: (device) => Column(
children: [
switch (device) {
DeviceType.small => const Spacer(),
// игнорируем остальные случаи
},
ElevatedButton(
onTap: () {},
child: Text('tap me'),
),
],
),
);
}
Чтобы иметь доступ к методу didChangeMetrics, нам нужно использовать WidgetsBinding:
class DeviceSizeBuilder extends StatefulWidget {
const DeviceSizeBuilder({
super.key,
required this.builder,
});
@override
State<DeviceSizeBuilder> createState() => _DeviceSizeBuilderState();
}
class _DeviceSizeBuilderState extends State<DeviceSizeBuilder> with WidgetsBindingObserver {
late DeviceType _lastSize;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_lastSize = widget.builder;
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeMetrics() {
super.didChangeMetrics();
final newSize = DeviceType.fromWidth(viewportWidth);
if (_lastSize != newSize) {
setState(() {});
}
}
double get viewportWidth => MediaQuery.of(context).size.width;
@override
Widget build(BuildContext context) {
_lastSize = DeviceType.fromWidth(viewportWidth);
return widget.builder(_lastSize);
}
}
Мы хотим перестроить дочерний элемент только при изменении типа устройства.
Наши точки останова:
enum DeviceType {
small(0),
medium(600),
large(1024),
Xlarge(2200);
final double breakpoint;
const DeviceType(this.breakpoint);
static DeviceType fromWidth(double width) {
return switch (width) {
< 600 => DeviceType.small,
< 1024 => DeviceType.medium,
< 2200 => DeviceType.large,
_ => DeviceType.Xlarge,
};
}
}
Оцените новую рубрику и напишите нам о своих впечатлениях! 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #ResponsiveDesign #UI #UX #Widgets #CodingTips
Выход за рамки Material: добавление пользовательских цветов в тему Flutter
Хотите выйти за пределы стандартных ограничений Material Design в вашем приложении Flutter? 🤔 В этой статье мы расскажем, как создать расширение темы для добавления пользовательских цветов! 🎨
Шаг 1: Создание ThemeExtension
Для начала создайте класс, который будет предоставлять ваши цвета. Этот класс должен расширять
Шаг 2: Добавление расширения в тему Material
Теперь добавьте созданное расширение в вашу тему Material, используя свойство
Шаг 3: Использование цветов из расширения
Чтобы получить доступ к вашим цветам в любом месте приложения, используйте следующий код:
Оцените новую рубрику Flutter Pulse Tips и оставьте свои отзывы! 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledevelopment #appdevelopment #uiux #codingtips #FlutterTips #ThemeExtension #CustomColors
Хотите выйти за пределы стандартных ограничений Material Design в вашем приложении Flutter? 🤔 В этой статье мы расскажем, как создать расширение темы для добавления пользовательских цветов! 🎨
Шаг 1: Создание ThemeExtension
Для начала создайте класс, который будет предоставлять ваши цвета. Этот класс должен расширять
ThemeExtension
. Пример реализации:
import 'package:flutter/material.dart';
class AppareanceKitColors extends ThemeExtension<AppareanceKitColors> {
final Color primary;
final Color secondary;
final Color dark;
final Color onePrimary;
final Color background;
final Color onbackground;
final Color surface;
final Color onSurface;
final Color grey1;
final Color grey2;
final Color grey3;
final Color error;
const AppareanceKitColors({
required this.primary,
required this.secondary,
required this.dark,
required this.onePrimary,
required this.background,
required this.onbackground,
required this.surface,
required this.onSurface,
required this.grey1,
required this.grey2,
required this.grey3,
required this.error,
});
factory AppareanceKitColors.light() => const AppareanceKitColors(
primary: Color(0xFFF830FF),
secondary: Color(0xFF3057AD),
dark: Color(0xFF20001D),
onePrimary: Color(0xFF110551),
background: Color(0xFFFFFFFF),
onbackground: Color(0xFF110551),
surface: Color(0xFFAEAEAE),
onSurface: Color(0xFF000000),
grey1: Color(0xFFF9E5FF),
grey2: Color(0xFFFFD8FF),
grey3: Color(0xFF632338),
error: Color(0xFFC41E1E),
);
}
Шаг 2: Добавление расширения в тему Material
Теперь добавьте созданное расширение в вашу тему Material, используя свойство
extensions
:
MaterialApp(
theme: ThemeData(
extensions: [
AppareanceKitColors.light(),
],
),
)
Шаг 3: Использование цветов из расширения
Чтобы получить доступ к вашим цветам в любом месте приложения, используйте следующий код:
extension AppareanceKitThemeExt on BuildContext {
AppareanceKitColors get colors => Theme.of(this).extension<AppareanceKitColors>()!;
}
// Использование
Container(
color: context.colors.primary,
)
Оцените новую рубрику Flutter Pulse Tips и оставьте свои отзывы! 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledevelopment #appdevelopment #uiux #codingtips #FlutterTips #ThemeExtension #CustomColors
Шаблон Riverpod: упрощаем работу с состоянием приложения
Привет, разработчики Flutter! 👋 Сегодня мы рассмотрим полезный совет по использованию Riverpod - популярной библиотеки для управления состоянием приложения. 📈
Проблема: при использовании Riverpod часто приходится писать повторяющийся код, например,
Решение: использование расширений Dart для создания удобных шорткатов. 🔥
Эти расширения позволяют легко получать экземпляр
Пример использования:
Такой подход делает код чище и читабельнее. 📚
Оцените новую рубрику и напишите в комментариях, насколько она вам полезна! 🤔
Все подобные новости можно найти по хэштегу #FlutterPulseTips 👍
#flutter #dart #flutterpulse #FlutterPulseTips #Riverpod #StateManagement #FlutterTips #MobileDevelopment #CodingTips
Привет, разработчики Flutter! 👋 Сегодня мы рассмотрим полезный совет по использованию Riverpod - популярной библиотеки для управления состоянием приложения. 📈
Проблема: при использовании Riverpod часто приходится писать повторяющийся код, например,
ref.read(myProvider).xxx
. Это может быть утомительно и привести к ошибкам. 😩Решение: использование расширений Dart для создания удобных шорткатов. 🔥
extension UserSessionRepositoryProvider on Ref {
UserSessionRepository get userSessionRepository =>
read(userSessionRepositoryProvider);
UserSessionRepository get userSessionRepository$ =>
watch(userSessionRepositoryProvider);
}
Эти расширения позволяют легко получать экземпляр
UserSessionRepository
, используя ref.userSessionRepository
или следить за его изменениями с помощью ref.userSessionRepository$
. 🔄Пример использования:
Future<UserSession> startSession({
required Session session,
}) async {
final activeSession = await ref.userSessionRepository
.getActiveSession(idOrThrow);
if (activeSession != null) {
throw AlreadyRunningSessionException();
}
return ref.userSessionRepository.start(
idOrThrow,
UserSession.fromSession(session),
);
}
Такой подход делает код чище и читабельнее. 📚
Оцените новую рубрику и напишите в комментариях, насколько она вам полезна! 🤔
Все подобные новости можно найти по хэштегу #FlutterPulseTips 👍
#flutter #dart #flutterpulse #FlutterPulseTips #Riverpod #StateManagement #FlutterTips #MobileDevelopment #CodingTips