Полезный совет по Dart: Как изменить версию Flutter
Привет, разработчики! 👋 Сегодня мы поделимся с вами полезным советом о том, как легко переключаться между версиями Flutter. 💡
Иногда возникает необходимость изменить версию Flutter. Вот как это можно сделать:
1. Проверьте, где установлен Flutter на вашей системе, а затем выполните команду:
После этого следующая команда flutter установит все необходимые требования.
2. Чтобы вернуться к последней стабильной версии, просто используйте:
Или используйте FVM для быстрого переключения версий Flutter:
1. Активируйте FVM:
2. Используйте нужную версию:
Дополнительная информация доступна на сайте FVM:
https://fvm.app/docs/getting_started/installation
https://fvm.app/
Оцените нашу новую рубрику и напишите в комментариях, какие темы вас интересуют! 🤔💬
Все подобные советы ищите по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #FlutterTips #MobileDev #DevTips #FlutterCommunity
Привет, разработчики! 👋 Сегодня мы поделимся с вами полезным советом о том, как легко переключаться между версиями 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
Полезный совет по Dart: Как изменить версию Flutter
Привет, разработчики! 👋 Сегодня мы поделимся с вами полезным советом о том, как легко переключаться между версиями Flutter. 💡
Иногда возникает необходимость изменить версию Flutter. Вот как это можно сделать:
1. Проверьте, где установлен Flutter на вашей системе, а затем выполните команду:
После этого следующая команда flutter установит все необходимые требования.
2. Чтобы вернуться к последней стабильной версии, просто используйте:
Или используйте FVM для быстрого переключения версий Flutter:
1. Активируйте FVM:
2. Используйте нужную версию:
Дополнительная информация доступна на сайте FVM:
https://fvm.app/docs/getting_started/installation
https://fvm.app/
Оцените нашу новую рубрику и напишите в комментариях, какие темы вас интересуют! 🤔💬
Все подобные советы ищите по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #FlutterTips #MobileDev #DevTips #FlutterCommunity
Привет, разработчики! 👋 Сегодня мы поделимся с вами полезным советом о том, как легко переключаться между версиями 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
Спам кнопок: как предотвратить множественные нажатия?
Вы когда-нибудь сталкивались с ситуацией, когда пользователь нажимает кнопку несколько раз подряд, вызывая нежелательные действия? 🤯
Представьте, что пользователь нажимает кнопку "Лайк" 10 раз за 1 секунду! 👍 Как сделать так, чтобы событие сработало только один раз? 🤔
Решение: использование RxDart с debounceTime ⏱️
Этот код создает кнопку "Лайк", которая срабатывает только один раз в секунду, даже если пользователь нажимает ее несколько раз подряд. 🔥
Оцените нашу новую рубрику и оставьте свои отзывы! 😊
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #RxDart #DebounceTime #ButtonSpam #SpamProtection
Вы когда-нибудь сталкивались с ситуацией, когда пользователь нажимает кнопку несколько раз подряд, вызывая нежелательные действия? 🤯
Представьте, что пользователь нажимает кнопку "Лайк" 10 раз за 1 секунду! 👍 Как сделать так, чтобы событие сработало только один раз? 🤔
Решение: использование RxDart с debounceTime ⏱️
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:rxdart/subjects.dart';
import 'package:rxdart/rxdart.dart';
class LikeButtonWidget extends StatefulWidget {
final Function onTap;
const LikeButtonWidget({required this.onTap, Key? key}) : super(key: key);
@override
_LikeButtonWidgetState createState() => _LikeButtonWidgetState();
}
class _LikeButtonWidgetState extends State<LikeButtonWidget> {
final pushSubject = BehaviorSubject<void>();
late StreamSubscription<void> pushSubscription;
@override
void initState() {
super.initState();
pushSubscription = pushSubject.stream
.debounceTime(const Duration(milliseconds: 1000))
.listen((_) {
// отправить запрос на сервер или выполнить другое действие
widget.onTap();
});
}
@override
void dispose() {
super.dispose();
pushSubscription.cancel(); // не забудьте отменить подписку на поток
}
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
pushSubject.add(null);
},
child: const Icon(Icons.plus_one),
);
}
}
Этот код создает кнопку "Лайк", которая срабатывает только один раз в секунду, даже если пользователь нажимает ее несколько раз подряд. 🔥
Оцените нашу новую рубрику и оставьте свои отзывы! 😊
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #RxDart #DebounceTime #ButtonSpam #SpamProtection
👍2🔥1
Центрирование формы без скрытия полей при открытом клавиатуре
Привет, подписчики! 👋 Сегодня мы рассмотрим полезный совет по Flutter, который поможет вам улучшить пользовательский опыт в ваших приложениях. 📱💡
Проблема: Когда клавиатура открывается, поля формы могут быть скрыты, что затрудняет ввод данных пользователем. 😕
Решение: Использовать
Как это работает:
-
-
-
👍 Оцените новую рубрику и напишите в комментариях, какие темы вам интересны! 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips. 🔍
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #UIUX #AppDevelopment #CodingTips
Привет, подписчики! 👋 Сегодня мы рассмотрим полезный совет по Flutter, который поможет вам улучшить пользовательский опыт в ваших приложениях. 📱💡
Проблема: Когда клавиатура открывается, поля формы могут быть скрыты, что затрудняет ввод данных пользователем. 😕
Решение: Использовать
Scaffold
с параметром resizeToAvoidBottomInset: true
и обернуть форму в SingleChildScrollView
. 📝
Scaffold(
resizeToAvoidBottomInset: true, // Изменяет размер при открытии клавиатуры
body: Form(
key: _formKey,
child: SingleChildScrollView( // Позволяет прокручивать содержимое
child: SizedBox(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center, // Центрирует содержимое
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Spacer(flex: 1), // Гибкое пространство сверху
TextFormField(...), // Поля формы
TextFormField(...),
const Spacer(flex: 1), // Гибкое пространство снизу
],
),
),
),
),
)
Как это работает:
-
resizeToAvoidBottomInset: true
заставляет Scaffold
изменять размер при открытии клавиатуры. 🔄-
SingleChildScrollView
позволяет прокручивать содержимое формы, если оно не помещается на экране. 🔄-
Spacer
с гибким размером (flex: 1
) обеспечивает равномерное распределение пространства сверху и снизу формы. ⚖️👍 Оцените новую рубрику и напишите в комментариях, какие темы вам интересны! 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips. 🔍
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #UIUX #AppDevelopment #CodingTips
👍4❤1🔥1🤯1
Круглый аватар с границей
Круглый аватар не имеет границы, но есть быстрый способ добавить её!
Если вы не хотите переписывать виджет CircleAvatar...
Просто оберните его ещё в один или используйте Container с градиентом.
Оцените новую рубрику лайком 👍 и подпишитесь, чтобы не пропустить новые советы! 😉
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledev #appdevelopment #uiux #codingtips
Круглый аватар не имеет границы, но есть быстрый способ добавить её!
Если вы не хотите переписывать виджет CircleAvatar...
Просто оберните его ещё в один или используйте Container с градиентом.
CircleAvatar(
radius: radius + 2, // Увеличиваем радиус для границы
backgroundColor: borderColor, // Цвет границы
child: CircleAvatar(
radius: radius, // Радиус внутреннего аватара
backgroundImage: NetworkImage(url), // Изображение из сети
),
);
Оцените новую рубрику лайком 👍 и подпишитесь, чтобы не пропустить новые советы! 😉
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledev #appdevelopment #uiux #codingtips
👍3
Как создать список чекбоксов с помощью CheckboxListTile
Привет, подписчики! 👋 Сегодня мы рассмотрим, как легко создать список чекбоксов в вашем Flutter-приложении, используя виджет CheckboxListTile. 📝
Преимущества CheckboxListTile:
- Упрощает создание списков с чекбоксами
- Позволяет легко управлять состоянием выбранных элементов
- Поддерживает стандартный стиль Material Design
Пример кода:
Ключевые моменты:
✦ ListView.separated используется для создания списка с разделителями
✦ CheckboxListTile упрощает создание элемента списка с чекбоксом и текстом
✦ Свойство onChanged обрабатывает изменения состояния чекбокса
Оцените эту рубрику и напишите в комментариях, какие темы вы хотели бы видеть в будущих выпусках! 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #UIUX #FlutterTips #AppDevelopment #CodingTips
Привет, подписчики! 👋 Сегодня мы рассмотрим, как легко создать список чекбоксов в вашем 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
👍4❤1
Работаем с клавиатурными сокращениями
При создании приложений для Flutter Web или Desktop, важно обеспечить удобное управление клавиатурными сокращениями. В этом нам помогут виджеты Shortcuts и Actions! 🚀
Shortcuts - это виджет, который создаёт привязку клавиш к определённым действиям для своих потомков. Всё просто: вы предоставляете карту клавиш и интенций (Intent).
Actions - этот виджет позволяет потомкам вызывать действия, определённые в родителе. Его можно использовать как вместе с Shortcuts, так и отдельно 😉
Давайте рассмотрим пример кода:
В этом примере мы создаём клавиатурное сокращение Ctrl+A для вызова действия SelectAllAction. Просто и удобно! 👍
Оцените нашу новую рубрику и напишите, о чём бы вы хотели узнать в следующий раз 🤔
Все подобные советы ищите по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #FlutterTips #MobileDev #KeyboardShortcuts #FlutterDev #CodingTips
При создании приложений для Flutter Web или Desktop, важно обеспечить удобное управление клавиатурными сокращениями. В этом нам помогут виджеты Shortcuts и Actions! 🚀
Shortcuts - это виджет, который создаёт привязку клавиш к определённым действиям для своих потомков. Всё просто: вы предоставляете карту клавиш и интенций (Intent).
Actions - этот виджет позволяет потомкам вызывать действия, определённые в родителе. Его можно использовать как вместе с Shortcuts, так и отдельно 😉
Давайте рассмотрим пример кода:
// Это просто используется для указания нужного действия
class SelectAllIntent extends Intent {}
@override
Widget build(BuildContext context) {
return Shortcuts(
shortcuts: <LogicalKeySet, Intent>{
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyA): SelectAllIntent(),
},
child: Actions(
dispatcher: LoggingActionDispatcher(),
actions: <Type, Action<Intent>>{
SelectAllIntent: SelectAllAction(),
},
child: Builder(
builder: (BuildContext context) => TextButton(
onPressed: Actions.handler<SelectAllIntent>(context, SelectAllIntent()),
child: const Text('SELECT ALL'),
),
),
),
);
}
// Action будет содержать логику, которую вы хотите выполнить при срабатывании клавиатурного сокращения
class SelectAllAction extends Action<SelectAllIntent> {
@override
void invoke(covariant SelectAllIntent intent) {
// делайте то, что вам нужно
}
}
В этом примере мы создаём клавиатурное сокращение Ctrl+A для вызова действия SelectAllAction. Просто и удобно! 👍
Оцените нашу новую рубрику и напишите, о чём бы вы хотели узнать в следующий раз 🤔
Все подобные советы ищите по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #FlutterTips #MobileDev #KeyboardShortcuts #FlutterDev #CodingTips
👍3
Изменение яркости системной панели
Отобразить системную панель с правильной яркостью на iOS и Android 🚀
При разработке мобильных приложений важно обеспечить корректное отображение системной панели на разных платформах. В этой статье мы рассмотрим, как изменить яркость системной панели в приложениях Flutter для iOS и Android.
Код для изменения яркости системной панели:
Обратите внимание:
-
-
Особенности для iOS: 🤔
На iOS строка состояния может быть изначально скрыта. Чтобы отобразить ее, откройте ваш проект в Xcode и убедитесь, что свойство
👍 Оцените нашу новую рубрику советов по Flutter! Ваши отзывы помогут нам сделать контент еще лучше.
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #iOS #Android #FlutterTips #DevTips
Отобразить системную панель с правильной яркостью на iOS и Android 🚀
При разработке мобильных приложений важно обеспечить корректное отображение системной панели на разных платформах. В этой статье мы рассмотрим, как изменить яркость системной панели в приложениях Flutter для iOS и Android.
Код для изменения яркости системной панели:
SystemChrome.setSystemUIOverlayStyle(
SystemUIOverlayStyle(
statusBarColor: Colors.transparent, // Прозрачный цвет статус-бара
statusBarBrightness: // Установка яркости статус-бара в зависимости от темы
mode == ThemeMode.light ? Brightness.light : Brightness.dark,
statusBarIconBrightness: // Установка яркости иконок статус-бара в зависимости от темы
mode == ThemeMode.light ? Brightness.dark : Brightness.light,
),
);
Обратите внимание:
-
statusBarBrightness
применяется только на Android.-
statusBarIconBrightness
также применяется только на Android, но с инвертированными значениями для iOS.Особенности для iOS: 🤔
На iOS строка состояния может быть изначально скрыта. Чтобы отобразить ее, откройте ваш проект в Xcode и убедитесь, что свойство
status bar initially hidden
не отмечено.👍 Оцените нашу новую рубрику советов по Flutter! Ваши отзывы помогут нам сделать контент еще лучше.
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #iOS #Android #FlutterTips #DevTips
👍2
Воспроизведение видео на весь экран
Покажите полноэкранное видео с правильным соотношением сторон 🤩
Чтобы показать видео на весь экран с сохранением правильного соотношения сторон, следуйте этим простым шагам:
1. Установите пакет
2. Встройте видеоплеер внутрь виджета
Обеспечьте, чтобы содержимое занимало весь экран 📱
Код виджета VideoContainer:
Оцените новую рубрику FlutterPulseTips 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledev #appdev #codingtips #uiux #videostreaming #fullscreenvideo
Покажите полноэкранное видео с правильным соотношением сторон 🤩
Чтобы показать видео на весь экран с сохранением правильного соотношения сторон, следуйте этим простым шагам:
1. Установите пакет
video_player
📦2. Встройте видеоплеер внутрь виджета
VideoContainer
📺Обеспечьте, чтобы содержимое занимало весь экран 📱
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
),
extendBodyBehindAppBar: true,
body: Stack(
children: [
Positioned.fill(
child: GestureDetector(
onTap: () => videoListener?.pauseOrResume(),
child: VideoContainer.fromController(_controller!),
),
),
],
),
);
Код виджета VideoContainer:
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class VideoContainer extends StatelessWidget {
final Widget child;
final double ratio;
final Size contentsSize;
const VideoContainer({
super.key,
required this.child,
required this.ratio,
required this.contentsSize,
});
factory VideoContainer.fromController(VideoPlayerController controller) =>
VideoContainer(
ratio: controller.value.aspectRatio,
contentsSize: controller.value.size,
child: VideoPlayer(controller),
);
@override
Widget build(BuildContext context) {
return FittedBox(
fit: BoxFit.cover,
child: AspectRatio(
aspectRatio: ratio,
child: child,
),
);
}
}
Оцените новую рубрику FlutterPulseTips 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledev #appdev #codingtips #uiux #videostreaming #fullscreenvideo
👍1
Получайте ⭐ отзывы в магазинах
Это не так просто, но есть некоторые нюансы, которые стоит знать
Проблема:
• Apple Store ограничивает запрос оценки через нативное всплывающее окно до 2 раз в год
• Google Play Store ограничивает запрос оценки примерно 2 раза каждые 3 месяца...
• Вы не хотите докучать пользователям и получать плохие оценки
Запрашивайте оценку в подходящее время:
Найдите "момент истины", когда пользователь получил наилучший опыт от использования вашего приложения. И запросите оценку именно в этот момент. Никогда не спрашивайте оценку у тех, кто только что установил приложение или никогда с ним не взаимодействовал...
Будьте терпеливы
Решение:
Создайте предварительный попап или карточку в вашем приложении
Но не пытайтесь повлиять на решение пользователя
Оцените новую рубрику и напишите в комментариях, насколько она вам полезна! 😊👍
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDevTips #ProgrammingTips
Это не так просто, но есть некоторые нюансы, которые стоит знать
Проблема:
• Apple Store ограничивает запрос оценки через нативное всплывающее окно до 2 раз в год
• Google Play Store ограничивает запрос оценки примерно 2 раза каждые 3 месяца...
• Вы не хотите докучать пользователям и получать плохие оценки
Запрашивайте оценку в подходящее время:
Найдите "момент истины", когда пользователь получил наилучший опыт от использования вашего приложения. И запросите оценку именно в этот момент. Никогда не спрашивайте оценку у тех, кто только что установил приложение или никогда с ним не взаимодействовал...
Будьте терпеливы
Решение:
Создайте предварительный попап или карточку в вашем приложении
Но не пытайтесь повлиять на решение пользователя
void _showReviewPopup() {
// Проверяем, согласен ли пользователь оставить отзыв
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Оцените наше приложение!'),
content: Text('Если вам нравится наше приложение, пожалуйста, оставьте отзыв в магазине приложений.'),
actions: <Widget>[
TextButton(
child: Text('Не сейчас'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text('Оставить отзыв'),
onPressed: () {
// Ссылка на страницу оценки в магазине
launchReviewUrl(); // Реализуйте эту функцию для открытия нужного URL
Navigator.of(context).pop();
},
),
],
);
},
);
}
// Функция для открытия URL (пример)
void launchReviewUrl() async {
const url = 'https://your-app-review-url.com'; // Замените на реальную ссылку
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Не удалось открыть $url';
}
}
Оцените новую рубрику и напишите в комментариях, насколько она вам полезна! 😊👍
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDevTips #ProgrammingTips
👍4
Запуск анимации при изменении свойства
Привет, подписчики! 👋 Сегодня мы рассмотрим интересный вопрос: как запустить анимацию каждый раз, когда меняется определенное свойство? 🤔
Представьте, что у вас есть виджет, который должен анимироваться при изменении определенного свойства. Например, вы хотите запустить анимацию загрузки при изменении состояния загрузки. 📈
Для этого мы можем использовать метод
Пример кода:
В этом примере мы проверяем, изменилось ли свойство
Как это работает?
1. Мы используем метод
2. Мы сравниваем старое и новое значения свойства
3. В зависимости от изменения, мы запускаем анимацию вперед или назад.
Оцените новую рубрику и напишите в комментариях, что вы думаете! 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips 👍
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledev #appdev #animation #ui #ux #codingtips #programming #softwaredevelopment
Привет, подписчики! 👋 Сегодня мы рассмотрим интересный вопрос: как запустить анимацию каждый раз, когда меняется определенное свойство? 🤔
Представьте, что у вас есть виджет, который должен анимироваться при изменении определенного свойства. Например, вы хотите запустить анимацию загрузки при изменении состояния загрузки. 📈
Для этого мы можем использовать метод
didUpdateWidget
в StatefulWidget
. Этот метод вызывается каждый раз, когда виджет обновляется. 🔄Пример кода:
@override
void didUpdateWidget(covariant UploadedAvatarAnimation oldWidget) {
super.didUpdateWidget(oldWidget);
final (wasUploading, isUploading) = (oldWidget.isUploading, widget.isUploading);
switch ((wasUploading, isUploading)) {
case (false, true):
_controller.forward(from: 0);
_initScaleAnim(0, pt);
case (true, false):
_controller.reverse(from: 1);
default:
}
}
В этом примере мы проверяем, изменилось ли свойство
isUploading
, и запускаем анимацию соответствующим образом. 🔮Как это работает?
1. Мы используем метод
didUpdateWidget
, чтобы отслеживать изменения виджета.2. Мы сравниваем старое и новое значения свойства
isUploading
.3. В зависимости от изменения, мы запускаем анимацию вперед или назад.
Оцените новую рубрику и напишите в комментариях, что вы думаете! 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips 👍
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledev #appdev #animation #ui #ux #codingtips #programming #softwaredevelopment
👍4
Добавьте кастомные переходы страниц с GoRouter
Переходы между страницами важны для пользовательского опыта
Добавьте этот небольшой помощник, чтобы определить кастомный переход страницы:
Теперь оберните свою страницу в переход, используя pageBuilder для вашего маршрута:
Вы также можете настроить стандартный переход страницы прямо в вашей теме:
Оцените нашу новую рубрику! 👍💡
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDev #UIUX #FlutterTips
Переходы между страницами важны для пользовательского опыта
Добавьте этот небольшой помощник, чтобы определить кастомный переход страницы:
Page<dynamic> Function(BuildContext, GoRouterState) buildPageTransition(
Widget child,
) => (BuildContext context, GoRouterState state) {
return CustomTransitionPage(
key: state.pageKey,
child: child,
transitionsBuilder: (context, animation, secondaryAnimation, child) =>
FadeThroughTransition( // можно создать свой собственный переход или использовать из пакета animations на pub.dev
animation: animation,
secondaryAnimation: secondaryAnimation,
child: child,
),
);
};
Теперь оберните свою страницу в переход, используя pageBuilder для вашего маршрута:
GoRoute(
path: '/signin',
builder: (context, state) => const SigninPage(),
pageBuilder: buildPageTransition(const SigninPage()),
),
Вы также можете настроить стандартный переход страницы прямо в вашей теме:
pageTransitionsTheme: PageTransitionsTheme(
builders: {
TargetPlatform.android: const ZoomPageTransitionsBuilder(),
TargetPlatform.iOS: const CupertinoPageTransitionsBuilder(),
},
),
Оцените нашу новую рубрику! 👍💡
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDev #UIUX #FlutterTips
👍5
Принудительный портретный режим
Когда вы в последний раз использовали приложение в ландшафтном режиме? 🤔
Фиксация ориентации экрана в Flutter
Чтобы заставить приложение работать только в портретном режиме, добавьте следующий код в функцию main() перед запуском приложения:
Теперь приложение не сможет перейти в ландшафтный режим 📱💻
Результат:
Приложение останется в портретном режиме 👍
Оцените нашу новую рубрику FlutterPulseTips! 👍 Ваши отзывы помогут нам улучшать контент. 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDev #ProgrammingTips #UIUX #DevTips
Когда вы в последний раз использовали приложение в ландшафтном режиме? 🤔
Фиксация ориентации экрана в Flutter
Чтобы заставить приложение работать только в портретном режиме, добавьте следующий код в функцию main() перед запуском приложения:
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp, // Портретная ориентация вверх
DeviceOrientation.portraitDown, // Портретная ориентация вниз
]);
Теперь приложение не сможет перейти в ландшафтный режим 📱💻
Результат:
Приложение останется в портретном режиме 👍
Оцените нашу новую рубрику FlutterPulseTips! 👍 Ваши отзывы помогут нам улучшать контент. 💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #MobileDev #AppDev #ProgrammingTips #UIUX #DevTips
👍3
Загрузка байтов изображения и отображение на холсте
Не так сложно сделать с помощью Flutter 😉
Вы когда-нибудь задумывались, как можно загрузить изображение и отобразить его на холсте в Flutter? 🤔 Давайте разберемся в этом вместе! 💡
Шаг 1: Загрузка изображения
Сначала нам нужно загрузить изображение из наших ресурсов. Для этого мы используем метод
Шаг 2: Отображение на холсте
Теперь, когда у нас есть изображение в формате
Вот и все! Теперь вы знаете, как загрузить байты изображения и отобразить их на холсте во Flutter. Просто и эффективно, не правда ли? 😊
Оцените нашу новую рубрику и оставьте свои комментарии! 👇
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledev #appdev #codingtips #FlutterTips
Не так сложно сделать с помощью Flutter 😉
Вы когда-нибудь задумывались, как можно загрузить изображение и отобразить его на холсте в Flutter? 🤔 Давайте разберемся в этом вместе! 💡
Шаг 1: Загрузка изображения
Сначала нам нужно загрузить изображение из наших ресурсов. Для этого мы используем метод
load
класса rootBundle
:
import 'dart:ui' as ui;
import 'package:flutter/services.dart';
// Загружаем изображение из ресурсов
final ByteData data = await rootBundle.load(path);
// Преобразуем в Uint8List
final Uint8List bytes = data.buffer.asUint8List();
// Преобразуем в ui.Image
final ui.Image image = await decodeImageFromList(bytes);
Шаг 2: Отображение на холсте
Теперь, когда у нас есть изображение в формате
ui.Image
, мы можем отобразить его на холсте. Для этого создадим собственный класс CustomPainter
:
// Создаем новый CustomPainter
class MyPainter extends CustomPainter {
final ui.Image image;
MyPainter(this.image);
@override
void paint(Canvas canvas, Size size) {
// Рисуем изображение на холсте
canvas.drawImageRect(image, srcRect, dstRect, Paint());
}
}
Вот и все! Теперь вы знаете, как загрузить байты изображения и отобразить их на холсте во Flutter. Просто и эффективно, не правда ли? 😊
Оцените нашу новую рубрику и оставьте свои комментарии! 👇
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledev #appdev #codingtips #FlutterTips
👍3🔥1
Хранение настроек пользователя
Используйте плагин 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
Детали для улучшения формы
Ничто не раздражает так сильно, как невозможность закрыть клавиатуру. Пользователь нажимает в любом месте... и клавиатура остаётся. Вместо этого вы можете просто сделать так:
Решение: Оберните всю страницу в 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
👍4
Supabase: Привязка анонимного пользователя к аутентифицированному
Анонимный пользователь - это действительно здорово. Вы автоматически создаете нового пользователя в своей базе данных каждый раз, когда кто-то впервые запускает ваше приложение.
Затем вы можете позволить ему подписаться, начать работать с вашим приложением, не беспокоя его просьбой ввести email...
А затем, когда он действительно вовлечется в процесс, вы можете привязать его учетную запись.
Оцените новую рубрику и напишите свое мнение! 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #Supabase #MobileDev #AppDev #CodingTips #DevTips
Анонимный пользователь - это действительно здорово. Вы автоматически создаете нового пользователя в своей базе данных каждый раз, когда кто-то впервые запускает ваше приложение.
Затем вы можете позволить ему подписаться, начать работать с вашим приложением, не беспокоя его просьбой ввести email...
А затем, когда он действительно вовлечется в процесс, вы можете привязать его учетную запись.
@override
Future<Credentials> signup(String email, String password) async {
if (client.auth.currentUser?.isAnonymous == true) {
// Обновляем анонимного пользователя с помощью email и password
final res = await client.auth.updateUser(UserAttributes(email: email, password: password));
if (res.user != null) {
return Credentials(id: res.user!.id);
} else {
throw 'Ошибка при обновлении пользователя';
}
}
return client.auth
.signUp(email: email, password: password)
.then(
(value) => Credentials(id: value.user!.id),
onError: (error) {
Logger().e("Ошибка при регистрации: $error");
throw SignupException();
},
);
}
Оцените новую рубрику и напишите свое мнение! 👍💬
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #Supabase #MobileDev #AppDev #CodingTips #DevTips
👍1
Flutter-дайджест сентября 🌐
Сентябрь выдался ярким месяцем для Flutter-разработчиков: статьи на Хабре, новые пакеты и мощные обновления, разборы на YouTube и полезные советы для прокачки проектов 🚀
В дайджесте вы найдёте:
🎓 статьи с Хабра (RenderObject, CI/CD, хитрости релиза в сторы);
🎥 лучшие видео (FFI + Rust, Talker, сборка бинарников);
📦 топовые пакеты месяца (flutter_slidable, go_router, drift, flutter_map, Firebase и др.);
🆕 новые пакеты недели (bodychart_heatmap, fquery, isar_plus, loader_pro, cupertino_native);
💡 #FlutterPulseTips (кастомные переходы страниц, точный таймер, лайфхаки с формами).
Полный обзор читайте 👉 здесь
Давайте вместе вспомним что произошло за прошедший месяц
#Flutter #Dart #FlutterPulse #PubDev #Хабр #MobileDev
Сентябрь выдался ярким месяцем для Flutter-разработчиков: статьи на Хабре, новые пакеты и мощные обновления, разборы на YouTube и полезные советы для прокачки проектов 🚀
В дайджесте вы найдёте:
🎓 статьи с Хабра (RenderObject, CI/CD, хитрости релиза в сторы);
🎥 лучшие видео (FFI + Rust, Talker, сборка бинарников);
📦 топовые пакеты месяца (flutter_slidable, go_router, drift, flutter_map, Firebase и др.);
🆕 новые пакеты недели (bodychart_heatmap, fquery, isar_plus, loader_pro, cupertino_native);
💡 #FlutterPulseTips (кастомные переходы страниц, точный таймер, лайфхаки с формами).
Полный обзор читайте 👉 здесь
Давайте вместе вспомним что произошло за прошедший месяц
#Flutter #Dart #FlutterPulse #PubDev #Хабр #MobileDev
Что такое Render Objects?
Render Objects являются основой визуальной системы Flutter. Они используются для отрисовки элементов интерфейса на экране.
Flutter строит пользовательские интерфейсы в три слоя:
1. Widget: конфигурация визуального элемента
2. Element: соединяет виджеты и объекты рендеринга
3. RenderObject: рисует на вашем экране
Настройка RenderObject
Поскольку мы будем рендерить одного потомка, мы расширяем
Render Objects рисуют как
- Могут иметь потомков и реагировать на ограничения макета
- Управляют как макетом, так и отрисовкой
- Обрабатывают ограничения макета
- Управляют своим собственным размером
Зачем использовать RenderObject?
Большую часть времени вам не придётся писать RenderObjects самостоятельно. Используйте виджеты!
Но пользовательские RenderObjects дают неограниченную творческую свободу для нестандартных виджетов.
Оцените новую рубрику лайком! 👍
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledev #renderobjects #flutterrenderobjects #flutterui #flutterdevelopment #codingtips
Render Objects являются основой визуальной системы Flutter. Они используются для отрисовки элементов интерфейса на экране.
Flutter строит пользовательские интерфейсы в три слоя:
1. Widget: конфигурация визуального элемента
2. Element: соединяет виджеты и объекты рендеринга
3. RenderObject: рисует на вашем экране
Настройка RenderObject
Поскольку мы будем рендерить одного потомка, мы расширяем
SingleChildRenderObjectWidget
.Render Objects рисуют как
CustomPainter
, но с гораздо большими возможностями:- Могут иметь потомков и реагировать на ограничения макета
- Управляют как макетом, так и отрисовкой
- Обрабатывают ограничения макета
- Управляют своим собственным размером
Зачем использовать RenderObject?
Большую часть времени вам не придётся писать RenderObjects самостоятельно. Используйте виджеты!
Но пользовательские RenderObjects дают неограниченную творческую свободу для нестандартных виджетов.
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: const Center(
child: CustomStar(
size: 200,
color: Colors.amber,
),
),
);
}
}
class CustomStar extends SingleChildRenderObjectWidget {
final double size;
final Color color;
const CustomStar({
super.key,
required this.size,
required this.color,
});
@override
RenderObject createRenderObject(BuildContext context) {
return RenderCustomStar(size: size, color: color);
}
@override
void updateRenderObject(BuildContext context, RenderCustomStar renderObject) {
renderObject.starSize = size;
renderObject.color = color;
}
}
class RenderCustomStar extends RenderBox {
RenderCustomStar({
required double size,
required Color color,
}) : starSize = size,
color = color;
double starSize;
Color color;
@override
void performLayout() {
size = constraints.biggest;
}
@override
void paint(PaintingContext context, Offset offset) {
final canvas = context.canvas;
canvas.save();
canvas.translate(offset.dx, offset.dy);
// ... рисуйте то, что вам нужно здесь
}
}
Оцените новую рубрику лайком! 👍
Все подобные новости можно найти по хэштегу #FlutterPulseTips
#flutter #dart #flutterpulse #FlutterPulseTips #mobiledev #renderobjects #flutterrenderobjects #flutterui #flutterdevelopment #codingtips
👍2❤1