Ускорьте Firebase Firestore на iOS
Firestore долго компилируется каждый раз, когда вы запускаете приложение с нуля...
...Хорошая новость в том, что есть решение, предоставленное invertase 🙌
Откройте файл podfile для iOS
Добавьте pod 'FirebaseFirestore'... следующим образом:
Вам нужно добавить соответствующую версию, используемую в вашем Flutter-зависимости.
Оцените новую рубрику лайком 👍! Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #Firebase #iOS #Firestore #MobileDevelopment #FlutterTips
Firestore долго компилируется каждый раз, когда вы запускаете приложение с нуля...
...Хорошая новость в том, что есть решение, предоставленное invertase 🙌
Откройте файл podfile для iOS
Добавьте pod 'FirebaseFirestore'... следующим образом:
target 'Runner' do
use_frameworks!
use_modular_headers!
# ДОБАВЬТЕ ЭТО
pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => '11.2.0'
Вам нужно добавить соответствующую версию, используемую в вашем Flutter-зависимости.
Оцените новую рубрику лайком 👍! Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #Firebase #iOS #Firestore #MobileDevelopment #FlutterTips
👍4
Хранение настроек пользователя
Используйте плагин shared preferences только для некритичных данных!
Почему не стоит хранить всё в SharedPreferences:
• Shared preferences предназначены для хранения простых данных в формате ключ-значение.
• Они не подходят для хранения сложных структур данных.
• Они не оптимизированы для высокопроизводительных операций чтения/записи.
• Не храните конфиденциальные данные, так как нет гарантии, что запись будет сохранена на диске (иногда всё может быть потеряно).
Если вы используете Provider или Riverpod, рассмотрите возможность сделать следующее:
вызовите метод init перед отображением чего-либо и используйте SharedPreferencesBuilder
для доступа к sharedPreferences.
Prefer SharedPreferencesAsync or SharedPreferencesWithCache,
так как SharedPreferences будет объявлен устаревшим в будущих обновлениях.
Оцените новую рубрику и напишите своё мнение! 🤔💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDev #ProgrammingTips #DevTips
Используйте плагин shared preferences только для некритичных данных!
Почему не стоит хранить всё в SharedPreferences:
• Shared preferences предназначены для хранения простых данных в формате ключ-значение.
• Они не подходят для хранения сложных структур данных.
• Они не оптимизированы для высокопроизводительных операций чтения/записи.
• Не храните конфиденциальные данные, так как нет гарантии, что запись будет сохранена на диске (иногда всё может быть потеряно).
// getInstance возвращает Future
// Хорошей практикой является инициализация в начале работы приложения,
// а затем использование уже инициализированного экземпляра
final SharedPreferences prefs = await SharedPreferences.getInstance();
Если вы используете Provider или Riverpod, рассмотрите возможность сделать следующее:
вызовите метод init перед отображением чего-либо и используйте SharedPreferencesBuilder
для доступа к sharedPreferences.
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
final sharedPreferencesProvider = Provider<SharedPreferencesBuilder>((ref) => SharedPreferencesBuilder(),
);
class SharedPreferencesBuilder implements OnStartService {
SharedPreferences? _sharedPreferences;
@override
Future<void> init() async {
if (_sharedPreferences != null) {
return;
}
_sharedPreferences = await SharedPreferences.getInstance();
}
SharedPreferences get prefs {
if (_sharedPreferences == null) {
throw Exception('SharedPreferences not loaded');
}
return _sharedPreferences!;
}
}
Prefer SharedPreferencesAsync or SharedPreferencesWithCache,
так как SharedPreferences будет объявлен устаревшим в будущих обновлениях.
Оцените новую рубрику и напишите своё мнение! 🤔💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDev #ProgrammingTips #DevTips
👍3
Builder with Dart
Dart позволяет сделать это без какого-либо шаблонного кода 🚀
В Dart вы можете использовать cascade notation для последовательного выполнения операций над одним и тем же объектом 🔥
В этом примере мы используем cascade notation (..), чтобы задать значения полям объекта
Зачем это нужно?
- Упрощает код, убирая необходимость в отдельных методах-сеттерах 🔄
- Делает код более читаемым и удобным для поддержки 📖
Оцените новую рубрику и напишите в комментариях, насколько она вам полезна! 🤔
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #DartTips #MobileDevelopment #CodingTips #SoftwareDevelopment #CascadeNotation
Dart позволяет сделать это без какого-либо шаблонного кода 🚀
В Dart вы можете использовать cascade notation для последовательного выполнения операций над одним и тем же объектом 🔥
class MyModel {
String? name;
String? title;
int? count;
MyModel({
this.name,
this.title,
this.count,
});
}
void main() {
final model = MyModel()
..name = 'John Doe' // Установка имени
..title = 'Software Engineer' // Установка должности
..count = 42; // Установка счетчика
final model2 = MyModel()
..name = 'Jane Doe'
..title = 'Data Scientist'
..count = 100;
}
В этом примере мы используем cascade notation (..), чтобы задать значения полям объекта
MyModel
последовательно 💡Зачем это нужно?
- Упрощает код, убирая необходимость в отдельных методах-сеттерах 🔄
- Делает код более читаемым и удобным для поддержки 📖
Оцените новую рубрику и напишите в комментариях, насколько она вам полезна! 🤔
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #DartTips #MobileDevelopment #CodingTips #SoftwareDevelopment #CascadeNotation
👍6👎1
Как создать таймер
Создание точного таймера с помощью Flutter
При создании таймера важно помнить, что не стоит полагаться на стандартный
Проблема с обычным таймером:
- Задержки и тики могут быть не идеально точными, особенно при высокой нагрузке на CPU.
Мы используем специальные колбэки для обновления виджета с анимациями. Обновляем наш виджет каждую секунду и запускаем анимацию соответствующим образом.
Код контроллера таймера:
Ключевые моменты:
- Если вы знаете, когда таймер должен начаться и закончиться, ваш таймер останется точным, даже если пользователь закроет приложение и вернется.
Оцените нашу новую рубрику! 👍 Оставьте ваши отзывы в комментариях! 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #AppDevelopment #ProgrammingTips #Таймер #Точность #FlutterРазработка
Создание точного таймера с помощью Flutter
При создании таймера важно помнить, что не стоит полагаться на стандартный
Timer
, так как задержки и тики могут быть не совсем точными, особенно если процессор загружен.Проблема с обычным таймером:
- Задержки и тики могут быть не идеально точными, особенно при высокой нагрузке на CPU.
Мы используем специальные колбэки для обновления виджета с анимациями. Обновляем наш виджет каждую секунду и запускаем анимацию соответствующим образом.
Код контроллера таймера:
class TimerController {
Timer? _timer;
DateTime? timerEndTime;
DateTime? timerStartTime;
TimerState state;
Duration duration;
Duration? remaining;
VoidCallback? onInit;
VoidCallback? onStart;
VoidCallback? onPause;
TimerTick? onTick;
List<VoidCallback> onCompleteListener;
List<VoidCallback> _onTickListener;
BasicTimerController({
required this.state,
required this.duration,
required this.timerEndTime,
this.remaining,
this.timerStartTime,
}) : onCompleteListener = [],
_onTickListener = [] {
remaining ??= duration;
}
Duration? get elapsed {
if (remaining == null) {
return null;
}
return duration - remaining!;
}
void start() {
state = TimerState.running;
final isNewTimer = remaining == null;
if (isNewTimer) {
timerStartTime = DateTime.now();
timerEndTime = timerStartTime!.add(duration);
} else {
timerEndTime = DateTime.now().add(remaining!);
timerStartTime = timerEndTime!.subtract(remaining!);
}
onInit?.call();
onStart?.call();
remaining ??= duration;
// Мы могли бы обновлять чаще, но это было бы бесполезно
const timerFrequency = Duration(milliseconds: 1000);
_timer = Timer.periodic(timerFrequency, (timer) {
if (remaining == null || remaining! <= Duration.zero) {
stop();
return;
}
if (timerEndTime == null) {
return;
}
remaining = timerEndTime!.difference(DateTime.now());
onTick?.call(remaining!);
for (final listener in _onTickListener) {
listener();
}
});
}
@override
void pause() {
_timer?.cancel();
state = TimerState.paused;
}
}
Ключевые моменты:
- Если вы знаете, когда таймер должен начаться и закончиться, ваш таймер останется точным, даже если пользователь закроет приложение и вернется.
Оцените нашу новую рубрику! 👍 Оставьте ваши отзывы в комментариях! 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #AppDevelopment #ProgrammingTips #Таймер #Точность #FlutterРазработка
👍5
Рисуем таймер
Создание точного таймера с помощью Flutter часть 2
Мы можем использовать шейдер в нашем кастомном рисовальщике (painter).
Мы рисуем полный круг, который будет отображаться постепенно.
Затем мы рисуем круг, который будет уменьшаться каждую секунду.
Мы перерисовываем только если прогресс изменился.
Ну а если вы хотите протестировать какой-то угол вручную...
Оцените новую рубрику! 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #AppDevelopment #ProgrammingTips #UIUX #FlutterCommunity
Создание точного таймера с помощью Flutter часть 2
Мы можем использовать шейдер в нашем кастомном рисовальщике (painter).
Мы рисуем полный круг, который будет отображаться постепенно.
Затем мы рисуем круг, который будет уменьшаться каждую секунду.
Мы перерисовываем только если прогресс изменился.
Ну а если вы хотите протестировать какой-то угол вручную...
class CircleTimerPainter extends CustomPainter {
final double progress;
final Color progressColor;
final Color backgroundColor;
CircleTimerPainter({
super.repaint,
required this.progress,
this.progressColor = Colors.blue,
this.backgroundColor = Colors.grey,
});
@override
void paint(Canvas canvas, Size size) {
final angle = 360 * progress; // примечание: Используйте напрямую радианы для лучшей производительности
final backgroundPaint = Paint()
..color = backgroundColor
..style = PaintingStyle.stroke
..strokeWidth = 28;
final progressPaint = Paint()
..shader = SweepGradient(
colors: [
progressColor,
Colors.red,
],
startAngle: 0 - 90.0.radians,
endAngle: angle.radians,
).createShader(
Rect.fromCircle(
center: Offset(size.width / 2, size.height / 2),
radius: size.width / 2),
)
..color = progressColor
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round
..strokeWidth = 20;
// Рисуем фоновый круг
canvas.drawCircle(
size.center(Offset.zero),
size.width / 2,
backgroundPaint,
);
canvas.drawArc(
Rect.fromLTWH(0, 0, size.width, size.height),
-90.0.radians,
angle.radians,
false,
progressPaint,
);
}
@override
bool shouldRepaint(covariant CircleTimerPainter oldDelegate) {
return oldDelegate.progress != progress;
}
}
extension RadianExt on double {
double get radians => this * (math.pi / 180);
}
Оцените новую рубрику! 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #AppDevelopment #ProgrammingTips #UIUX #FlutterCommunity
👍4
Получение данных с использованием http-клиента
Как получить данные с удаленного сервера, используя http-клиент 🤔
Шаг 1: Установите пакет http 📦
* Возвращение обобщенного типа T, чтобы можно было напрямую возвращать другой тип. Рекомендуется использовать пакет json_serializable для легкого парсинга объектов 📄
* Предоставление пользовательских заголовков, таких как токен API 🔒
* Улучшение: отправка пользовательских ошибок в зависимости от кода состояния ⚠️
Оцените новую рубрику и напишите свое мнение в комментариях! 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #AppDevelopment #ProgrammingTips #Coding #SoftwareDevelopment
Как получить данные с удаленного сервера, используя http-клиент 🤔
Шаг 1: Установите пакет http 📦
Future<T> request<T>({
required String endpoint,
Map<String, String>? headers,
Map<String, String>? queryParams,
}) async {
final url = Uri(
scheme: config.baseUrlScheme, // http или https
host: config.baseUrlHost, // localhost или mydomain.com
path: endpoint, // /api/articles
queryParameters: queryParams,
port: config.baseUrlPort, // порт вашего бэкенда
);
final response = await http.get(
url,
headers: {
...?headers, // Предоставление пользовательских заголовков, например, токена API
},
);
if (response.statusCode != 200) {
throw Exception('Запрос к API завершился неудачей: ${response.statusCode} ${response.reasonPhrase}');
}
return json.decode(response.body) as T; // Возвращение обобщенного типа T
}
* Возвращение обобщенного типа T, чтобы можно было напрямую возвращать другой тип. Рекомендуется использовать пакет json_serializable для легкого парсинга объектов 📄
* Предоставление пользовательских заголовков, таких как токен API 🔒
* Улучшение: отправка пользовательских ошибок в зависимости от кода состояния ⚠️
Оцените новую рубрику и напишите свое мнение в комментариях! 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #AppDevelopment #ProgrammingTips #Coding #SoftwareDevelopment
👍1👎1
🎨 Vibe coding: Создаём приложение для скетчей с нуля вместе с ИИ!
Привет, Flutter-разработчики! 👋 Сегодня мы делимся крутым видео, которое точно стоит вашего внимания. Руслан Цицер начинает новый практический цикл по созданию приложения для скетчей с использованием ИИ.
🚀 Что ждет в этом выпуске?
• Чистый проект с нуля: от
• Работа с Cursor IDE и генерация кода через промпты
• Верстка экранов в стиле Cupertino (iOS)
• Создание компонентов: SketchCanvas, GenerateButton, навигация
• Подготовка к интеграции с GPT API и генерацией изображений (в следующей части!)
💡 Почему это стоит посмотреть?
👉 Реальный процесс работы с ИИ-инструментами
👉 Практические приемы организации кода
👉 Подготовка базы для сложных фич с генерацией контента
👉 Живой процесс принятия решений при разработке
📂 Ресурсы:
🔗 Репозиторий с примерами
🔗 Смотреть видео на YouTube
Не пропустите продолжение! В следующем выпуске — добавление AI-логики и генерации изображений через Gemini.
#Flutter #Dart #FlutterPulse #FlutterPulseTips #FlutterPulseYoutube
Смотрите другие наши видео по хэштегу #FlutterPulseYoutube!
Привет, Flutter-разработчики! 👋 Сегодня мы делимся крутым видео, которое точно стоит вашего внимания. Руслан Цицер начинает новый практический цикл по созданию приложения для скетчей с использованием ИИ.
🚀 Что ждет в этом выпуске?
• Чистый проект с нуля: от
flutter create
до первого коммита• Работа с Cursor IDE и генерация кода через промпты
• Верстка экранов в стиле Cupertino (iOS)
• Создание компонентов: SketchCanvas, GenerateButton, навигация
• Подготовка к интеграции с GPT API и генерацией изображений (в следующей части!)
💡 Почему это стоит посмотреть?
👉 Реальный процесс работы с ИИ-инструментами
👉 Практические приемы организации кода
👉 Подготовка базы для сложных фич с генерацией контента
👉 Живой процесс принятия решений при разработке
📂 Ресурсы:
🔗 Репозиторий с примерами
🔗 Смотреть видео на YouTube
Не пропустите продолжение! В следующем выпуске — добавление AI-логики и генерации изображений через Gemini.
#Flutter #Dart #FlutterPulse #FlutterPulseTips #FlutterPulseYoutube
Смотрите другие наши видео по хэштегу #FlutterPulseYoutube!
Детали для улучшения формы
Ничто не раздражает так сильно, как невозможность закрыть клавиатуру. Пользователь нажимает в любом месте... и клавиатура остаётся. Вместо этого вы можете просто сделать так:
Решение: Оберните всю страницу в GestureDetector, а затем снимите фокус со всех элементов, используя функцию FocusScope. Это позволит автоматически убрать клавиатуру при нажатии вне текстовых полей.
Оцените новую рубрику и напишите своё мнение! 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #UIUX #AppDev #CodingTips #DevTips #FlutterTips
Ничто не раздражает так сильно, как невозможность закрыть клавиатуру. Пользователь нажимает в любом месте... и клавиатура остаётся. Вместо этого вы можете просто сделать так:
final _formKey = GlobalKey<FormState>();
class SigninPage extends StatelessWidget {
const SigninPage({super.key, this.canDismiss = true});
@override
Widget build(BuildContext context) {
final translations = Translations.of(context).signin;
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(), // Убираем фокус с полей при нажатии вне их
child: PopScope(
canPop: canDismiss,
child: TopImgBackground(
bgImagePath: 'assets/images/signin/signin_background.png',
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: canDismiss,
foregroundColor: context.colors.background,
),
resizeToAvoidBottomInset: false,
body: Form(
autovalidateMode: AutovalidateMode.disabled,
key: _formKey,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: ListView(
children: [
const SizedBox(height: 150),
Text(
translations.title,
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
),
),
],
),
),
),
),
),
),
);
}
}
Решение: Оберните всю страницу в GestureDetector, а затем снимите фокус со всех элементов, используя функцию FocusScope. Это позволит автоматически убрать клавиатуру при нажатии вне текстовых полей.
Оцените новую рубрику и напишите своё мнение! 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #UIUX #AppDev #CodingTips #DevTips #FlutterTips
👍3
Шпаргалка по InteractiveViewer
InteractiveViewer - это виджет, который позволяет пользователям перемещать, масштабировать и взаимодействовать с дочерним содержимым с помощью жестов, таких как сжатие и перетаскивание.
* scaleEnabled:
* Позволяет пользователю масштабировать с помощью жестов сжатия (по умолчанию: true).
* Установите значение false, чтобы отключить масштабирование.
* constrained:
* Ограничивает дочерний элемент в пределах границ просмотра (по умолчанию: true).
* Установите значение false для неограниченного перемещения/масштабирования за пределами границ просмотра.
* panEnabled:
* Позволяет перетаскивать/перемещать дочерний элемент с помощью касания (по умолчанию: true).
* Установите значение false, чтобы отключить перемещение.
* onInteractionStart:
* Callback, срабатывающий при начале взаимодействия (перемещение или масштабирование).
* Предоставляет детали, такие как фокусная точка и масштаб.
* onInteractionUpdate:
* Callback, вызываемый непрерывно при перемещении или масштабировании пользователем.
* Полезно для отслеживания обновлений жестов в реальном времени.
Оцените новую рубрику и напишите своё мнение! 👍✍️
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #UIUX #FlutterTips #CodingCheatsheet
InteractiveViewer - это виджет, который позволяет пользователям перемещать, масштабировать и взаимодействовать с дочерним содержимым с помощью жестов, таких как сжатие и перетаскивание.
InteractiveViewer(
transformationController: TransformationController()
..value = (Matrix4.identity()..scale(scale)),
scaleEnabled: false,
constrained: false,
panEnabled: false,
onInteractionStart: (details) => print('Начало взаимодействия'),
onInteractionUpdate: (details) => print('Обновление взаимодействия'),
onInteractionEnd: (details) => print('Конец взаимодействия'),
child: Image.asset("name_of_your_image.png"),
)
* scaleEnabled:
* Позволяет пользователю масштабировать с помощью жестов сжатия (по умолчанию: true).
* Установите значение false, чтобы отключить масштабирование.
* constrained:
* Ограничивает дочерний элемент в пределах границ просмотра (по умолчанию: true).
* Установите значение false для неограниченного перемещения/масштабирования за пределами границ просмотра.
* panEnabled:
* Позволяет перетаскивать/перемещать дочерний элемент с помощью касания (по умолчанию: true).
* Установите значение false, чтобы отключить перемещение.
* onInteractionStart:
* Callback, срабатывающий при начале взаимодействия (перемещение или масштабирование).
* Предоставляет детали, такие как фокусная точка и масштаб.
* onInteractionUpdate:
* Callback, вызываемый непрерывно при перемещении или масштабировании пользователем.
* Полезно для отслеживания обновлений жестов в реальном времени.
Оцените новую рубрику и напишите своё мнение! 👍✍️
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #UIUX #FlutterTips #CodingCheatsheet
👍1
Шпаргалка по форматированию цен
Вы можете легко форматировать цены, используя пакет intl. Вот наиболее распространенные методы:
Оцените нашу новую рубрику по Flutter советам! 👍 Оставьте свои комментарии и реакции, если вам понравился этот пост! 💬👍
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #AppDevelopment #ProgrammingTips #Coding #FlutterTips
Вы можете легко форматировать цены, используя пакет intl. Вот наиболее распространенные методы:
import 'package:intl/intl.dart';
// Форматирование с указанием локали и символа валюты
NumberFormat.currency(locale: 'en_US', symbol: '\$').format(12.2);
// $12.2
// Форматирование валюты с использованием текущей локали устройства
NumberFormat.currency().format(12.2);
// US 12.2 или EUR 12.2 в зависимости от локали устройства
// Форматирование валюты без десятичных знаков
NumberFormat.currency(decimalDigits: 0).format(12.2);
// US 12
// Простое форматирование валюты
NumberFormat.simpleCurrency().format(12.2);
// $12.2
// Компактное форматирование больших чисел
NumberFormat.compactSimpleCurrency().format(1200000);
// $1.2M
Оцените нашу новую рубрику по Flutter советам! 👍 Оставьте свои комментарии и реакции, если вам понравился этот пост! 💬👍
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #AppDevelopment #ProgrammingTips #Coding #FlutterTips
👍2
Как правильно обрабатывать результат диалога
Не пытайтесь выполнить код напрямую после закрытия диалога! 🚫💻
При работе с диалогами важно правильно обрабатывать их результат. Давайте рассмотрим два примера кода на Dart, чтобы понять, как это сделать корректно. 💡
Неправильный способ: 🚫
Правильный способ: ✅
В первом примере при нажатии на кнопки "Rate" или "Improve" диалог закрывается, но результат не возвращается. Во втором примере при нажатии на кнопки возвращается соответствующее значение из enum `RatingResult`, что позволяет корректно обработать результат.
Оцените новую рубрику и напишите в комментариях, что вы думаете о ней! 🤔💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #AppDevelopment #ProgrammingTips #UIUX #SoftwareDevelopment
Не пытайтесь выполнить код напрямую после закрытия диалога! 🚫💻
При работе с диалогами важно правильно обрабатывать их результат. Давайте рассмотрим два примера кода на Dart, чтобы понять, как это сделать корректно. 💡
Неправильный способ: 🚫
Future<void> showRatingDialog(BuildContext context) {
return showDialog<RatingResult>(
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
title: const Text('Rate the app'),
content: const Text('Please rate the app'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
// не пытайтесь выполнить что-либо здесь
// потому что диалог отклонен
},
child: const Text('Rate'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
// не пытайтесь выполнить что-либо здесь
// потому что диалог отклонен
},
child: const Text('Improve'),
),
],
);
},
);
}
Правильный способ: ✅
enum RatingResult {
rate,
improve,
never,
}
Future<RatingResult?> showRatingDialog(BuildContext context) {
return showDialog<RatingResult>(
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
title: const Text('Rate the app'),
content: const Text('Please rate the app'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(RatingResult.rate);
},
child: const Text('Rate'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop(RatingResult.improve);
},
child: const Text('Improve'),
),
],
);
},
);
}
В первом примере при нажатии на кнопки "Rate" или "Improve" диалог закрывается, но результат не возвращается. Во втором примере при нажатии на кнопки возвращается соответствующее значение из enum `RatingResult`, что позволяет корректно обработать результат.
Оцените новую рубрику и напишите в комментариях, что вы думаете о ней! 🤔💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #AppDevelopment #ProgrammingTips #UIUX #SoftwareDevelopment
👍2