Добавить поддержку интеллектуального жеста назад.

Рисунок 1. Макет интерфейса и функциональности прогнозируемого жеста «Назад» на телефоне.

Функция «Предиктивная навигация назад» (Predictive Back), использующая жесты, позволяет пользователям предварительно просмотреть, куда их перенесет жест «назад».

Например, с помощью жеста «назад» можно отобразить анимированный предварительный просмотр главного экрана, расположенного за вашим приложением, как показано на макете на рисунке 1.

Начиная с Android 15, опция разработчика для анимаций возврата назад больше недоступна. Системные анимации, такие как возврат на главный экран, анимация при переходе между задачами и действиями, теперь отображаются для приложений, которые полностью или частично включили функцию прогнозирования жеста возврата назад.

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

Для поддержки предиктивного жеста «назад» необходимо обновить приложение, использовать обратно совместимый API OnBackPressedCallback AppCompat 1.6.0-alpha05 (AndroidX) или более поздней версии, либо использовать новый API платформы OnBackInvokedCallback . Большинство приложений используют обратно совместимый API AndroidX.

Это обновление предоставляет путь миграции для корректного перехвата перехода назад, который включает замену перехвата перехода назад из KeyEvent.KEYCODE_BACK и любых классов с методами onBackPressed , таких как Activity и Dialog на новые системные API для перехода назад.

Видео Codelab и Google I/O

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

Вы также можете посмотреть наше видео с Google I/O, в котором представлены дополнительные примеры реализации AndroidX и API платформы.

Обновите приложение, использующее стандартную навигацию «Назад».

Функция предиктивного ответа включена по умолчанию.

Если ваше приложение использует фрагменты или компонент навигации, обновите AndroidX Activity до версии 1.6.0-alpha05 или выше.

Обновите приложение, использующее пользовательскую навигацию "Назад".

Если ваше приложение реализует пользовательское поведение возврата назад, существуют разные пути миграции в зависимости от того, использует ли оно AndroidX и как обрабатывает навигацию назад.

Ваше приложение использует AndroidX. Как ваше приложение обрабатывает возврат к предыдущему экрану Рекомендуемый путь миграции (ссылка на этой странице)
Да API AndroidX Перенести существующую реализацию AndroidX на задний план.
Неподдерживаемые API платформы Перенесите приложение AndroidX, содержащее неподдерживаемые API для навигации назад, на API AndroidX.
Нет Неподдерживаемые API платформы, возможна миграция. Перенесите приложение, использующее неподдерживаемые API для обратной навигации, на API платформы.
API платформы не поддерживаются, но миграция невозможна. Временно отключить эту функцию можно, установив атрибут android:enableOnBackInvokedCallback в false в теге <application> или <activity> файла AndroidManifest.xml вашего приложения.

Перенести реализацию навигации "назад" из AndroidX.

Этот вариант использования является наиболее распространенным (и наиболее рекомендуемым). Он применим к новым или существующим приложениям, которые реализуют пользовательскую обработку навигации жестами с помощью OnBackPressedDispatcher , как описано в разделе «Предоставление пользовательской навигации назад» .

Чтобы обеспечить бесперебойную работу API, уже использующих OnBackPressedDispatcher (таких как фрагменты и компонент навигации), с предиктивным жестом «назад», обновите AndroidX Activity до версии 1.6.0-alpha05 .

```xml
// In your build.gradle file:
dependencies {

// Add this in addition to your other dependencies
implementation "androidx.activity:activity:1.6.0-alpha05"
```

Перенесите приложение AndroidX, содержащее неподдерживаемые API для навигации назад, на API AndroidX.

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

Для переноса неподдерживаемых API на API AndroidX:

  1. Migrate your system Back handling logic to AndroidX's OnBackPressedDispatcher with an implementation of OnBackPressedCallback . For detailed guidance, see Provide custom back navigation .

  2. Отключите функцию OnBackPressedCallback , когда будете готовы прекратить перехват жеста "назад".

  3. Прекратите перехватывать события возврата через OnBackPressed или KeyEvent.KEYCODE_BACK .

  4. Обязательно обновите AndroidX Activity до версии 1.6.0-alpha05 .

    // In your build.gradle file:
    dependencies {
    
    // Add this in addition to your other dependencies
    implementation "androidx.activity:activity:1.6.0-alpha05"
    

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

Если ваше приложение не может использовать библиотеки AndroidX и вместо этого реализует или ссылается на пользовательскую навигацию «Назад» с помощью неподдерживаемых API, вам необходимо перейти на API платформы OnBackInvokedCallback .

Выполните следующие шаги для переноса неподдерживаемых API в API платформы:

  1. Используйте новый API OnBackInvokedCallback на устройствах под управлением Android 13 и выше, а на устройствах под управлением Android 12 и ниже используйте неподдерживаемые API.

  2. Зарегистрируйте свою пользовательскую логику возврата в OnBackInvokedCallback с помощью onBackInvokedDispatcher . Это предотвратит завершение текущей активности, и ваш коллбэк получит возможность отреагировать на действие «Назад» после того, как пользователь завершит системную навигацию «Назад».

  3. Отмените регистрацию OnBackInvokedCallback когда будете готовы прекратить перехват жеста «Назад». В противном случае пользователи могут столкнуться с нежелательным поведением при использовании системной навигации «Назад» — например, «застреванием» между представлениями и необходимостью принудительного завершения работы приложения.

    Вот пример того, как перенести логику из onBackPressed :

    Котлин

    @Override
    fun onCreate() {
        if (BuildCompat.isAtLeastT()) {
            onBackInvokedDispatcher.registerOnBackInvokedCallback(
                OnBackInvokedDispatcher.PRIORITY_DEFAULT
            ) {
                /**
                 * onBackPressed logic goes here. For instance:
                 * Prevents closing the app to go home screen when in the
                 * middle of entering data to a form
                 * or from accidentally leaving a fragment with a WebView in it
                 *
                 * Unregistering the callback to stop intercepting the back gesture:
                 * When the user transitions to the topmost screen (activity, fragment)
                 * in the BackStack, unregister the callback by using
                 * OnBackInvokeDispatcher.unregisterOnBackInvokedCallback
                 * (https://developer.android.com/reference/kotlin/android/window/OnBackInvokedDispatcher#unregisteronbackinvokedcallback)
                 */
            }
        }
    }

    Java

    @Override
    void onCreate() {
      if (BuildCompat.isAtLeastT()) {
        getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT,
            () -> {
              /**
               * onBackPressed logic goes here - For instance:
               * Prevents closing the app to go home screen when in the
               * middle of entering data to a form
               * or from accidentally leaving a fragment with a WebView in it
               *
               * Unregistering the callback to stop intercepting the back gesture:
               * When the user transitions to the topmost screen (activity, fragment)
               * in the BackStack, unregister the callback by using
               * OnBackInvokeDispatcher.unregisterOnBackInvokedCallback
               * (https://developer.android.com/reference/kotlin/android/view/OnBackInvokedDispatcher#unregisteronbackinvokedcallback)
               */
            }
        );
      }
    }
  4. Прекратите перехват событий возврата с помощью OnBackPressed или KeyEvent.KEYCODE_BACK в Android 13 и более поздних версиях.

Вы можете зарегистрировать OnBackInvokedCallback с PRIORITY_DEFAULT или PRIORITY_OVERLAY , что недоступно в аналогичном AndroidX OnBackPressedCallback . Регистрация коллбэка с PRIORITY_OVERLAY полезна в некоторых случаях.

Это относится к случаю, когда вы переходите с onKeyPreIme() и вашему коллбэку необходимо получить жест "назад" вместо открытого IME. IME регистрируют коллбэки с PRIORITY_DEFAULT при открытии. Зарегистрируйте свой коллбэк с PRIORITY_OVERLAY , чтобы гарантировать, что OnBackInvokedDispatcher передаст жест "назад" вашему коллбэку, а не открытому IME.

Отказаться от функции прогнозирования результатов

Чтобы отказаться от этого, в файле AndroidManifest.xml , в теге <application> , установите флаг android:enableOnBackInvokedCallback в false .

<application
    ...
    android:enableOnBackInvokedCallback="false"
    ... >
...
</application>

Установка этого параметра в значение false приводит к следующему результату:

  • Отключает анимацию системы прогнозирования жестов при движении назад.
  • Игнорирует OnBackInvokedCallback , но вызовы OnBackPressedCallback продолжают работать.

Отказаться от участия на уровне активности

Флаг android:enableOnBackInvokedCallback позволяет отказаться от предиктивной системной анимации на уровне активности. Такое поведение упрощает миграцию больших приложений с несколькими активностями на предиктивные жесты возврата.

Приведенный ниже код демонстрирует пример использования параметра enableOnBackInvokedCallback для включения системной анимации возврата на главный экран из MainActivity :

<manifest ...>
    <application . . .

        android:enableOnBackInvokedCallback="false">

        <activity
            android:name=".MainActivity"
            android:enableOnBackInvokedCallback="true"
            ...
        </activity>
        <activity
            android:name=".SecondActivity"
            android:enableOnBackInvokedCallback="false"
            ...
        </activity>
    </application>
</manifest>

При использовании флага android:enableOnBackInvokedCallback следует учитывать следующие моменты:

  • Установка параметра android:enableOnBackInvokedCallback=false отключает анимацию «назад» с функцией прогнозирования либо на уровне активности, либо на уровне приложения, в зависимости от того, где вы задали этот тег, и указывает системе игнорировать вызовы API платформы OnBackInvokedCallback . Однако вызовы OnBackPressedCallback продолжают выполняться, поскольку OnBackPressedCallback обратно совместим и вызывает API onBackPressed , который не поддерживается до Android 13.
  • Установка флага enableOnBackInvokedCallback на уровне приложения задает значение по умолчанию для всех действий в приложении. Вы можете переопределить значение по умолчанию для каждого действия, установив флаг на уровне действия, как показано в приведенном выше примере кода.

Рекомендации по использованию функции обратного вызова

Ниже приведены рекомендации по использованию поддерживаемых системных обратных вызовов: BackHandler (для Compose), OnBackPressedCallback или OnBackInvokedCallback .

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

Состояние пользовательского интерфейса — это свойство, описывающее пользовательский интерфейс. Мы рекомендуем выполнить следующие основные шаги.

  1. Определите состояние пользовательского интерфейса, которое включает и отключает каждый обратный вызов.

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

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

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

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

Если в вашем приложении включена функция OnBackPressedCallback или OnBackInvokedCallback с PRIORITY_DEFAULT или PRIORITY_OVERLAY , анимация возврата назад не будет выполняться, и вам необходимо будет обработать событие возврата. Не создавайте эти функции обратного вызова для выполнения бизнес-логики или для логирования.

Если вашему приложению необходимо выполнять бизнес-логику или регистрировать события, когда пользователь смахивает назад, используйте следующие подходы:

  • Используйте OnBackInvokedCallback с PRIORITY_SYSTEM_NAVIGATION_OBSERVER на устройствах под управлением Android 16 и выше. Это создаст коллбэк-наблюдатель, который не обрабатывает событие «Назад». Например, вы можете зарегистрировать этот коллбэк, когда пользователь проводит пальцем назад от корневой активности, или, другими словами, когда пользователь покидает ваше приложение. В этом случае вы можете регистрировать событие «Назад» или выполнять другую бизнес-логику, и анимация возвращения на главный экран все равно будет воспроизводиться.
  • В случаях взаимодействия между активностями или между фрагментами, регистрируйте в логе, если isFinishing в onDestroy true в рамках жизненного цикла Activity.
  • В случаях, когда изменения происходят между фрагментами, регистрируйте в логе, если isRemoving в onDestroy имеет значение true в рамках жизненного цикла представления фрагмента. Или регистрируйте с помощью методов onBackStackChangeStarted или onBackStackChangeCommitted в FragmentManager.OnBackStackChangedListener .
  • В случае с Compose, логи следует выводить в обработчике события onCleared() ViewModel , связанного с целевым объектом Compose. Это лучший способ узнать, когда целевой объект Compose удаляется из стека возврата и уничтожается.

Создайте обратные вызовы с единственной обязанностью.

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

Управлять состоянием активности функции обратного вызова проще, если эта функция выполняет единственную задачу. Например:

Порядок вызова функций обратного вызова в стеке.
Рисунок 2. Диаграмма стека обратных вызовов.

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

Другой вариант обратного вызова может включать компонент Material Design, поддерживающий предиктивную отмену перехода, переход AndroidX с использованием API Progress или другой пользовательский обратный вызов.

Коллбэк childFragmentManager выполняется, если указанные выше коллбэки отключены и стек возврата для этого FragmentManager не пуст, при условии, что childFragmentManager прикреплен к фрагменту. В этом примере этот внутренний коллбэк отключен.

Аналогично, внутренний коллбэк supportFragmentManager срабатывает, если указанные выше коллбэки отключены и его стек не пуст. Такое поведение наблюдается при использовании FragmentManager или NavigationComponent для навигации, поскольку NavigationComponent зависит от FragmentManager . В этом примере этот коллбэк срабатывает, если пользователь не ввел текст в форму, что привело к отключению коллбэка "Вы уверены...".

Наконец, super.onBackPressed() — это системный коллбэк, который снова срабатывает, если указанные выше коллбэки отключены. Для запуска системных анимаций, таких как возврат на главный экран, анимация между различными активностями и задачами, стек возврата supportFragmentManager должен быть пустым, чтобы его внутренний коллбэк был отключен.

Протестируйте анимацию предиктивного жеста «назад».

Если вы все еще используете Android 13 или Android 14, вы можете протестировать анимацию возврата на главный экран, показанную на рисунке 1.

Для проверки этой анимации выполните следующие шаги:

  1. На вашем устройстве перейдите в Настройки > Система > Параметры разработчика .

  2. Выберите «Предиктивная анимация спины» .

  3. Запустите обновлённое приложение и используйте жест «назад», чтобы увидеть его в действии.