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

Обратная навигация – это способ перемещения пользователей назад по истории посещенных ими ранее экранов. На всех устройствах 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 .