Превращаем дизайн-макет в реальность

Дизайнеры получают все самое интересное.

Они работают с идеальным случаем, платоническим телом всех макетов. Затем щелкают export as.... Никаких краев, которые мешали бы безупречному набору. Никаких недостающих API для достижения компромиссов. Нет длинного хвоста поддержки для устранения недоработок или обновлений. Просто идеальная гармония пользовательского интерфейса.

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

Это не значит, что веселье окончено. Воплощение красивого дизайна в реальность - это процесс, который я обожаю, и для такого разработчика, как я, есть дополнительное измерение красоты, которое можно встроить в настоящий цифровой артефакт: чистый, управляемый API. С внешней стороны API должен быть минимальным выражением требований и экономии движущихся частей. Изнутри разделение задач.

Построение как чистого API, так и красивого дизайна требует признания реальной сложности.

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

Отлично!

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

Чтобы было ясно, цель этого конкретного примера - создать настраиваемый компонент для полосы прокрутки с правой стороны. Он должен быть прикреплен к любому прокручиваемому контенту. Он может взаимодействовать со списком контактов, но должен быть готов поддерживать секционированный контент, как определено разработчиком, использующим его. Это означает, что он не будет жестко закодирован с помощью A-Z и не будет пытаться отсортировать соответствующую коллекцию.

Когда начать?

1. Наблюдайте.

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

Кроме того, в проектах часто используются неявные предположения. Искорените их.

  • Какая информация, по замыслу проекта, легко доступна? Представляет ли он данные, которых у вас нет?
  • Основан ли дизайн на несуществующих API или событиях?
  • Сможете ли вы получить недостающую информацию самостоятельно, или ваши потребители API будут вынуждены унаследовать дополнительную сложность?
  • Предполагает ли дизайн, что данные вполне реальны? Как бы выглядела реализация, если бы данные были некрасивыми?

Отвечая на эти вопросы, помните о своем идеальном внешнем API. Двигаясь в обратном направлении, вы можете обнаружить, какая минимальная дополнительная сложность позволит вашему компоненту функционировать.

Возвращаясь к примеру с полосой прокрутки, моим идеальным внешним API был бы единственный метод:

public void attach(Scrollable s);

Где Scrollable - это любой контейнер для прокрутки, например RecyclerView или ScrollView.

Возможный?

Обратите внимание на следующее о макете:

  • Анимация прямолинейная

У нас достаточно информации в потоке событий касания Android, чтобы анимировать эти буквы с боковым смещением. Окончательная реализация будет включать только два из примитивных типов анимации (перевод, масштаб, поворот и альфа). Подробнее об этом ниже.

  • Макет предполагает точную информацию о проценте прокрутки.

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

Можно приблизительно определить расстояние прокрутки с помощью smoothScrollTo, но это основано на положении элемента, а не на его высоте. Более детальная прокрутка, безусловно, возможна, но она возлагает ответственность на потребителя и усложняет API.

  • Данные фиктивных контактов слишком чистые.

Как отмечалось выше, список плавно прокручивается, чтобы соответствовать проценту на настраиваемой полосе прокрутки. Даже если нам будет дан абсолютный процент прокрутки от RecyclerView (опять же, это сложно сделать), он не будет отображать 1:1 на равномерно расположенные буквы на полосе прокрутки.

Это еще больше подталкивает наш API к прокрутке на основе позиции элемента вместо детализированного процента.

  • На данный момент можно приблизительно определить пологий наклон буквенных смещений.

Говоря практически, стратегия анимации букв будет использовать «бамперный круг» справа от вертикального выравнивания текста.

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

Круг и линия не будут нарисованы, но будут использоваться для расчета мгновенного горизонтального смещения каждой буквы, когда пользователь проводит вверх и вниз по полосе прокрутки. Также можно использовать ValueAnimator для изменения положения круга center.x с течением времени, обеспечивая плавный переход букв между покоящимися и выступающими.

В конструкции вместо полукруга наклонная кривая. возможно воспроизвести наклон в коде, но пока круг - хорошее приближение с более простой математикой.

Я нарисовал несколько строк отладки на пустом холсте, чтобы продемонстрировать эффект:

Вычислив вертикальный путь и выступающий полукруг, легко нарисовать текст прямо на холсте с горизонтальным смещением, соответствующим положению контура x.

2. Работайте в обратном направлении от вашего идеального API.

С некоторыми дополнениями к идеальному API можно решить описанные выше сложности, не возлагая слишком большую ответственность на потребителя API.

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

  • Количество секций.
  • Название каждого раздела (может быть буквой алфавита или нет)
  • Относительный размер каждого раздела.

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

По возможности используйте установленные шаблоны. В этом случае интерфейс в стиле Adapter имеет некоторый смысл, потому что ближайшие элементы пользовательского интерфейса, такие как ListView и RecyclerView, имеют свои аналогичные Adapter.

3. Используйте его сами, а затем напишите отличный README.

Будьте своим собственным потребителем API. Укрепите цикл обратной связи, первым реализовав функцию с использованием вашего компонента.

Спроси себя,

Что я ожидаю от разработчика при его использовании?

затем запишите четкие шаги с примерами.

Хотя он может иметь доступ к беспорядочным реальным данным и для разумной минимизации сложности API, красота дизайна сохраняется. Как разработчик, вы первым почувствуете, что это оживает.

Кому сейчас весело?

Коллин - пользователь пользовательского интерфейса на Livefront, и он благодарит вас за чтение.