Обеспечьте настраиваемую обратную навигацию

Пользователи перемещаются назад по экранам с помощью кнопки «Назад» . Большинство устройств Android имеют кнопку «Назад» — физическую, программную или управляемую жестами. Обычно добавлять кнопку «Назад» в приложение не рекомендуется. Однако устройства Android Automotive OS (AAOS) в режиме совместимости используют системную кнопку «Назад». Она отвечает за навигацию, поэтому добавлять свою собственную кнопку не нужно. Подробнее см. в разделе «Режим совместимости AAOS» .

Android поддерживает стек возврата к предыдущим страницам по мере перемещения пользователя по приложению. Обычно это позволяет Android корректно возвращаться к предыдущим страницам при нажатии кнопки «Назад». Однако в некоторых случаях вашему приложению может потребоваться реализовать собственное поведение кнопки «Назад» для обеспечения наилучшего пользовательского опыта. Например, при использовании WebView вы можете переопределить поведение кнопки «Назад» по умолчанию, чтобы позволить пользователю возвращаться к истории просмотра веб-страниц, а не к предыдущим экранам вашего приложения.

Реализуйте пользовательскую навигацию "Назад" в Compose.

В Jetpack Compose вы можете управлять пользовательской навигацией назад с помощью составного объекта BackHandler .

При использовании Navigation Compose обычно для перехода на предыдущий экран в стеке возврата используются NavController.navigateUp() или NavController.popBackStack() Однако BackHandler полезен в случаях, когда необходимо реализовать пользовательское поведение при нажатии системной кнопки «Назад» или использовании жеста «Назад». Например, если в вашем приложении отображается WebView , вы можете разрешить пользователям возвращаться назад по истории просмотров при нажатии системной кнопки «Назад».

Если у вас включено несколько компонуемых объектов BackHandler на разных уровнях дерева компонуемых объектов, то событие "назад" будет перехватывать только самый внутренний из них.

Реализуйте пользовательскую навигацию "Назад" с помощью Views.

ComponentActivity , базовый класс для FragmentActivity и AppCompatActivity , позволяет управлять поведением кнопки «Назад» с помощью метода OnBackPressedDispatcher , который можно получить, вызвав getOnBackPressedDispatcher() .

Объект OnBackPressedDispatcher управляет тем, как события кнопки «Назад» передаются одному или нескольким объектам OnBackPressedCallback . Конструктор OnBackPressedCallback принимает логическое значение для начального состояния активности. Только когда функция обратного вызова активна, например, когда isEnabled() возвращает true , диспетчер вызовет метод handleOnBackPressed() этой функции для обработки события кнопки «Назад». Вы можете изменить состояние активности, вызвав setEnabled() .

Коллбэки добавляются с помощью методов addCallback . Используйте метод addCallback() , который принимает LifecycleOwner . Таким образом, OnBackPressedCallback добавляется только тогда, когда LifecycleOwner имеет Lifecycle.State.STARTED . Активность также удаляет зарегистрированные коллбэки, когда связанный с ними LifecycleOwner уничтожается, что предотвращает утечки памяти и делает ее подходящей для использования во фрагментах или других владельцах жизненного цикла, имеющих более короткий срок жизни, чем активность.

Вот пример реализации функции обратного вызова:

Котлин

class MyFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // This callback will only be called when MyFragment is at least Started.
        val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
            // Handle the back button event
        }

        // The callback can be enabled or disabled here or in the lambda
    }
    ...
}

Java

public class MyFragment extends Fragment {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // This callback will only be called when MyFragment is at least Started.
        OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
            @Override
            public void handleOnBackPressed() {
                // Handle the back button event
            }
        };
        requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);

        // The callback can be enabled or disabled here or in handleOnBackPressed()
    }
    ...
}

С помощью addCallback() можно указать несколько коллбэков. При этом коллбэки вызываются в обратном порядке их добавления — последний добавленный коллбэк первым получает возможность обработать событие нажатия кнопки «Назад». Например, если вы добавили три коллбэка с именами one , two и three в указанном порядке, они будут вызваны в порядке three , two и one соответственно.

Обратные вызовы следуют шаблону «цепочка ответственности» . Каждый обратный вызов в цепочке вызывается только в том случае, если предыдущий обратный вызов не был включен. Это означает, что в приведенном выше примере two обратный вызов будет вызван только в том случае, если three обратный вызов не был включен. one обратный вызов будет вызван только в том случае, если two обратный вызов не был включен, и так далее.

Обратите внимание, что при добавлении с помощью addCallback() функция обратного вызова не добавляется в цепочку ответственности до тех пор, пока LifecycleOwner не перейдет в состояние Lifecycle.State.STARTED .

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

Однако, если вы хотите полностью удалить OnBackPressedCallback , следует вызвать remove() . Впрочем, обычно это не требуется, поскольку коллбэки автоматически удаляются при уничтожении связанного с ними LifecycleOwner .