Flutter Pulse
497 subscribers
301 photos
633 links
На канале будут новости про flutter с сайтов, информация об обновлении пакетов, а также авторский контент.
Download Telegram
Несколько навигаторов
В вашем приложении может быть несколько навигаторов. Например, основной навигатор и вторичный навигатор внутри него. Вторичный навигатор может использоваться для onboarding процесса.



class OnboardingPage extends ConsumerWidget {
const OnboardingPage({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
body: Navigator( // Вторичный навигатор
onGenerateRoute: (settings) => switch (settings.name) {
'feature_1' => OnboardingRouteTransition(
builder: (context) => const MultimediaOnboardingStep(),
settings: settings,
),
...
},
),
);
}
}



Если вы хотите перейти на страницу из основного навигатора, вам нужно получить доступ к основному навигатору следующим образом:



Navigator.of(context, rootNavigator: true).pushNamed("premium")



Оцените новую рубрику по Flutter советам! 👍💡 Ваши мысли нам очень важны! 🤔

Все подобные новости можно найти по хэштегу #FlutterPulseTips

#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #AppDevelopment #ProgrammingTips #FlutterTips
🔥1
Сравнение версий приложения
Привет, Flutter-разработчики! 👋 Сегодня мы рассмотрим полезный совет о том, как сравнить версии вашего приложения. Это может быть особенно полезно, когда вы хотите проверить, использует ли пользователь последнюю версию вашего приложения. 🤔

Зачем сравнивать версии приложения?
Сравнение версий приложения необходимо для того, чтобы убедиться, что пользователи используют последнюю версию вашего приложения. Это важно для обеспечения безопасности, исправления ошибок и добавления новых функций. 🔄

Как сравнить версии приложения?
Для сравнения версий приложения мы будем использовать пакеты package_info_plus и version. Вот пример кода:


// получаем текущую установленную версию приложения
import 'package:package_info_plus/package_info_plus.dart';
// пакет version для сравнения версий
import 'package:version/version.dart';

Future<void> checkAppVersion(Version minVersion) {
final info = await PackageInfo.fromPlatform();
final currentVersion = Version.parse(info.version);

if (currentVersion < minVersion) {
throw UpdateRequired();
}
}



В этом примере мы получаем текущую версию приложения, используя PackageInfo.fromPlatform(), а затем сравниваем ее с минимальной требуемой версией, используя класс Version из пакета version. Если текущая версия меньше минимальной, мы бросаем исключение UpdateRequired. 🚀

Вы можете напрямую сравнивать две версии, такие как "1.0.1" и "2.40.1". 👍

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

Все подобные новости можно найти по хэштегу #FlutterPulseTips. 🔍

#flutter #dart #flutterpulse #FlutterPulseTips #mobiledevelopment #appdevelopment #codingtips
🔥5
🎮🔥 НОВОСТЬ: FlutterPulse представляет — Duit: эффективный Backend-Driven UI фреймворк для Flutter от Никиты Синявина (BetBoom)

На конференции CrossConf 2025 разработчик из компании BetBoom , Никита Синявин , представил свой open-source проект — Duit , мощный и легковесный фреймворк для реализации подхода Backend-Driven UI на Flutter.

💡 Что такое Backend-Driven UI?
Backend-Driven UI — это подход, при котором не только данные, но и структура интерфейса управляется с сервера. Это позволяет:

🚀 Быстро обновлять интерфейс без публикации новых версий в сторах
🧪 Упрощает A/B тестирование и управление фичами
⏱️ Сокращает время выхода продукта на рынок (Time to Market)
Однако у этого подхода есть и свои вызовы:

📉 Зависимость от скорости сети
🐛 Сложности в отладке и тестировании
🔄 Необходимость тонкой настройки обмена данными между клиентом и сервером

🧰 Основные особенности Duit:
1. Контролируемые виджеты
Подходят для динамического обновления UI
Используют StatefulWidget под капотом, но с оптимизациями для производительности
2. Атрибуты
Хранят параметры виджетов (цвет, размер, текст и т.д.)
Позволяют гибко управлять состоянием и внешним видом элементов
3. Драйвер + Контроллер
Драйвер — центральная часть, отвечающая за обработку действий пользователя и взаимодействие с сервером
Контроллер связывает виджеты с логикой драйвера, обеспечивая двустороннюю коммуникацию
4. Поддержка кастомных виджетов
Возможность добавлять собственные виджеты, например, SVG или анимации
Гибкая система регистрации через три этапа: AttributeFactory, ModelFactory, BuildFactory
5. Компоненты
Шаблоны, которые можно переиспользовать, отделяя макет от данных
6. Действия и события
Действия описываются на сервере и выполняются на клиенте
События — результат выполнения действий, могут обновлять состояние UI
7. Анимации
Поддерживаются как implicit, так и explicit анимации
Реализованы через Tween и AnimationController
8. Расширяемый транспортный слой
Поддерживает HTTP и WebSocket
Возможность интеграции сторонних клиентов, таких как Dio
9. Интеграция с нативными приложениями
Возможность использования Duit в нативных iOS/Android приложениях через Flutter Add-to-App

🌟 Почему это важно для Flutter-сообщества?
Duit — первый полноценный open-source фреймворк для Backend-Driven UI, созданный специально под Flutter. Он даёт командам:

Возможность управлять UI удалённо
Высокую скорость доставки изменений
Гибкость в интеграции и расширении
📦 Что дальше?
Фреймворк уже используется в экспериментальном режиме внутри BetBoom. В планах:

Публикация на pub.dev
Улучшение документации
Создание демо-приложения
Расширение поддержки виджетов Flutter
📌 Ссылка на доклад:
Youtube: Duit – как создать эффективный BDUI-фреймворк для Flutter

#FlutterPulse #FlutterDev #BDUI #BackendDrivenUI #Duit #MobileDevelopment #FlutterFramework #OpenSource #CrossConf #FlutterAddToApp #BETBOOM #NickSinyavin
🔥 НОВОСТЬ: Что ждёт Dart в ближайшие годы? Станислав Чернышёв делится подробностями

На прошедшей конференции CrossConf 2025 автор книги «Основы Dart» и один из самых узнаваемых экспертов в сообществе, Станислав Чернышёв, выступил с докладом о будущем языка Dart. Он рассказал о ключевых фичах, которые уже находятся в разработке или планируются к внедрению в ближайших версиях. Вот самые важные анонсы:

### 🧠 1. Макросы (Macros) — новый уровень метапрограммирования

Одна из самых долгожданных фич в Dart — макросы — наконец-то приближается к релизу. Они позволят:
- Генерировать код на этапе компиляции.
- Упрощать шаблонную логику (например, сериализацию/десериализацию JSON).
- Делать аргументацию классов и функций без необходимости использования отдельных кодогенераторов.

📌 Макросы будут работать через специальные аннотации и поддерживать три типа:
- type — для работы с типами.
- declaration — для добавления объявлений.
- definition — для изменения поведения существующих сущностей.

⚠️ Важно: макросы не смогут использовать dart:io, dart:isolate и другие небезопасные библиотеки, чтобы избежать нежелательного влияния на систему.

### 🔢 2. Цифровые разделители (Dart 36)

int bigNumber = 1_000_000;


Начиная с Dart 36, появятся разделители в числах — удобный способ читать большие значения. Это улучшение качества жизни разработчика, особенно при работе с финансовыми или статистическими данными.

### 🎯 3. Wildcards (Dart 37)

Теперь можно использовать _ как имя переменной в callback’ах, без опаски получить ошибку анализа кода:

list.forEach((_, index) {
print(index);
});


Это упростит работу с ненужными параметрами и уменьшит количество "заглушек".

### 🔄 4. Изменяемые ресурсы между изолятами

Разработчики рассматривают возможность передачи изменяемых объектов между изолятами, используя модификатор sharable. Это может радикально изменить подход к многопоточности в Dart и Flutter, особенно в тяжёлых приложениях.

💡 Предполагается, что вместе с этим будет добавлена библиотека dart:concurrent, предоставляющая примитивы синхронизации и безопасной работы с общими ресурсами.

### 🛠 5. Первичные конструкторы (Primary Constructors)

Ещё одна фича, которая поможет писать меньше кода:

class User(primary constructor(this.name, this.age));


Сокращает объявление простых классов, где поля создаются прямо в конструкторе. Также добавлено ключевое слово required для именованных параметров.

### 📦 6. Новые возможности импортов

Появление scoped imports позволит писать меньше повторяющегося кода:

import 'package:mylib/mylib.dart' show Color;

Color red = Color.red; // Теперь работает!


Такой подход упростит работу с перечислениями и статическими методами.

### 💬 7. Интерполяция строк с тегами (String Tags)

var html = htmlTag"<div>$content</div>";


Такие теги позволят обрабатывать строки особым образом, например, экранировать HTML, форматировать SQL-запросы или валидировать регулярные выражения.

### 📐 8. Static Extensions

Фича, которая позволит добавлять новые конструкторы к классам, не изменяя их исходный код:

static extension UserExtensions on User {
User.fromMap(Map<String, dynamic> data) => ...;
}


Отличное решение для расширения сторонних библиотек без fork’ов.

### 🚀 Итого: куда движется Dart?

Dart продолжает эволюционировать, становясь более мощным и выразительным. Фичи вроде макросов и изменяемых ресурсов между изолятами могут сделать язык конкурентоспособным даже в сложных системах. Однако растёт и порог входа: новые разработчики теперь столкнутся с гораздо более сложным инструментарием.

📌 Dart больше не просто язык для Flutter. Он становится полноценным системным языком с широкими возможностями абстракции, метапрограммирования и параллелизма.

🎥 Видео доступно на YouTube
#FlutterPulse #DartLanguage #FlutterDev #FutureOfDart #MacrosInDart #Isolates #StaticExtensions #FlutterCommunity #MobileDevelopment #PotokConf #Dart36 #Dart37 #FlutterNews #DartEvolution #CodeGeneration #DartIsMoreThanFlutter
Создаём изображение из виджета с помощью пакета

Привет, разработчики Flutter! 👋 Сегодня мы рассмотрим полезный совет по созданию изображения из виджета без его отображения на экране, используя пакет screenshot. 📸

Шаг 1: Установка пакета screenshot
Для начала необходимо установить пакет screenshot. Для этого добавьте следующую строку в файл pubspec.yaml и выполните команду flutter pub get:

import 'package:screenshot/screenshot.dart';


Шаг 2: Создание изображения из виджета
Теперь вы можете создать изображение из любого виджета, указав его размер и соотношение пикселей. Вот пример кода:


final controller = ScreenshotController();
final imgBytes = await controller.captureFromWidget(
widget, // ваш виджет
targetSize: const Size(320, 520), // размер изображения
pixelRatio: 3, // соотношение пикселей
);



Этот код позволяет вам программно создавать изображения любых виджетов, что может быть полезно для различных задач, например, для создания скриншотов или генерации контента. 📱💻

Оцените нашу новую рубрику и оставьте свои комментарии! 💬 Нам важно ваше мнение. 👍

Все подобные новости вы можете найти по хэштегу #FlutterPulseTips

#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #FlutterTips #CodingTips #AppDevelopment
Рисуем текст на холсте
Холст - это интерфейс для рисования непосредственно на экране 🤩

В этом совете мы рассмотрим, как использовать CustomPaint и TextPainter для рисования текста на холсте во Flutter. Это полезно для создания пользовательских виджетов и сложных визуализаций 🎨


import 'package:flutter/material.dart';
import 'dart:ui' as ui;

// Класс виджета, который рисует текст на холсте
class TextOnCanvas extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Текст на холсте')),
body: CustomPaint(
painter: TextPainterExample(),
child: Container(),
),
);
}
}

// Класс, который расширяет CustomPainter для рисования текста
class TextPainterExample extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// Определяем стиль текста
final textStyle = TextStyle(
color: Colors.black,
fontSize: 40,
);

// Создаем TextSpan с текстом и стилем
final textSpan = TextSpan(
text: 'Привет, холст!',
style: textStyle,
);

// Создаем TextPainter для рисования текста
final textPainter = TextPainter(
text: textSpan,
textDirection: ui.TextDirection.ltr,
);

// Вычисляем размер текста
textPainter.layout();

// Определяем позицию, где будет нарисован текст
final offset = Offset(50, 100);

// Рисуем текст на холсте в указанной позиции
textPainter.paint(canvas, offset);
}

@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}


Оцените новую рубрику и напишите в комментариях, какие темы вам наиболее интересны! 💬👍
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #UIUX #CodingTips
1
Автоматическое перерисовывание холста с помощью ChangeNotifier

Привет, подписчики! 👋 Сегодня мы рассмотрим полезный совет по Flutter, который поможет вам оптимизировать процесс отрисовки пользовательского интерфейса. 📱💻

Вы когда-нибудь сталкивались с ситуацией, когда ваш CustomPainter не обновлялся автоматически при изменении данных? 🤔 Это может быть раздражающим, особенно когда вы работаете с динамическим содержимым. Но не волнуйтесь, у нас есть решение! 😊

Использование ChangeNotifier для автоматического обновления

Один из способов обеспечить автоматическое перерисовывание холста — использовать ChangeNotifier. Давайте разберемся, как это работает: 🔍



class WaveModel extends ChangeNotifier {
// ...
void notify() => notifyListeners(); // Уведомляем слушателей об изменении
}

class WorldPainter extends CustomPainter {
final WaveModel model;

WorldPainter({required this.model}) : super(repaint: model);

@override
bool shouldRepaint(covariant WorldPainter oldDelegate) => false;
}



В этом примере WaveModel расширяет ChangeNotifier и уведомляет своих слушателей при вызове метода notify(). 🔔

WorldPainter, который расширяет CustomPainter, принимает WaveModel в качестве параметра и передает его в конструктор суперкласса с параметром repaint. 🔄 Это означает, что всякий раз, когда WaveModel уведомляет своих слушателей, WorldPainter будет перерисовываться автоматически. 🎨

Преимущества этого подхода

* Автоматическое обновление холста при изменении данных 🔄
* Упрощение кода за счет использования встроенных механизмов Flutter 📚
* Повышение производительности приложения за счет оптимального управления отрисовкой 🚀

Оцените новую рубрику и напишите в комментариях, какие темы вам наиболее интересны! 👇

Все подобные новости можно найти по хэштегу #FlutterPulseTips

#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #UIUX #CodingTips #AppDevelopment
👍1
Flutter Canvas: что делают canvas.save() и canvas.restore()?

Привет, разработчики Flutter! 👋 Сегодня мы рассмотрим важный аспект работы с Canvas во Flutter - методы save() и restore(). Эти методы крайне полезны при создании сложных графических элементов и анимаций. 🔍

Когда вы работаете с Canvas, вы часто выполняете различные трансформации, такие как вращение, масштабирование или перемещение. Эти трансформации изменяют текущее состояние Canvas, и иногда вам нужно временно сохранить это состояние, чтобы позже вернуться к нему. Именно здесь на помощь приходят save() и restore(). 🔄

canvas.save() сохраняет текущее состояние Canvas, включая все примененные трансформации и настройки отрисовки. Это позволяет вам временно изменить состояние Canvas, выполнив необходимые операции, а затем вернуться к сохраненному состоянию с помощью canvas.restore().

Рассмотрим пример кода:


class WorldPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
canvas.save(); // сохраняем текущее положение
canvas.translate(size.width/2, size.height/2); // перемещаемся в центр
...
canvas.drawLine(Offset(0, 0), model.offset, whitePainter); // выполняем необходимые действия
canvas.restore(); // сбрасываем до последнего сохраненного положения
}
}



В этом примере мы сохраняем текущее состояние Canvas перед тем, как переместиться в центр экрана. После выполнения необходимых операций мы восстанавливаем сохраненное состояние, возвращая Canvas в исходное положение.

Использование save() и restore() позволяет вам создавать сложные графические элементы, сохраняя чистоту и управляемость кода. 💻

Оцените нашу новую рубрику и оставьте свои комментарии! 💬 Все подобные новости вы можете найти по хэштегу #FlutterPulseTips. Не забудьте подписаться и следить за новыми советами и трюками! 😉

#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #CanvasTips #FlutterTips #ProgrammingTips
Flutter советы - Как связать анимации в цепочку

Привет, разработчики Flutter! 👋 Сегодня мы поделимся с вами полезным советом о том, как создавать сложные анимации, связывая их в цепочку с помощью одного контроллера анимации 🔄

Создание сложных анимаций
Вы можете создать сложные анимации, связывая несколько анимаций в одну цепочку с помощью AnimationController. Это позволяет вам управлять несколькими анимациями одновременно и создавать более интересные и динамичные пользовательские интерфейсы 🎨



fadeAnimController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 2000));
backgroundAnimation = CurvedAnimation(
parent: fadeAnimController,
curve: Interval(0, .4, curve: Curves.easeIn));
titleOpacityAnimation = CurvedAnimation(
parent: fadeAnimController,
curve: Interval(.4, .5, curve: Curves.easeIn));
titleSizeAnimation = CurvedAnimation(
parent: fadeAnimController,
curve: Interval(.4, .6, curve: Curves.easeInOutBack));
// ... свяжите другие анимации



В этом примере мы создаем AnimationController с длительностью 2 секунды и три CurvedAnimation, которые привязаны к этому контроллеру. Каждая CurvedAnimation имеет свой собственный интервал и кривую, что позволяет нам создавать сложные анимации 🔩

Оцените новую рубрику и оставьте свои комментарии! 💬

Все подобные новости можно найти по хэштегу #FlutterPulseTips

#flutter #dart #flutterpulse #FlutterPulseTips #AnimationTips #UIUX #MobileDevelopment #FlutterTips
👍3
Тестирование выбрасывания ошибки
Привет, Flutter-разработчики! 🤖💻
Сегодня мы рассмотрим полезный совет по тестированию в Flutter: как проверить, что ваше приложение выбрасывает конкретную ошибку. Это очень важно для обеспечения стабильности и надежности вашего приложения. 📈

Вы когда-нибудь сталкивались с ситуацией, когда ваш код выбрасывает ошибку, и вы не знали, как ее правильно протестировать? 🤔 Теперь у вас есть решение! Мы будем использовать `testWidgets` для проверки того, что виджет выбрасывает ожидаемую ошибку.

Пример кода:


testWidgets('создание виджета с некоторым параметром → throw', (WidgetTester tester) async {
var exceptionRes;
// catch flutter error или это приведет к провалу теста
FlutterError.onError = (details) {
exceptionRes = details.exception;
};
await tester.pumpWidget(myAppWithError);
// вернуть обработчик ошибок Flutter обратно
// Flutter выбросит ошибку, если этого не сделать
FlutterError.onError = (details) => FlutterError.presentError(details);
expect(exceptionRes, isNotNull);
expect(exceptionRes, isInstanceOf<MyCustomException>());
});



В этом примере мы тестируем, что виджет выбрасывает `MyCustomException`, когда ему передаются определенные параметры. Мы используем `FlutterError.onError` для перехвата исключения и его проверки.

Оцените нашу новую рубрику и напишите в комментариях, какие темы вы хотели бы видеть в будущем! 💬

Все подобные новости можно найти по хэштегу #FlutterPulseTips. 🔍
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #FlutterTips #Programming #SoftwareDevelopment #ErrorHandling #Testing
Отслеживание изменений размера окна

Привет, Flutter-разработчики! 👋 Сегодня мы поделимся с вами полезным советом о том, как отслеживать изменения размера окна в вашем приложении Flutter 🌟

Используем WidgetBindingObserver

Для того чтобы отслеживать изменения размера окна, мы будем использовать `WidgetBindingObserver`. Этот миксин позволяет нам получать уведомления о различных событиях, происходящих в приложении, включая изменения размера окна 📱

Пример кода



class MetricsReactor extends StatefulWidget {
const MetricsReactor({Key? key}) : super(key: key);

@override
_MetricsReactorState createState() => _MetricsReactorState();
}

class _MetricsReactorState extends State<MetricsReactor> with WidgetsBindingObserver {
late Size _lastSize;

WidgetsBinding get widgetBinding => WidgetsBinding.instance!;

@override
void initState() {
super.initState();
_lastSize = WidgetsBinding.instance!.window.physicalSize;
widgetBinding.addObserver(this);
}

@override
void dispose() {
widgetBinding.removeObserver(this);
super.dispose();
}

@override
void didChangeMetrics() {
setState(() {
_lastSize = widgetBinding.window.physicalSize;
});
}

@override
Widget build(BuildContext context) {
return Text('Текущий размер: $_lastSize');
}
}



В этом примере мы создаем `StatefulWidget` под названием `MetricsReactor`, который использует `WidgetsBindingObserver` для отслеживания изменений размера окна. Когда размер окна изменяется, мы обновляем состояние виджета с новым размером 📈

Оцените нашу новую рубрику! 👍 Мы надеемся, что вам понравится эта рубрика и вы найдете ее полезной. Оцените нас и подпишитесь на наш канал, чтобы быть в курсе всех последних советов и новостей из мира Flutter 📲

Все подобные новости можно найти по хэштегу #FlutterPulseTips

#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #FlutterTips #Programming #Development #Coding
👍2
6 способов копирования списков и карт в Dart

Привет, разработчики Flutter! 👋

В Dart существует несколько способов копирования списков и карт. Давайте рассмотрим шесть наиболее популярных методов:

1. Использование json decode/encode - клонирование без сохранения ссылки

   List newList = json.decode(json.encode(oldList));
Map newMap = json.decode(json.encode(oldMap));


2. Использование оператора spread - клонирование без сохранения ссылки

   List newList = [...oldList];
Map newMap = {...oldMap};
HashMap newMap = HashMap.from({...oldMap});


3. Использование фабрики from - копирование ссылки на значение

   List newList = List.from(oldList);
Map newMap = Map.from(oldMap);


4. Использование метода addAll - копирование ссылки на значение

   List newList = []..addAll(oldList);


5. Использование пакета built_collection - не создает копию, а возвращает обертку с возможностью записи при изменении

   var builtList = [1, 2, 3].build();
builtList = builtList.rebuild((b) => b..addAll([7, 6, 5]));


6. Использование пакета fast_immutable_collections

   final IList<String> oldList;
var newList = IList.orNull(oldList);


Эти методы помогут вам эффективно работать со списками и картами в Dart. 👍

Оцените нашу новую рубрику и напишите в комментариях, что хотите видеть в следующих постах! 💬

Все подобные новости можно найти по хэштегу #FlutterPulseTips

#flutter #dart #flutterpulse #FlutterPulseTips #codingtips #mobiledevelopment #programming #FlutterTips #DartLang