Flutter Pulse
416 subscribers
270 photos
540 links
На канале будут новости про flutter с сайтов, информация об обновлении пакетов, а также авторский контент.
Download Telegram
Как показать уведомление Toast с Riverpod
Избавляемся от требования 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
Flutter tips: Расширения для работы с датами

Привет, подписчики! Сегодня мы поговорим о полезных расширениях для работы с датами в 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.

Пример кода:


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, чтобы установить высоту всплывающего окна точно по размеру контента. 📏

Вот пример кода:

showCupertinoModalPopup<void>(
context: context,
builder: () => const IntrinsicHeight(
child: RecordChoiceSelector(), // Ваш виджет содержимого
),
);



Что делает IntrinsicHeight? 🔍
- Этот виджет устанавливает размер своего потомка в соответствии с его внутренней высотой. 📐

Результат: 🎉
- Всплывающее окно будет отображаться точно по размеру содержимого, без лишнего пространства. 👍


Оцените эту рубрику и напишите в комментариях, насколько она была для вас полезна! 🤗

Все подобные советы вы можете найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #FlutterTips #AppDevelopment #UIUX #CodingTips
Выход за рамки Material: добавление пользовательских цветов в тему Flutter

Хотите выйти за пределы стандартных ограничений 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 часто приходится писать повторяющийся код, например, 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