en
Feedback
Flutter. Много

Flutter. Много

Open in Telegram

Заказать мобильную разработку: https://amiga.ru//?utm_source=tg Заказать рекламу в канале @amiga_agency_bot Новости Flutter-разработки, дайджесты мероприятий, личный опыт.

Show more
3 013
Subscribers
-224 hours
-47 days
-1030 days
Attracting Subscribers
July '26
July '26
+31
in 2 channels
June '26
+18
in 1 channels
Get PRO
May '26
+38
in 1 channels
Get PRO
April '26
+506
in 2 channels
Get PRO
March '26
+23
in 2 channels
Get PRO
February '26
+40
in 0 channels
Get PRO
January '26
+31
in 1 channels
Get PRO
December '25
+25
in 1 channels
Get PRO
November '25
+28
in 0 channels
Get PRO
October '25
+29
in 0 channels
Get PRO
September '25
+62
in 1 channels
Get PRO
August '25
+41
in 1 channels
Get PRO
July '25
+30
in 1 channels
Get PRO
June '25
+26
in 0 channels
Get PRO
May '25
+38
in 0 channels
Get PRO
April '25
+39
in 0 channels
Get PRO
March '25
+44
in 1 channels
Get PRO
February '25
+55
in 1 channels
Get PRO
January '25
+55
in 0 channels
Get PRO
December '24
+51
in 1 channels
Get PRO
November '24
+62
in 0 channels
Get PRO
October '24
+75
in 2 channels
Get PRO
September '24
+110
in 0 channels
Get PRO
August '24
+142
in 1 channels
Get PRO
July '24
+116
in 2 channels
Get PRO
June '24
+703
in 4 channels
Get PRO
May '24
+91
in 1 channels
Get PRO
April '24
+183
in 0 channels
Get PRO
March '24
+146
in 0 channels
Get PRO
February '24
+184
in 1 channels
Get PRO
January '24
+248
in 0 channels
Get PRO
December '23
+103
in 0 channels
Get PRO
November '23
+114
in 0 channels
Get PRO
October '23
+151
in 0 channels
Get PRO
September '23
+211
in 0 channels
Get PRO
August '23
+164
in 0 channels
Get PRO
July '23
+84
in 0 channels
Get PRO
June '23
+216
in 0 channels
Get PRO
May '23
+69
in 0 channels
Get PRO
April '23
+152
in 0 channels
Get PRO
March '23
+55
in 0 channels
Get PRO
February '23
+123
in 0 channels
Get PRO
January '23
+75
in 0 channels
Get PRO
December '22
+772
in 0 channels
Date
Subscriber Growth
Mentions
Channels
30 July+1
29 July+1
28 July+2
27 July+2
26 July0
25 July0
24 July+1
23 July+1
22 July+1
21 July+1
20 July+5
19 July+3
18 July0
17 July+2
16 July+4
15 July+4
14 July0
13 July+1
12 July0
11 July0
10 July0
09 July0
08 July0
07 July0
06 July+1
05 July0
04 July0
03 July+1
02 July0
01 July0
Channel Posts
Hola, Amigos! Сегодня посмотрим на один пакет, который может быть полезен в разработке - paged_vertical_calendar. Он выводит
Hola, Amigos! Сегодня посмотрим на один пакет, который может быть полезен в разработке - paged_vertical_calendar. Он выводит календарь непрерывным вертикальным списком вместо одного месяца переключением. Это полезно в таких случаях: ⭕️ Нужно показать сразу несколько месяцев; ⭕️ Есть выбор интервала дат, которые могут быть в разных месяцах; ⭕️ Нужен другой UX, чем стандартный. Давайте разберем его базовое использование:

PagedVerticalCalendar(
  minDate: DateTime.now().subtract(Duration(days 365)),
  maxDate: DateTime.now().add(Duration(days 365)),
  initialDate: DateTime.now().add(Duration(days 3)),
  invisibleMonthsThreshold: 1,
  startWeekWithSunday: true,
  onMonthLoaded: (year, month) {
    // on month widget load 
  },
  onDayPressed: (value) {
    // on day widget pressed   
  },
  onPaginationCompleted: (direction) {
    // on pagination completion
  },
);
Пройдемся по его параметрам: • minDate и maxDate помогают нам сделать календарь не бесконечным; • initialDate - дата начального месяца, который будет показан пользователю посередине списка; • invisibleMonthThreshold - количество месяцев, которые пользователь не видит, но они просчитываются для дальнейшего отображения; • startWeekWithSunday - полезное свойство, если приложение работает в странах, где неделя начинается с воскресенья, а не с понедельника; • onMonthLoaded, onPaginationCompleted - обратные вызовы, которые помогают подгружать данные, если это нужно; • onDayPressed - обработка нажатия на какой-либо день. Так как это все-таки список, то ему доступны еще параметры, которые есть у других похожих виджетов - controller, physics, addAutomaticKeepAlives и reverse. Но самое интересное и важное, что такой календарь можно максимально кастомизировать под себя следующими параметрами: • dayAspectRatio - помогает задать соотношение сторон для виджета дня; • weekdaysToHide - скрывает дни недели, если нужно показать только определенные. Например, только рабочие дни; • listPadding - позволяет задать отступы у списка; • monthBuilder - позволяет кастомизировать шапку месяца под себя; • dayBuilder - позволяет кастомизировать отображение дня на календаре. Рассказывайте, решали ли уже подобные задачи и пользовались ли этим пакетом в своих проектах?

2
Hola, Amigos! Сегодня мы вводим новую рубрику - обзоры правил для статического анализатора #lintRules. В ней мы будем рассказ+8
Hola, Amigos! Сегодня мы вводим новую рубрику - обзоры правил для статического анализатора #lintRules. В ней мы будем рассказывать о тех правилах, которыми пользуемся сами на наших проектах. Поэтому ловите первую подборку. А также рассказывайте в комментариях, про какие правила рассказать в следующий раз?
712
3
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. В прошлых частях мы разобрали базовую кастомизацию виджетов
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. В прошлых частях мы разобрали базовую кастомизацию виджетов Slider и RangeSlider, а также замену индикатора на собственный. Сегодня мы займемся изменением полосы значений (Track) под наш дизайн. Для этого нам так же, как и с индикатором, нужно создать отдельный класс, наследуемый от SliderTrackShape для Slider и RangeSliderTrackShape для RangeSlider. Данные классы отличаются от тех, которые мы применяли в прошлой части, так как вместо метода на получение размера, тут есть метод на получение объекта Rect. Для примера выберем самое простое - задать только размеры: @override Rect getPreferredRect({ required RenderBox parentBox, Offset offset = Offset.zero, required SliderThemeData sliderTheme, bool isEnabled, bool isDiscrete }) { return Rect.fromTLWH(0, 0, parentBox.constraints.width, 8.0); } После чего переопределяем метод для отрисовки. В нашем примере полоса всегда будет одинаковой, поэтому мы рисуем только один RRect: @override void void paint( PaintingContext context, Offset offset, { required RenderBox parentBox, required SliderThemeData sliderTheme, required Animation<double> enableAnimation, required Offset thumbCenter, Offset? secondaryOffset, bool? isEnabled, bool? isDiscrete, required TextDirection textDirection }) { final trackRect = Rect.fromTLWH(0, 0, parentBox.constraints.width, 8.0); final trackRRect = RRect.fromRectAndRadius(trackRect, Radius.circular(4); final redPaint = Paint() ..color = Colors.red ..strokeWidth = 2.0 ..style = PaintingStyle.stroke; final whitePaint = Paint() ..color = Colors.white ..style = PaintingStyle.fill; canvas ..drawRRect(trackRRect, whitePaint) ..drawRRect(trackRRect, redPaint); } Если вы хотите показывать часть полосы до индикатора одним стилем, а после - другим, то на помощь придет свойство thumbCenter. Оно означает координаты центра индикатора: final trackRectBefore = Rect.fromPoints( Offset.zero, Offset(thumbCenter.dx, 8.0), ); final trackRectAfter = Rect.fromPoints( Offset(thumbCenter.dx, 0), Offset(parentBox.constraints.width, 8.0), ); Для RangeSliderTrackShape будут доступны два таких свойства - startThumbCenter и endThumbCenter. С их помощью можно разделить трек на три зоны: неактивную область до начального индикатора, активную область между индикаторами и неактивную область после конечного индикатора. Для того, чтобы применить наш стиль нужно добавить классы к теме: SliderThemeData( …, trackShape: AppSliderTrackShape(), rangeTrackShape: AppRangeSliderTrackShape(), ) Небольшая рекомендация от нас - если применяете собственную отрисовку трека, то лучше всего Slider будет оборачивать в SizedBox для лучшего позиционирования на экране. Рассказывайте в комментариях, кастомизацию каких виджетов хотели бы увидеть? 🙂
795
4
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. В прошлой части мы рассмотрели базовую кастомизацию виджетов
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. В прошлой части мы рассмотрели базовую кастомизацию виджетов Slider и RangeSlider. Сегодня мы углубимся в детали и изменим внешний вид индикатора у слайдера. Для этого нам нужно будет создать отдельный класс, который наследуется от SliderComponentShape для Slider или RangeSliderThumbShape для RangeSlider: class AppThumbShape extends SliderComponentShape class AppRangeThumbShape extends RangeSliderThumbShape Сначала, нам нужно задать размер нашего индикатора. В нашем примере он круглый, поэтому идем от радиуса большего круга. @override Size getPrefferedSize(bool isEnabled, bool isDiscrete) => Size.fromRadius(8); Далее наступает момент отрисовать на канвасе. Делается это точно также как и при использовании CustomPaint, только свойства у методов немного другие. Давайте на них посмотрим. Для SliderComponentShape это: • PaintingContext, который нам и выдает канвас для отрисовки; • Offset center - координаты центра канваса; • activationAnimation и enableAnimation - анимации начала взаимодействия и включения / выключения слайдера; • sliderTheme - тема для получения цветов и всего необходимого, что мы уже настроили ранее; Остальные параметры могут быть не настолько полезны, кроме тех, что используются при отрисовке текста. Например, выбранного значения. Для RangeSliderThumbShape добавляются: • bool isOnTop - показывает, находится ли этот индикатор над другим; • Thumb thumb - какой это именно индикатор - в начале или в конце интервала. Давайте нарисуем наш индикатор для обычного Slider: @override void paint( PaintingContext context, Offset center, { required Animation<double> activationAnimation, required Animation<double> enableAnimation, required bool isDiscrete, required TextPainter labelPainter, required RenderBox parentBox, required SliderThemeData sliderTheme, required TextDirection textDirection, required double value, required double textScaleFactor, required Size sizeWithOverflow, ) { final canvas = context.canvas; final redPaint = Paint() ..color = Colors.red ..style = PaintingStyle.fill; final whitePaint = Paint() ..color = Colors.white ..style = PaintingStyle.fill; canvas ..drawCircle(center, 8, redPaint) ..drawCircle(center, 6, whitePaint) ..drawCircle(center, 3, redPaint); } Теперь нужно добавить наш готовый индикатор в тему: SliderThemeData( …, thumbShape: AppThumbShape(), rangeThumbShape: AppRangeThumbShape(), ) В следующей части мы рассмотрим, как кастомизировать полосу со значениями. Пишите в комментариях, если уже пробовали кастомизировать слайдеры своими руками! 👇
853
5
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. В этой небольшой серии мы разберем, как кастомизировать видж
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. В этой небольшой серии мы разберем, как кастомизировать виджеты Slider и RangeSlider, чтобы они лучше соответствовали вашему дизайну. Делается это как и внутри самого виджета, так и через тему. Начнём с простого кейса: внешний вид слайдера нас устраивает, но нужно изменить только цветовую схему. Slider( … // Основные настройки слайдера activeColor: Colors.red, inactiveColor: Colors.blue, overlayColor: WidgetStatePropertyAll(Colors.green), ); Эти три параметра позволяют быстро адаптировать внешний вид Slider: activeColor отвечает за цвет активной части полосы — от начального значения до текущей позиции, а также за цвет индикатора выбранного значения; inactiveColor задаёт цвет неактивной части полосы; overlayColor позволяет перекрасить цвет выделения, которое показывается при перемещении индикатора. Те же настройки доступны и для RangeSlider. Если нужно применять стили сразу ко всем слайдерам в приложении, удобнее вынести их в тему: SliderThemeData( activeTrackColor: Colors.red, thumbColor: Colors.red, inactiveTrackColor: Colors.blue, overlayColor: Colors.green, ) Как мы видим, свойство activeColor - разделилось на два: activeTrackColor отвечает за полосу, а thumbColor за индикатор выбранного значения. Кроме этого, тема позволяет кастомизировать и цвета для отключенных виджетов при помощи таких же свойств, только с префиксом disabled. В следующей части поговорим о более глубокой кастомизации — разберём, как создать собственный индикатор выбранного значения для Slider и RangeSlider. А пока делитесь в комментариях: приходилось ли вам менять стандартный вид этих виджетов? Какие настройки использовали?
906
6
Hola, Amigos! Продолжаем рассказывать про полезные виджеты. Сегодня на очереди SliverMainAxisGroup, который позволит нам увел
Hola, Amigos! Продолжаем рассказывать про полезные виджеты. Сегодня на очереди SliverMainAxisGroup, который позволит нам увеличить читаемость кода. Во время разработки экрана со сложной версткой и использовании на нем CustomScrollView, может случиться ситуация, когда количество используемых сливеров становится слишком большим. Из-за этого кода становится настолько много, что его читаемость сильно падает. И тут встает вопрос о выносе некоторых сливеров в отдельный виджет. Ранее для этого писали собственные решения или использовали виджет MultiSliver из библиотеки sliver_tools. Но время идет, фреймворк обновляется, а старые решения работают все хуже. Например, sliver_tools уже пару лет не обновляется и ее использование может отражаться на производительности приложений. Сейчас для выноса нескольких сливеров в отдельный виджет есть SliverMainAxisGroup, который работает из коробки. Давайте на него посмотрим: SliverMainAxisGroup( slivers: [...] ); Делитесь в комментариях, используете ли данный виджет на своих проектах или все еще делаете по старинке?
1 087
7
Hola, Amigos! Сегодня мы хотим рассказать про один из редко используемых, но очень полезных виджетов - OverflowBar. Представь
Hola, Amigos! Сегодня мы хотим рассказать про один из редко используемых, но очень полезных виджетов - OverflowBar. Представьте, что вы делаете сложную верстку, где несколько кнопок с текстом должны быть расставлены горизонтально и занимать максимально доступную ширину. Если текста больше, чем нужно, а это может быть при увеличенном шрифте, то одну кнопку мы переносим на следующую строку. Сначала кажется верным использовать Row или Wrap. Но тут мы встречаемся с проблемой - при использовании первого, мы не можем перенести дочерние виджеты, а со вторым не можем растянуть их. Третий вариант - использовать LayoutBuilder и вычислять размеры самим, но это сложно. Вот тут то нам и приходит на помощь виджет OverflowBar. И вместо Row( mainAxisAlignment: MainAxisAlignment.end, spacing: 8, children: [ TextButton(onPressed: () {}, child: Text("Cancel")), TextButton(onPressed: () {}, child: Text("Save")), ElevatedButton(onPressed: () {}, child: Text("Delete")), ], ) Мы можем сделать так: OverflowBar( alignment: MainAxisAlignment.end, spacing: 8, overflowSpacing: 8, children: [ TextButton(onPressed: () {}, child: Text("Cancel")), TextButton(onPressed: () {}, child: Text("Save")), ElevatedButton(onPressed: () {}, child: Text("Delete")), ], ) Как мы видим, этот виджет больше похож на Wrap, но он работает как смесь Wrap и Row. Делитесь в комментариях, использовали ли данный виджет на своих проектах?
1 087
8
Hola, Amigos! Продолжаем разговаривать про настройку наших IDE. В этот раз разберемся, как мы можем работать с импортами в на
Hola, Amigos! Продолжаем разговаривать про настройку наших IDE. В этот раз разберемся, как мы можем работать с импортами в наших .dart файлах и как их настроить, чтобы они сортировались и удалялись, если не используются, автоматически. Для Android Studio перейдем в настройки IDE (Settings на Windows и Linux, Preferences на macOS), там в “Languages & Frameworks” и выберем Flutter. У нас откроется окно настроек плагина, где у нас уже включен чекбокс “Format code on save”. Под ним есть еще один - “Organize imports on save”, именно он нам и нужен - включаем его. Для VS Code все немного проще. В settings.json нужно всего лишь включить: “editor.codeActionsOnSave”: { “source.organizeImports”: true } Теперь при сохранении файла, наши импорты будут упорядочены, но желательно еще настроить правила линтера для этого в нашем analysis_options.yaml: linter: rules: - directives_ordering или linter: rules: directives_ordering: true Таким образом, наши импорты будут выстраиваться так: • Импорты из Dart • Импорты из библиотек, самого фреймворка или статические импорты из проекта • Локальные импорты по проекту, без использования package: Например: import ‘dart:async’; import ‘package:flutter/material.dart’; import ‘package:flutter_bloc/flutter_bloc.dart’; import ‘package:my_app/common/widgets.dart’; import ‘widgets/app_bar.dart’; import ‘../../navigation.dart’; Делитесь в комментариях, включена ли у вас эта настройка и как вы организуете импорты на ваших проектах?
1 115
9
💸 Дешёвый старт, дорогой финал: как выбор технологии мстит команде спустя год Планируете мобильное приложение и пока не опре
💸 Дешёвый старт, дорогой финал: как выбор технологии мстит команде спустя год Планируете мобильное приложение и пока не определились со стеком? Прежде чем выбирать по цене и тому, с чем проще запускаться – стоит понимать, во что это выльется через год. На старте всё выглядит логично: минимальный бюджет, быстрый MVP, разработчиков найти проще. Но экономия на технологии часто оборачивается совсем другими цифрами, когда продукт начинает расти. В статье разбираем, как решения, которые кажутся выгодными на первом этапе, влияют на скорость обновлений, производительность, стоимость команды через год-два – и как понять цену выбора до того, как проект будет написан. 🔗 https://amiga.ru/blog/flutter-vs-react-native-vs-kmp-vybor-steka-2026
838
10
Hola Amigos! Собрали в одну подборку все полезные посты июня, которые вы могли пропустить. Выбирайте, что интересно, и перехо
Hola Amigos! Собрали в одну подборку все полезные посты июня, которые вы могли пропустить. Выбирайте, что интересно, и переходите по ссылкам для полезного выходного чтива: 🟡Snippet для анимированного виджета 🟡Форматируем код при сохранении 🟡Кастомные иконки для iOS 🟡Оптимизируем Assets. Часть 1. Часть 2. Часть 3. 🔴Динамические иконки приложения на Flutter Всем хорошего кода!
970
11
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead агентства продуктовой разработки Amiga. Сегодня мы снова поговорим пр
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead агентства продуктовой разработки Amiga. Сегодня мы снова поговорим про иконки приложения, но в этот раз про динамические, которые вы можете менять по воздуху или дать возможность пользователю выбрать самому. Про это мы нашли и перевели для вас подробную инструкцию. Что вы сможете узнать из нее: • Как добавить сразу несколько вариантов иконок в ваше приложение для iOS и Android; • Как одновременно предоставить выбор пользователю для изменения настроек приложения и иногда самим их перезаписывать по воздуху; 🔗 Ссылка на переведенную статью Делитесь в комментариях, пробовали ли вы менять иконку приложения таким способом?
1 226
12
Hola, Amigos! Завершаем цикл постов про оптимизацию ассетов. Сегодня посмотрим на фишку, которая появилась в Flutter 3.41 - п
Hola, Amigos! Завершаем цикл постов про оптимизацию ассетов. Сегодня посмотрим на фишку, которая появилась в Flutter 3.41 - платформенные ассеты. Раньше мы писали пути к нашим ассетам в pubspec.yaml так: assets: - assets/images/ - assets/android/icons/ - assets/ios/icons/ - assets/web/icons/ - assets/desktop/icons/ Тут ассеты для всех платформ летят во все сборки, даже в те, где они не нужны. Теперь Flutter позволяет выделить отдельные ассеты как под одну, так и под несколько платформ. Например, какие-то папки нам нужно открыть только для десктопных приложений: assets: - assets/images/ - path: assets/desktop/icons/ platforms: - windows - linux - macos - path: assets/android/icons/ platforms: - android - path: assets/ios/icons/ platforms: - ios - path: assets/web/icons/ platforms: - web Этот новый способ не будет добавлять ассеты для других платформ в сборку, что сделает ее меньше и легче. Рассказывайте в комментариях, знали ли о таком?
1 231
13
Hola, Amigos! В прошлой части мы рассказали, какими лайфхаками пользуемся, чтобы наши ассеты были меньшего размера. Сегодня п
Hola, Amigos! В прошлой части мы рассказали, какими лайфхаками пользуемся, чтобы наши ассеты были меньшего размера. Сегодня поговорим про то, как нам сформировать растровые изображения так, чтобы они хорошо смотрелись на любом устройстве. Во-первых, у каждого устройства есть соотношение размера экрана к его разрешению. Его можно измерить в виде DPI (dot per inch, точки на дюйм), так и в специальном соотношении, где при единице одна точка будет равна одному физическому пикселю. Из Flutter мы его можем получить через MediaQuery.devicePixelRatioOf(context). Во-вторых, важно помнить, что Flutter отрисовывает именно по точкам, а не по пикселям. Поэтому, если у нашего изображения есть предел на экране, то этот предел и будет его максимальным размером. Теперь, когда у нас определены размеры в точках, то нужно подготовить изображения. В прошлом посте мы писали, что максимальный - это размер, умноженный на 4. Но на самом деле мы готовим много одинаковых изображений - под devicePixelRatio со значениями 1x, 1.5x, 2x, 3x и 4x. Конечно, вы можете сделать и больше, но практика показывает, что этих размеров более, чем достаточно. Далее важно их правильно хранить. Для этого в папке для ассетов нужно создать еще несколько - для всех соотношений, кроме самого маленького. Называем их мы таким образом: x{N} - где N - это 1.5, 2.0 и т. п. Наша структура будет выглядеть так: assets/ —| images/ ——| x1.5/ ———| image.webp ——| x2.0/ ———| image.webp ——| x3.0/ ———| image.webp ——| x4.0/ ———| image.webp —| image.webp В pubspec.yaml мы добавляем только корневую папку и используем только самый маленький файл, так как Flutter уже самостоятельно будет обрабатывать эти значения. В следующей части мы расскажем, как работать с ассетами под определенные платформы. Пишите в комментариях, пользуетесь ли вы таким разделением?
1 000
14
Hola, Amigos! Среднестатистический пользователь любит, когда скачивание приложения занимает мало времени. Для этого нам нужно
Hola, Amigos! Среднестатистический пользователь любит, когда скачивание приложения занимает мало времени. Для этого нам нужно по максимуму уменьшать размер установочного файла. В основном это необходимо для Android, но может быть полезно и под другие платформы. И главное, чтобы это быстро и правильно работало. В первую очередь много места занимают ассеты: картинки, шрифты, иконки. Держите несколько полезных лайфхаков от нас: 1️⃣ Храните растровые изображения в формате WebP. Это современный формат, который создан в недрах Google и он намного эффективнее сжимает файлы, чем более распространенные JPEG и PNG, а также умеет в прозрачность. 2️⃣ Следите за максимальным размером изображений. Если вам нужно отобразить картинку в формате 100 на 100, а вы добавляете в ассеты картинку размером 2000 на 2000, то это излишне даже для очень больших экранов. Поэтому, максимальный размер мы высчитываем так - размер виджета, умноженный на 4. 3️⃣ Храните иконки в шрифте. Для хранения этого типа ассетов существует три варианта: • Хранить иконки в формате SVG. Да, это векторный формат, но он не до конца подходит к Flutter. Мало того, что для него необходима отдельная библиотека, так еще ее использование съедает ресурсы. • Перевод иконок в специальный векторный формат. Это лучше, но не лишает всех минусов, так как такие иконки все равно отдельные и тоже влияют на отрисовку, хоть и меньше. • Специализированный шрифт. Это нативный вариант, так как вы получаете IconData, а при сборке будут откидываться неиспользуемые иконки. Но есть минусы - не всегда получается сложные иконки перегнать в этот формат и он подходит только для монохромных иконок. Поэтому мы на своих проектах стараемся использовать второй и третий вариант, хотя большее предпочтение отдаем как раз шрифту. В следующей части мы расскажем, как подогнать растровые изображения под разрешение экрана устройства. А пока делитесь в комментариях, какие еще лайфхаки используете для ассетов?
983
15
Hola, Amigos! Мы уже рассказывали про то, как сделать динамические иконки приложения на iOS, но с того времени появился Liqui+5
Hola, Amigos! Мы уже рассказывали про то, как сделать динамические иконки приложения на iOS, но с того времени появился Liquid Glass, а вместе с ним вышел дополнительный инструмент - Icon Composer. Он умеет: • Делить иконки на слои, чтобы правильно организовывать все эффекты • Показывать сетку, чтобы расположить элементы на нужное место. Сама сетка может быть как темной, так и светлой • Показывать иконку в светлой и темной темах, а также в монохроме, и где все Liquid Glass слои становятся прозрачными. Фон, на котором смотреть, тоже можно менять - есть серый и цветной • Менять направление света так, как будто пользователь поворачивает телефон • Экспортировать все иконки как PNG В итоге работы мы получим файл с расширением .icon. Теперь его можно добавить в Xcode, где нужно выбрать название нашей иконки. Очень важно - оставить иконки для более старых версий iOS, так как такой формат поддерживается только от iOS 26. Рассказывайте в комментариях, пользовались ли уже этим инструментом?
1 065
16
Hola, Amigos! Все мы используем IDE для разработки и это облегчает нам написание кода. Но IDE не умеет автоматически применят
Hola, Amigos! Все мы используем IDE для разработки и это облегчает нам написание кода. Но IDE не умеет автоматически применять форматирование написанного. Давайте вместе разберемся как это делать при сохранении файла. Для Android Studio перейдем в настройки IDE (Settings на Windows и Linux, Preferences на macOS), там в “Languages & Frameworks” и выберем Flutter. У нас откроется окно настроек плагина, где нужно включить чекбокс “Format code on save”. Для VS Code все немного проще. В файл с настройками нужно всего лишь включить строку: editor.formatOnSave = true Делитесь в комментариях, помогает ли автоматическое форматирование кода на вашем проекте? Или вы делаете это вручную?
1 247
17
Hola, Amigos! Продолжаем рассказывать про полезные сниппеты. Сегодня создадим сниппет с настройкой для анимации через Animate
Hola, Amigos! Продолжаем рассказывать про полезные сниппеты. Сегодня создадим сниппет с настройкой для анимации через Animated Controller - animStful. class $NAME$ extends StatefulWidget { const $NAME$(super.key); @override State<$NAME$> createState() => _$NAME$State(); } class _$NAME$State extends State<$NAME$> with SingleTickerProviderMixin { late final AnimationController _controller; late final Animation<double> _animation; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: Duration(milliseconds: $DURATION$), ); _controller.addListener(() => setState(() {})); _animation = Tween<double>(begin: 0, end: 1).animate(_controller); } @override Widget build(BuildContext context) { return Container(); } @override void dispose() { _controller.dispose(); super.dispose(); } } Можно копировать в свой IDE и пользоваться! #snippets@flutter_amiga
1 109
18
Hola, Amigos! Собрали в одну подборку все посты мая, которые вы могли пропустить. Выбирайте, что интересно, и переходите по с
Hola, Amigos! Собрали в одну подборку все посты мая, которые вы могли пропустить. Выбирайте, что интересно, и переходите по ссылкам для полезного выходного чтива: 🟡 Прокачиваем локальный поиск на Dart и Flutter 🟡 Полезные сниппеты для жизненного цикла виджета 🟡 Полезные extensions для DateTime 🟡 Как понять, нужна ли библиотека и как ее выбрать? 🟡 Обзор плагина Flutter Intl для IDE 🟡 Краткий обзор Dart 3.12 и Flutter 3.44 🟡 Оптимизируем кастомные анимации Всем хорошего кода! P.S. Завтра ждем вас на квартирнике “Мифическая кроссплатформа” на CodeFest в Новосибирске!
1 143
19
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. Сегодня разберем два виджета, которые помогают оптимизироват
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. Сегодня разберем два виджета, которые помогают оптимизировать производительность анимаций - AnimationBuilder и TickerMode. Начнем с AnimationBuilder. Он перерисовывает только изменяющиеся части, не затрагивая остальное. Не требует addListener у AnimationController. Идеален для анимации фона без перерисовки всего виджета.. AnimatedBuilder( animation: _controller, child: Container( width: 200.0, height: 200.0, color: Colors.green, child: const Center(child: Text('Whee!')), ), builder: (BuildContext context, Widget? child) { return Transform.rotate( angle: _controller.value * 2.0 * math.pi, child: child, ); }, ), TickerMode позволяет управлять активностью анимаций у дочерних виджетов. Он полезен для остановки анимаций, когда пользователь переходит на другой экран, сворачивает приложение или выключает экран устройства. Это все можно реализовать вместе с использованием AppLifecycleState, про который мы рассказывали ранее. Работает это просто. Где-то сверху оборачиваем наш экран в TickerMode и передаем ему переменную в свойство enabled. Но работать будет, только если контроллеры анимаций завязаны на TickerProviderStateMixin и SingleTickerProviderStateMixin. TickerMode( enabled: _enabled, child: ... ); Делитесь в комментариях, используете ли данные виджеты у себя на проектах?
1 062
20
Hola, Amigos! В рамках Google I/O 2026 были представлены Dart 3.12 и Flutter 3.44. Давайте вместе разберемся, что в них новог
Hola, Amigos! В рамках Google I/O 2026 были представлены Dart 3.12 и Flutter 3.44. Давайте вместе разберемся, что в них нового. Начнем, конечно же, с Dart. Тут добавился новый функционал - приватные именованные параметры. Теперь мы можем добавлять наши приватные переменные в конструктор. Как это было в старых версиях: class MyClass { final String _myVar; const MyClass({required String myVar}) : _myVar = myVar; } Как это выглядит теперь: class MyClass { final String _myVar; const MyClass({required this.myVar}); } А при использовании ничего не поменялось: final a = MyClass(myVar: ‘my value’); Еще из того, что добавилось: 🟡В экспериментальной фазе находятся обновленные конструкторы для классов; 🟡Добавилась нативная поддержка Git LFS; 🟡Запустили превью Genkit Dart. Flutter 3.44 приносит нам 2 больших и важных изменения, для которых нужно будет проводить миграции, если этого еще не сделано: 🔴Повышение версии Android Gradle Plugin до версии 9.0 и переход на использование Kotlin. Пока временно есть обратная совместимость. 🔴Переезд на Swift Package Manager, который очень ждали. Еще изменения в фреймворке: 🟡Переработана система обнаружения Widget Preview, что уменьшило потребление памяти; 🟡Добавлена поддержка Apple Silicon для macOS приложений без необходимости использования Rosetta; 🟡Для Android добавлен Hybrid Composition++ для отрисовки нативных виджетов, который производительнее обычного Hybrid Composition; 🟡Много других, более мелких изменений. Делитесь в комментариях, как вам обновление и смотрели ли Google I/O 2026?
1 119