Flutter Pulse
524 subscribers
349 photos
768 links
На канале будут новости про flutter с сайтов, информация об обновлении пакетов, а также авторский контент.
Download Telegram
Полезный совет по Dart: Как изменить версию Flutter

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

Иногда возникает необходимость изменить версию Flutter. Вот как это можно сделать:

1. Проверьте, где установлен Flutter на вашей системе, а затем выполните команду:
git checkout 1.22.6
> Updating files: 100% (4559/4559), done.
> Note: switching to '1.22.6'.

После этого следующая команда flutter установит все необходимые требования.

2. Чтобы вернуться к последней стабильной версии, просто используйте:
git checkout stable

Или используйте FVM для быстрого переключения версий Flutter:

1. Активируйте FVM:
dart pub global activate fvm

2. Используйте нужную версию:
fvm use 1.22.6

Дополнительная информация доступна на сайте FVM:
https://fvm.app/docs/getting_started/installation
https://fvm.app/

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

Все подобные советы ищите по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #FlutterTips #MobileDev #DevTips #FlutterCommunity
Создаем защиту маршрута страницы

Привет, подписчики! 👋 Сегодня мы рассмотрим полезный совет по Flutter - создание защиты маршрута страницы. 🚀

Что это такое?

Защита маршрута страницы позволяет перенаправлять пользователя на другую страницу, если определенное условие не выполнено. 🔄

Пример реализации



Route<dynamic> route(RouteSettings settings) {
switch (settings.name) {
case 'init_account':
return MaterialPageRoute(
builder: (_) => AuthenticatedGuard(child: InitAccountPage()),
);
}
}

// AuthenticatedGuard внедряет нашу защиту, чтобы предотвратить доступ неавторизованного пользователя к нашей странице

class Guard extends StatelessWidget {
final Future<bool> canActivate;
final Widget child;
final String fallbackRoute;

const Guard({
Key? key,
required this.canActivate,
required this.child,
required this.fallbackRoute,
}) : super(key: key);

@override
Widget build(BuildContext context) {
return FutureBuilder<bool>(
future: canActivate,
builder: (_, isOk) {
if (!isOk.hasData || isOk.hasError) {
return Container();
}
if (isOk.data!) {
return child; // Показываем страницу, если условие выполнено
}
redirect(context); // Иначе перенаправляем
return Container();
},
);
}

redirect(BuildContext context) {
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
Navigator.pushReplacementNamed(context, fallbackRoute);
});
}
}



Совет для нескольких условий: вы можете каскадировать защиты или просто объединить ваши условия. 🤔

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

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

#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #FlutterTips #Programming #Development #Coding #FlutterCommunity
👍1
Полезный совет по Dart: Как изменить версию Flutter

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

Иногда возникает необходимость изменить версию Flutter. Вот как это можно сделать:

1. Проверьте, где установлен Flutter на вашей системе, а затем выполните команду:
git checkout 1.22.6
> Updating files: 100% (4559/4559), done.
> Note: switching to '1.22.6'.

После этого следующая команда flutter установит все необходимые требования.

2. Чтобы вернуться к последней стабильной версии, просто используйте:
git checkout stable

Или используйте FVM для быстрого переключения версий Flutter:

1. Активируйте FVM:
dart pub global activate fvm

2. Используйте нужную версию:
fvm use 1.22.6

Дополнительная информация доступна на сайте FVM:
https://fvm.app/docs/getting_started/installation
https://fvm.app/

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

Все подобные советы ищите по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #FlutterTips #MobileDev #DevTips #FlutterCommunity
Запускайте тесты с несколькими вариантами

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

Вы когда-нибудь сталкивались с ситуацией, когда нужно протестировать один и тот же сценарий с разными входными данными? Вместо того, чтобы писать множество повторяющихся тестов, вы можете использовать возможности ValueVariant из Flutter! 🔥



final timesVariant = ValueVariant<double>({1, 10, 100, 1000}); // Создаём вариант со списком значений

testWidgets('push counter N times', (
WidgetTester tester,
) async {
await tester.pumpWidget(const myApp()); // Инициализируем виджет
for (int i = 0; i < timesVariant.currentValue!; i++) { // Получаем текущее значение варианта
await tester.tap(find.byType(OutlinedButton).first); // Симулируем нажатие кнопки
}
expect(find.text("pushed ${timesVariant.currentValue!} times"), findsOneWidget); // Проверяем текст
}, variant: timesVariant); // Устанавливаем вариант для теста




В этом примере мы:
1. Создаём ValueVariant с нужными нам значениями.
2. Используем timesVariant.currentValue внутри теста, чтобы получить текущее значение.
3. Указываем variant: timesVariant, чтобы тест выполнился для каждого значения.

Таким образом, вы экономите время и пишете более чистый код! 💪

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

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

#flutter #dart #flutterpulse #FlutterPulseTips #FlutterTips #MobileDevelopment #Testing #ValueVariant #FlutterTesting #CodingTips
👍1
Форматирование JSON с помощью Dart

Привет, разработчики! 👋 Сегодня мы рассмотрим полезный совет по работе с JSON в Dart. Вы узнаете, как красиво напечатать JSON-строку, сделав её более читаемой и удобной для отладки 🛠️

Проблема: JSON-данные часто приходят в компактном, неформатированном виде, что затрудняет их чтение и анализ.

Решение: Используйте класс JsonEncoder из пакета dart:convert для форматирования JSON.


import 'dart:convert';

// Создаём кодировщик с отступами для форматирования
var encoder = const JsonEncoder.withIndent(' ');
// Преобразуем данные в красиво отформатированную строку
String prettyprint = encoder.convert(data);


Этот простой код позволяет превратить нечитаемую JSON-строку в структурированный и понятный формат с отступами 🌟

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

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

#flutter #dart #flutterpulse #FlutterPulseTips #JSON #DartTips #FlutterTips #CodingTips #AppDevelopment #MobileDevelopment
👍31
Запускайте тесты на нескольких размерах экрана

Предотвратите переполнение для разных размеров экранов 🤯

Это позволит запустить тест с каждой конфигурацией экрана в screenSizeVariants 📱


final screenSizeVariants = ValueVariant<ScreenSize>(basicPhones);

testWidgets('''клик на кнопку => отображается закрепленный виджет наложения''', (
WidgetTester tester,
) async {
await tester.setScreenSize(screenSizeVariants.currentValue!);

await tester.pumpWidget(const MyAppWithCircleAnchored());
expect(find.byType(AnchoredHelper), findsNothing);
await tester.tap(find.byType(OutlinedButton).first);
await tester.pump(const Duration(seconds: 2));
expect(find.byType(AnchoredHelper), findsOneWidget);
}, variant: screenSizeVariants);



import 'dart:ui';
import 'package:flutter_test/flutter_test.dart';

// это определяет конфигурацию размера конкретного устройства
class ScreenSize {
// имя этой конфигурации
final String name;

// конфигурация размера и плотность пикселей
final double width, height, pixelDensity;

const ScreenSize(this.name, this.width, this.height, this.pixelDensity);

@override
String toString() => name;
}

extension ScreenSizeManager on WidgetTester {
Future<void> setScreenSize(ScreenSize screenSize) async {
return _setScreenSize(
width: screenSize.width,
height: screenSize.height,
pixelDensity: screenSize.pixelDensity,
);
}

Future<void> _setScreenSize({
double width = 540,
double height = 960,
double pixelDensity = 1,
}) async {
final size = Size(width, height);
await binding.setSurfaceSize(size);
binding.window.physicalSizeTestValue = size;
binding.window.devicePixelRatioTestValue = pixelDensity;
}
}


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

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

#flutter #dart #flutterpulse #FlutterPulseTips #MobileDevelopment #TestingTips #ScreenSize #FlutterTips
👍1
Простой доступ к виджету в тесте

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

Вы когда-нибудь сталкивались с ситуацией, когда вам нужно было получить доступ к конкретному виджету внутри теста? 🤔 Обычно для этого приходилось писать длинные цепочки методов, что делало код теста громоздким и трудночитаемым. 😩

Но есть решение! 💡 Вы можете создать свою собственную утилиту для прямого доступа к виджету. 📦


import 'package:flutter_test/flutter_test.dart';

// Вспомогательная функция для прямого доступа к виджету
T findWidget<T>() => find
.byType(T)
.evaluate()
.first
.widget as T;

// Вспомогательная функция для прямого доступа к N-му виджету типа T
T findNWidget<T>(int n) => find
.byType(T)
.evaluate()
.toList()
.elementAt(n)
.widget as T;


Теперь вы можете использовать эти функции, чтобы упростить свои тесты. Например, вместо того, чтобы писать:

// можно заменить это
final miniature = find.byType(VideoMiniature)
.evaluate()
.first
.widget as VideoMiniature;

// на это
final miniature = findWidget<VideoMiniature>();


Такой подход не только делает ваш код теста более читаемым, но и экономит время при написании новых тестов. ⏱️

Оцените нашу новую рубрику и оставьте свои отзывы! 🤗 Нам важно ваше мнение, чтобы мы могли делать наш контент лучше для вас.

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

#flutter #dart #flutterpulse #FlutterPulseTips #FlutterTips #MobileDevelopment #Testing #CodeQuality
👍1🔥1
Документ Firebase как модель сущности

Привет, разработчики Flutter! 👋 Сегодня мы поделимся с вами полезным советом о том, как использовать документ Firebase в качестве модели сущности в вашем приложении Flutter. 📱💻

Вы когда-нибудь сталкивались с необходимостью внедрить идентификатор документа Firebase в вашу модель данных, не сохраняя его в самом документе? 🤔 Теперь это легко сделать с помощью пакета json_serializable! 🎉

Вот пример кода, который показывает, как это можно сделать:


@JsонSerializable()
class DogEntity {
// получаем id в нашу сущность
@JsонKey(toJsон: Converters.id, includeIfNull: false)
final String? id;
final String name;

// внедряем id в нашу сущность
factory DogEntity.fromJsон(String id, Map<String, dynamic> jsон) =>
_$DogEntityFromJsон(jsон..['id'] = id);

...
}

class Converters {
// предотвращаем сохранение id в документ
static String? id(String? id) => null;
}



В этом примере мы используем аннотацию @JsonKey для указания того, как должен быть сериализован идентификатор документа. Мы также используем фабричный конструктор fromJson для внедрения идентификатора документа в нашу модель данных. 📈

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

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

#flutter #dart #flutterpulse #FlutterPulseTips #Firebase #json_serializable #MobileDevelopment #FlutterTips
Как протестировать дизайн виджета?

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

Используйте метод 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👍1
Как создать список чекбоксов с помощью CheckboxListTile

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

Преимущества CheckboxListTile:
- Упрощает создание списков с чекбоксами
- Позволяет легко управлять состоянием выбранных элементов
- Поддерживает стандартный стиль Material Design

Пример кода:


class SkillsFilterList extends StatelessWidget {
final SkillsFilter skillsFilter;
final Function() onChanged;

const SkillsFilterList({
Key? key,
required this.skillsFilter,
required this.onChanged,
}) : super(key: key);

@override
Widget build(BuildContext context) {
return ListView.separated(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemCount: skillsFilter.value.length,
separatorBuilder: (context, index) => const SizedBox.shrink(),
itemBuilder: (context, index) {
final skill = this.skillsFilter.value[index];
return ListTileTheme(
contentPadding: EdgeInsets.all(0),
child: CheckboxListTile(
dense: true,
title: Text(skill.scopeName),
value: skill.chosed,
onChanged: (skill) {
skillsFilter.select(skill);
onChanged();
},
),
);
},
);
}
}



Ключевые моменты:
ListView.separated используется для создания списка с разделителями
CheckboxListTile упрощает создание элемента списка с чекбоксом и текстом
✦ Свойство onChanged обрабатывает изменения состояния чекбокса

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

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

#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #UIUX #FlutterTips #AppDevelopment #CodingTips
👍31
Кнопка с градиентом и анимацией

Привет, подписчики! 👋 Сегодня мы рассмотрим интересный пример создания анимированной кнопки с градиентным фоном во 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