Открытый исходный код этого виджета Jetpack Compose

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

После этой статьи я начал задаваться вопросом, как бы это было, если бы я написал ее в Compose. Излишне говорить, что Compose — один из самых модных инструментов для создания декларативного пользовательского интерфейса, когда я пишу. Это позволяет вам легко программно создавать компоненты пользовательского интерфейса и упорядочивать их на экране. Это означает, что нам больше не нужен XML для объявления структуры пользовательского интерфейса.

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

Короткий ответ: абсолютно! Позвольте мне поделиться с вами своим путешествием, которое в конечном итоге привело к публикации этого виджета Compose в библиотеке с открытым исходным кодом.

Рисование пользовательских фигур в Canvas с помощью Compose

Логика рисования на Canvas не изменилась с Compose. Compose предоставляет свой виджет Canvas, чтобы вы могли рисовать внутри компонуемой функции. Он использует одни и те же методы независимо от того, хотите ли вы нарисовать линию, прямоугольник, дугу или путь.

Canvas принимает два параметра:

  • Modifier, чтобы определить, как Canvas будет отображаться на экране
  • onDraw лямбда, где происходит вся магия рисования.

Чтобы нарисовать наши сегменты, мы будем:

  1. повторно используйте SegmentCoordinatesComputer, которые я описал в предыдущей статье. Этот класс вычисляет координаты сегмента с заданным диапазоном параметров (расстояние, угол и т. д.).
  2. сохранить состояние компьютера с компонуемым remember.
  3. перебрать аргумент segmentCount и получить координаты каждого сегмента.
  4. нарисовать отрезок по заданным координатам. Вы можете изменить цвет и прозрачность сегмента — SegmentColor представляет класс данных с этими двумя атрибутами.

Я создал функцию расширения для рисования сегмента, так как она понадобится нам для рисования сегмента прогресса.

Наконец, рисование индикатора выполнения приводит к извлечению его координат из SegmentedCoordinatesComputer и вызову метода расширения drawSegment.

Теперь мы перестроили наш сегментированный индикатор выполнения с помощью Compose. Но нам все еще не хватает ключевого аспекта любого индикатора выполнения.

Анимация с Compose

Таким образом, наш виджет не анимирует свое продвижение. Довольно хромой для индикатора выполнения, не так ли?

Но не волнуйтесь. Compose поставляется с несколькими встроенными API. Я был сбит с толку тем, насколько прямолинейны анимации в Compose!

На самом деле, вы можете связать его в одну строку кода! Поскольку наша последовательность состоит из интерполяции двух целых чисел, мы можем использовать компонуемый animateFloatAsState для перекомпоновки нашего виджета с progress в качестве целевого значения. Затем вам нужно передать интерполированное значение animatedProgress компьютеру, а рекомпозиция сделает все остальное.

По умолчанию прогресс будет анимироваться с эффектом spring, но компонуемый animateFloatAsState имеет необязательный аргумент animationSpec, если вы хотите изменить его поведение.

Стоит ли переходить на Compose?

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

Также я уменьшил LOC на 180% 🤩

Наконец, я высоко оценил инструмент предварительного просмотра при создании виджета. Это позволило мне напрямую увидеть, как компонент отображается на экране. Мне удалось разбить мой виджет во многих превью, чтобы убедиться, что он отвечает всем различным сценариям, которые я мог придумать. Когда у вас есть несколько параметров, работающих вместе, таких как расстояние и углы, при изменении количества сегментов, предварительный просмотр очень помогает визуализировать все эти варианты использования.

Использование этого виджета в вашем проекте

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

Репозиторий поставляется с образцом, показывающим все, что вы можете делать с этим виджетом. Я также показал эффект дыхания и анимацию в стиле «Камехамеха», чтобы дать вам представление о том, как вы можете дополнительно настроить свой компонент поверх него.

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