Обратная навигация – это способ перемещения пользователей назад по истории посещенных ими ранее экранов. На всех устройствах Android предусмотрена кнопка «Назад» для этого типа навигации, поэтому вам не следует добавлять кнопку «Назад» в пользовательский интерфейс вашего приложения. В зависимости от устройства Android пользователя эта кнопка может быть физической или программной.
Android поддерживает резервную стопку пунктов назначения, когда пользователь перемещается по вашему приложению. Обычно это позволяет Android правильно перейти к предыдущим пунктам назначения при нажатии кнопки «Назад». Однако в некоторых случаях вашему приложению может потребоваться реализовать собственное поведение «Назад», чтобы обеспечить наилучшее взаимодействие с пользователем. Например, при использовании WebView
вы можете переопределить поведение кнопки «Назад» по умолчанию, чтобы позволить пользователю перемещаться назад по истории просмотра веб-страниц, а не к предыдущим экранам вашего приложения.
Внедрить пользовательскую обратную навигацию
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 } ... }
Ява
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
.
Активность onBackPressed()
Если вы используете onBackPressed()
для обработки событий кнопки «Назад», мы рекомендуем вместо этого использовать OnBackPressedCallback
. Однако если вы не можете внести это изменение, применяются следующие правила:
- Все обратные вызовы, зарегистрированные через
addCallback
, оцениваются при вызовеsuper.onBackPressed()
. - В Android 12 (уровень API 32) и более ранних версиях
onBackPressed
вызывается всегда, независимо от каких-либо зарегистрированных экземпляровOnBackPressedCallback
.