Flutter Pulse
532 subscribers
354 photos
779 links
На канале будут новости про flutter с сайтов, информация об обновлении пакетов, а также авторский контент.
Download Telegram
Как протестировать дизайн виджета?

Обеспечьте, чтобы обновления не влияли на то, как ваш виджет отображается для пользователя.

Используйте метод golden file. Это проверит, что дизайн остался таким же, как и на изображении.

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



testWidgets('Golden test', (WidgetTester tester) async {
await tester.pumpWidget(MyApp());
await expectLater(
find.byType(MyCard),
matchesGoldenFile('card.png')
);
});



Теперь запуск ваших тестов обеспечит неизменность дизайна. Например, вы создаете карту, используя некоторые аватары и другие виджеты. Если один из дочерних элементов будет изменен, ваша карта не останется прежней, и вы узнаете об этом.

Как сгенерировать Golden файлы?



flutter test --update-goldens



Это сгенерирует golden файлы для каждого вызова matchesGoldenFile в ваших тестах.

Оцените новую рубрику и напишите своё мнение! 👍💬

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

#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #WidgetTesting #GoldenFiles #FlutterTips #DevelopmentTips
Проверьте устаревшие зависимости
Flutter cli спешит на помощь!

Команда Flutter pub outdated



flutter pub outdated
# Показывает устаревшие пакеты.
# [*] указывает на версии, которые не являются последними доступными.

# Имя пакета Текущая Обновляемая Разрешимая Последняя
# прямые зависимости:
adaptive_dialog *1.3.0 1.4.0 1.4.0 1.4.0
cloud_firestore *3.1.6 3.1.10 3.1.10 3.1.10
cloud_functions *3.2.5 3.2.10 3.2.10 3.2.10



Совет по CI: Вы можете извлечь данные в формате json и использовать их в шаге CI. Запуск этого шага каждую неделю на вашей основной ветке (main) и уведомление по электронной почте, если доступна новая версия пакета.

Оцените новую рубрику! 👍💡
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #FlutterTips #MobileDevelopment #CI #DevTips
Создаем собственный экран ошибок

Вам надоело видеть красный или серый экран при возникновении ошибки? 🤔

Это поведение Flutter-приложения по умолчанию. 📱

Примечание: Если вы хотите, чтобы Flutter перестал показывать красный экран в режиме отладки или серый в production-режиме, просто удалите функцию presentError. 💡

Вы можете переопределить виджет ошибки по умолчанию или вообще не показывать ничего... 🤷‍♂️

Хорошим решением может быть перенаправление пользователя и отображение ошибки в виде всплывающего сообщения. 📢



void main() {
FlutterError.onError = (FlutterErrorDetails details) {
FlutterError.presentError(details); // Показываем ошибку
};
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routes: routes,
initialRoute: 'route1',
builder: (context, widget) {
ErrorWidget.builder = (FlutterErrorDetails errorDetails) {
Widget error = Text('...rendering error... : ${errorDetails.summary}');
if (widget is Scaffold || widget is Navigator) {
error = Scaffold(body: Center(child: error));
}
return error;
};
return widget;
},
);
}
}



Оцените нашу новую рубрику! 👍💬 Оставляйте ваши отзывы в комментариях! 💬👇

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

#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #AppDevelopment #ErrorHandling #CustomErrorScreen #FlutterTips
👍2
Создаём круглый индикатор прогресса
Привет, подписчики! 👋 Сегодня мы рассмотрим интересный Flutter-трюк, который поможет вам создать круглый индикатор прогресса с помощью ClipRRect 🌟

Вы можете использовать виджет ClipRRect, чтобы создать круглый индикатор прогресса. Для этого нужно обернуть LinearProgressIndicator в ClipRRect и задать ему радиус границы 🌈



ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(10)),
child: LinearProgressIndicator(
minHeight: 14,
value: progress, // текущий прогресс
color: Colors.red, // цвет прогресса
backgroundColor: Colors.white, // фон индикатора
),
),



В этом примере мы используем LinearProgressIndicator с minHeight равным 14 и оборачиваем его в ClipRRect с радиусом 10, чтобы получить круглый индикатор прогресса 🔴⚪️

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

Все подобные новости можно найти по хэштегу #FlutterPulseTips 🤓
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #UIUX #ProgressIndicator #FlutterTips #CodingTricks #AppDevelopment
👍2
Скачивание файла из Firebase и отслеживание прогресса

Привет, разработчики Flutter! 👋 Сегодня мы рассмотрим полезный совет по загрузке файлов из Firebase Storage и отслеживанию прогресса загрузки. 📈

Код для скачивания файла:


Stream<TaskSnapshot> downloadFile(String path) async* {
if (await Permission.storage.request().isDenied) {
throw "Вы должны принять разрешение на запись";
}
var fileRef = storage.ref().child(path);
var fileName = fileRef.name;
Directory directory;
if (Platform.isAndroid) {
directory = Directory("/storage/emulated/0/Download");
} else {
directory = (await getExternalStorageDirectory())!;
}
final File destinationFile = File('${directory.path}/$fileName');
if (destinationFile.existsSync()) {
destinationFile.deleteSync();
}
destinationFile.createSync();
var task = fileRef.writeToFile(destinationFile);
yield* task.asStream();
}



Ключевые моменты:
- Проверка разрешений: Используем permission_handler для проверки разрешения на доступ к хранилищу.
- Сохранение в папку загрузок: Файл сохраняется в папку "Download" на Android.
- Замена существующего файла: Если файл уже существует, он будет удален и заменен новым.
- Отслеживание прогресса: Используем yield* для передачи событий из задачи в наш поток, что позволяет отображать прогресс загрузки в приложении.

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


var progress = task.bytesTransferred / task.totalBytes * 100;



Оцените нашу новую рубрику советов по Flutter! 👍 Ваши отзывы помогут нам сделать ее еще лучше. 💬

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

#flutter #dart #flutterpulse #FlutterPulseTips #Firebase #MobileDevelopment #FlutterTips #AppDevelopment #CodingTips
👍1
Firestore: конфигурация из нативных приложений

Вы, возможно, пропустили это... Плагин Firebase может использовать конфигурацию напрямую на стороне Dart!

Шаги по настройке:

1. Создайте несколько окружений Firebase для разработки/стадии/продакшена, используя только Dart.
Создайте 3 файла в папке runners. Один для каждой среды.

2. Создайте несколько файлов конфигурации Flavors.
Также сгенерируйте все файлы FirebaseOptions, используя flutterFire cli.

3. Удалите запуск из вашего main.dart и добавьте это:


Future<void> runWrapperApp(FlavorConfig config) async {
// Инициализируйте конфигурацию приложения здесь
// Например, установите уровень журнала на основе среды
final firebaseApp = await Firebase.initializeApp(
options: config.firebaseConfig,
);
runApp(MyApp());
}



4. Запустите приложение:


flutter run -t lib/runners/main_dev.dart



Важно:
- FlutterFire cli добавляет нативную зависимость на iOS/Android.
- Удалите конфигурацию Firebase из папок android и iOS.
- На Android удалите службы Google из build.gradle.

Оцените новую рубрику! 👍 Оставляйте ваши отзывы в комментариях! 💬

Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #Firestore #Firebase #FlutterTips #MobileDevelopment #AppDevelopment
👍1
Оптимизация генерации кода
Ускорьте генерацию кода Flutter ⚡️

Заметка: Что такое генерация кода в Flutter?
Flutter позволяет генерировать шаблонный код с помощью аннотаций над классом/методом.
Это особенно полезно для генерации JSON-объектов (пакет json_serializable) или внедрения сервисов (gate_generator).

Как запустить генерацию кода?
1. Установите пакет build_runner и пакет, генерирующий код (см. примечание выше)
2. Выполните команду:
flutter packages pub run build_runner build --delete-conflicting-outputs


1 - Создайте файл build.yaml в корне проекта, как этот:

targets:
$default:
builders:
gate_generator:gate_schema:
enabled: true
generate_for:
include:
- "lib/gate/**.dart"
- "lib/services/**/**.dart"
- "lib/data/repositories/**.dart"
- "lib/ui/**/**.dart"
exclude:
- "lib/data/entities/**.freezed.dart"
- "lib/data/entities/**.g.dart"
freezed:
enabled: true
generate_for:
exclude:
- test
include:
- lib/data/entities/**
source_gen|combining_builder:
options:
ignore_for_file:
- "type=lint"


Включайте папки, содержащие файлы с аннотациями.
Генераторы кода будут сканировать только эти папки.
Вы можете легко исключать папки или файлы для каждого генератора кода.

Оцените новую рубрику и напишите своё мнение! 👍💬

Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #FlutterTips #CodeGeneration #OptimizeCode #FlutterDevelopment #MobileDevelopment #ProgrammingTips #DevelopmentTips
👍2🔥2
Кнопка с градиентом и анимацией

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

Основная идея:
Мы создадим кнопку, у которой при нажатии будет изменяться градиентный фон с анимацией. Для этого мы используем AnimatedGradientButton, который будет обрабатывать анимацию.

Код примера:


class AnimatedGradientButton extends StatefulWidget {
final Text? label;
final Gradient gradient;
final Gradient onPushGradient;
final Icon? icon;
final Function()? onPressed;

AnimatedGradientButton({
this.label,
required this.gradient,
required this.onPushGradient,
this.icon,
this.onPressed,
});

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

class _AnimatedGradientButtonState extends State<AnimatedGradientButton>
with TickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;

@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(milliseconds: 1000),
vsync: this,
);
_animation = CurvedAnimation(curve: Curves.decelerate, parent: _controller);
}

@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
gradient: LinearGradient(
colors: widget.gradient.colors.map((color) => Color.lerp(
color,
widget.onPushGradient.colors[widget.gradient.colors.indexOf(color)],
_animation.value,
)).toList(),
),
),
child: MaterialButton(
onPressed: () {
_controller.forward();
widget.onPressed?.call();
_controller.reverse();
},
child: widget.label,
),
);
},
);
}
}



Как это работает:
1. Мы оборачиваем MaterialButton в контейнер с градиентным фоном.
2. При нажатии на кнопку запускается анимация, которая изменяет градиент от исходного к целевому.
3. Color.lerp используется для плавного перехода между цветами градиента.

Перспективы:
- Можно создать собственный объект рендеринга.
- Полностью переработать кнопку без использования MaterialButton.
- Расширить ButtonStyleButton как обычные кнопки.

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

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

#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #UIUX #Animation #FlutterTips #DartLang #GradientButton #AnimatedButton
🔥2👍1
🚀 Расширяем возможности Flutter с помощью FFI: Вызываем функции из GO!

Привет, Flutter-энтузиасты! Руслан подготовил 🔥горячее видео, которое откроет вам мир межъязыкового взаимодействия. Узнайте, как заставить Dart и Go работать в тандеме через FFI (Foreign Function Interface)!

👉 Смотрите видео здесь:
Расширяем возможности Flutter с помощью FFI. Вызываем функции из GO

В этом выпуске вы узнаете:
🔹 Как передавать строки между Dart и Go (и обратно!)
🔹 Особенности работы с памятью и Garbage Collector
🔹 Магию горутин (goroutine) и defer
🔹 Практические примеры вызова Go-кода из Flutter-приложений

Почему это важно?
Вы сможете использовать сильные стороны Go (например, многопоточность через горутины) в своих Flutter-проектах! Автор наглядно показывает процесс компиляции, преобразования типов и управления памятью.

💡 В следующих выпусках:
- Работа с Rust, Python и C++ через FFI
- Продвинутые техники оптимизации


🔥 P.S. Увидите, как Go-горутины ускоряют вычисления в сравнении с Dart-изолятами!

#Flutter #Dart #FlutterPulse #FlutterPulseTips #FlutterPulseYoutube
#FFI #Golang #MobileDevelopment #CrossPlatform

👉 Больше полезного в плейлисте: #FlutterPulseYoutube
Шпаргалка по Dart map

Maps are fast - Карты работают быстро

Карта - это коллекция пар ключ/значение. Значение извлекается из карты с помощью связанного с ним ключа.

В Dart существует 3 типа карт:
- HashMap - неупорядоченная
- LinkedHashMap - упорядоченная по порядку вставки
- SplayTreeMap - упорядоченная по ключам



// Простая карта со строковым ключом: строковым значением
var data = {'name': 'John Doe', 'occupation': 'gardener'};
// карта, типизированная с помощью конструктора Map<String, String>()
var data2 = <int, String>{1: 'sky', 2: 'falcon', 3: 'rock'};



Преобразование списка в карту



// преобразование списка в карту
var resultMap = Map.fromIterable(list, key: (v) => v[0], value: (v) => v[1]);
// или
var result = { for (var v in list) v[0]: v[1] };
// или просто используя метод asMap() для автоматического индексирования
var result = ["test","test2","test3"].asMap(); // {0: test, 1: test2, 2: test3}



Зачем использовать карту?

Доступ к элементу в списке с использованием indexOf или contains имеет сложность O(n).

Доступ к элементу или проверка его наличия в карте занимает O(1).

Карты выигрывают в этом

Как создать неизменяемую карту?

https://pub.dev/packages/built_collection - Этот пакет предоставляет способы создания неизменяемых карт (разработан командой Dart).

Функции карты



var details = {'Usrname': 'bruce', 'Password': 'mypas'};
// добавление
details['Uid'] = '3802983209A';
// обновление
details.putIfAbsent("Uid", () => "3802983209A");
// преобразование в другую карту
details.map((key, value) => MapEntry(key, "$key:$value"));
// приведение к другому типу
details.cast<int, int>();
// проверка наличия ключа
details.containsKey("key"); // сложность O(1)
// копирование
var copy = {...details};
// обновление
details.update("Usrname", (value) => "joker");



Оцените новую рубрику! 👍💬

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

#flutter #dart #flutterpulse #FlutterPulseTips #DartTips #MobileDevelopment #ProgrammingTips #Coding #FlutterCommunity
👍2
Создаем чистую круглую кнопку
Как сделать свою собственную круглую кнопку в Flutter? 🤔

В этом совете мы покажем, как создать красивую и простую круглую кнопку для вашего Flutter-приложения. 📱

Давайте разберем пример кода:


const CircleButton({
super.key,
required this.bgColor, // Цвет фона кнопки
required this.borderColor, // Цвет границы кнопки
required this.iconColor, // Цвет иконки
required this.onTap, // Обработчик нажатия
required this.radius, // Радиус кнопки
required this.iconSize, // Размер иконки
required this.borderWidth, // Ширина границы
required this.icon, // Иконка
this.disabled = false, // Флаг блокировки кнопки
});

@override
Widget build(BuildContext context) {
return Opacity(
opacity: disabled ? 0.5 : 1, // Изменяем прозрачность, если кнопка заблокирована
child: ClipOval(
child: Material(
color: Colors.transparent, // Прозрачный фон для эффекта Ink
// Ink покажет эффект касания, который вы видите на всех кнопках Flutter
child: Ink(
width: radius,
height: radius,
decoration: BoxDecoration(
shape: BoxShape.circle, // Круглая форма
color: bgColor, // Цвет фона
border: Border.all(color: borderColor, width: borderWidth), // Граница кнопки
),
child: InkWell(
onTap: () {
if (disabled) {
return; // Ничего не делаем, если кнопка заблокирована
}
// Даем легкую вибрационную обратную связь
HapticFeedback.lightImpact();
// Вызываем метод onTap
onTap();
},
child: Icon(icon, color: iconColor, size: iconSize), // Иконка внутри кнопки
),
),
),
),
);
}



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

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

#flutter #dart #flutterpulse #FlutterPulseTips #mobiledevelopment #uiux #fluttertutorial #codingtips
👍1