Освой Android играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Edge-to-Edge/Управление жестами: От края до края

В Android Q был добавлен новый режим навигации по системе, позволяющий пользователю возвращаться на предыдущий экран (жест от левого или правого края), переходить на главный экран (жест от нижнего края вверх) и запускать ассистента с помощью жестов.

С переходом на модель управления системой жестами приложения получили больше экранного пространства. В начале был переходный период, когда пользователи могли выбрать режим навигации: старый трёхкнопочный режим навигации (кнопки Back, Home, Recents) или новый через жесты. В последних версиях новый режим ставится по умолчанию и является настоятельно рекомендуемым.

В документации приводится GIF-картинка, показывающая изменения при переходе на новый режим.

Edge-to-Edge

При традиционном режиме приложения располагаются под строкой состояния (status bar) и над панелью навигации (navigation bar) - вместе они называются панелями системы (system bars).

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

Мы рассматриваем примеры, которые приходилось решать в 2019 году. Позже, система сама многое взяла на себя и вручную настраивать уже ничего не нужно.

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


<!-- values-v29/themes.xml -->
<style name="Theme.MyApp">
    <item name="android:navigationBarColor">
        @android:color/transparent
    </item>

    <!-- Optional, if drawing behind the status bar too -->
    <item name="android:statusBarColor">
        @android:color/transparent
    </item>
</style>

На устройствах Android Pie и ниже нужны следующие стили.


<!-- values/themes.xml -->
<style name="Theme.MyApp">
    <item name="android:navigationBarColor">
        #B3FFFFFF
    </item>
</style>

<!-- values-night/themes.xml -->
<style name="Theme.MyApp">
    <item name="android:navigationBarColor">
        #B3000000
    </item>
</style>

Insets

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

В Android Insets представлены классом WindowInsets, а в AndroidX - классом WindowInsetsCompat. Начиная с Android Q, у нас появляются 5 типов Insets, которые мы можем использовать при создании экранов приложения.

System window inset – наиболее распространённый тип Insets на сегодняшний день. Существуют с API 1. Частые примеры – строка состояния и панель навигации, а иногда и экранная клавиатура (IME). Узнать о нём можно через метод getSystemWindowInsets() (устарело, теперь getInsets() с systemBars). Мы можем использовать значения systemWindowInsets.bottom и systemWindowInsets.right, чтобы увеличить отступы компонента с каждой стороны, дабы переместить его подальше от панели навигации.

Tappable element insets появились в Android Q. Они очень похожи на system window insets выше, однако они реагируют на варьирующуюся видимость панели навигации. Используется метод getTappableElementInsets() (устарело, теперь getInsets() с tappableElement)).

Tappable element insets определяют минимальные Insets, которые нужно применить к интерактивным (tappable) компонентам. «Минимальные» в этом случае означает, что полученное значение может привести к конфликту с системными панелями. Этим они и отличаются от system window insets, которые всегда нацелены на избежание конфликтов с системными панелями.

И tappable element insets и system gesture insets ведут себя одинаково, когда устройство находится в режиме кнопочной навигации. Ключевая разница становится видна, когда устройство использует управление жестами и у него включена динамическая адаптация цвета. В этом случае панель навигации прозрачна, а это значит, что в ней теоретически можно расположить интерактивные компоненты, поэтому отступ от низа равен 0.

Gesture insets - появились в версии Android Q, где был представляет новый режим управления жестами. Используются методы getSystemGestureInsets() (устарело, теперь getInsets с systemGestures) и getMandatorySystemGestureInsets() (устарело, теперь getInsets с mandatorySystemGestures).

Пользователь может управлять устройством с помощью двух сенсорных жестов.

  1. Движение пальцем горизонтально от одного из краёв дисплея. Это запустит действие возврата
  2. Движение пальцем вверх от нижнего края дисплея. Это позволит пользователю перейти на свой домашний экран или к последним использованным приложениям

System gesture insets отражают области окна, в которых системные жесты имеют приоритет над жестами-касаниями в вашем приложении. Существует два типа system gesture insets: один из них хранит все области жестов, а второй – подмножество, содержащее обязательные из system gesture insets.

System gesture insets - содержат все области на экране, где системные жесты имеют приоритет над жестами вашего приложения. В Android Q это значит, что insets будут выглядеть примерно так, то есть содержать отступ от нижнего края для жеста возврата к домашнему экрану, отступы слева и справа для жеста «назад»:


           0
    +--------------+
    |              |
    |   System     |
 40 |   Gesture    |  40
    |   Insets     |
    |              |
    +--------------+
           60

Когда вам пригодятся system gesture insets? Эти insets указывают, где жесты системы имеют приоритет, поэтому вы можете использовать их для проактивного перемещения любых view, которым требуется жест свайпа.

Примерами могут послужить выдвигающийся снизу экран, свайпы в играх, карусели (по типу ViewPager). В целом, вы можете использовать эти insets для перемещения/создания отступов от краёв экрана.

Обязательные system gesture insets являются подмножеством system gesture insets и содержат только области, которые нельзя убрать из приложения (например, название). Помните, что приложения могут убрать системные жесты из некоторых областей экрана.

Обязательные system gesture insets указывают на области экрана, в которых системные жесты имеют приоритет всегда и являются обязательными. На Android Q единственной обязательной областью на данный момент является область жеста возврата на домашний экран в нижней части экрана. Это нужно, чтобы пользователь всегда мог выйти из приложения.


            0                              0  
    +--------------+               +--------------+
    |              |               |   Mandatory  |
    |   System     |               |   System     |
 40 |   Gesture    | 40          0 |   Gesture    | 0
    |   Insets     |               |   Insets     |
    |              |               |              |
    +--------------+               +--------------+
           60                             60

Видно, что system gesture insets содержат отступы слева, справа и снизу, тогда как необходимые содержат только отступ снизу для того, чтобы жест возврата на домашний экран отрабатывал нормально.

Stable insets относятся к system window insets, но они обозначают, где интерфейс системы может отображаться поверх вашего приложения, а не где он отображается в принципе. Stable insets в основном используются, когда интерфейс системы настроен таким образом, что его видимость может быть включена либо выключена, например, при использовании режимов lean back или immersive (например, игры, просмотр фотографий и видеоплееры). Используется метод getStableInsets() (устарело, теперь getInsetsIgnoringVisibility() с systemBars).

При работе с insets помните про класс WindowInsetsCompat. WindowInsets API улучшалось и расширялось на протяжении многих лет, а версия compat обеспечивает согласованность API и поведение на всех уровнях API.

Там, где затрагиваются новые типы insets, доступные в Android Q, метод compat представляет собой набор значений, которые являются валидными для хост-устройства на всех уровнях API.

Дополнительные материалы

Лабораторная работа

Управление жестами: Обработка визуальных перекрытий. Часть 2

Управление жестами: обработка конфликтов жестов. Часть 3

Реклама