Android onbackpressed from fragment

Android onbackpressed from fragment

28 октября 2014

В Android-приложениях иногда требуется особым образом обработать нажатие кнопки back. Если у вас не используются фрагменты, всё просто. Перекрываем метод onBackPressed у Activity и делаем что нам нужно. Если же используются фрагменты и по нажатию back необходимо что-то поменять в фрагменте, обработку хочется сделать именно в нём.

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

Начнём с интерфейса для фрагментов. Готового в фреймворке нет, сделаем свой:

Далее перекроем метод onBackPressed в нашем FragmentActivity :

Вытаскиваем все фрагменты, которые у нас есть. Ищем первый попавшийся, который реализует наш интерфейс OnBackPressedListener . Тут можно было придумать что-то, чтобы работать с несколькими обработчиками, но чаще всего он один. Если есть фрагмент, который реализует OnBackPressedListener , вызываем его единственный метод. Если нет — обрабатываем back как обычно.

Ну и, наконец, сам фрагмент:

Плюс данного подхода в том, что можно, например, отнаследовать все наши activity от MyActivity и использовать OnBackPressedListener без каких-либо изменений в коде MyActivity .

Комментарии RSS по email OK

Александр, смотрю ты уже на Android перешел. Мобильная разработка всех поглощает? Или это просто хобби 🙂

Я не ограничиваю себя какой-то одной технологией или языком. В случае андройда это не хобби. Коммерческий проект.

Согласен. Я то в моб. разработке дальше ionicframework(cordova) не пошел пока.

Спасибо за ваш вариант. На основе вашего у меня родилось следующее решение:

Я новечек важно ваше мнение. Конструкция вроде работает. Но могут ли быть с ней проблемы?

Могут. Как минимум, стоит учитывать, что использоваться может более одного фрагмента в одном activity.

В ListActivity это выглядит примерно так:

А как такое сделать в ListFragment и обычном Activity?

Sam, а почему вы пишете «андроЙд»? Или вы с такой же ошибкой пишите слова «плазмоЙд», «гиперболоЙд», «стероЙд» и «планетоЙд»? Домашнее задание: попробуйте произнести вслух эти слова так, как они написаны — с буквой «Й». Постарайтесь при этом не завязать язык в узел.

Капитан О., описочка вышла. Кстати, произнести с «й» вполне получается и при этом ничего в узел не завязывается. Это сочетание звуков вполне характерно для английского.

Читайте также:  Android studio поворот экрана сохранение данных

Спасибо за статью! Очень наглядный пример как ловить onBackPressed в фрагментах)

Источник

Как реализовать onBackPressed () во фрагментах?

Есть ли способ, которым мы можем реализовать onBackPressed() в Android Fragment аналогично тому, как мы реализуем в Android Activity?

Так как Фрагмент жизненного цикла не имеет onBackPressed() . Есть ли другой альтернативный способ перегрузки onBackPressed() фрагментов Android 3.0?

Я решил таким образом переопределить onBackPressed в Activity. Все FragmentTransaction это , addToBackStack прежде чем совершить:

На мой взгляд, лучшее решение:

JAVA SOLUTION

Создать простой интерфейс:

И в вашей деятельности

Наконец в вашем фрагменте:

КОТЛИН РЕШЕНИЕ

1 — Создать интерфейс

2 — Подготовьте свою деятельность

3 — Внедрите в свой целевой фрагмент

Согласно @HaMMeRed ответом здесь является псевдокод, как он должен работать. Допустим, называется ваша основная деятельность BaseActivity с дочерними фрагментами (как в примере с SlidingMenu lib). Вот шаги:

Сначала нам нужно создать интерфейс и класс, который реализует его интерфейс, чтобы иметь универсальный метод

Создать интерфейс класса OnBackPressedListener

Создать класс, который реализует навыки OnBackPressedListener

С этого момента мы будем работать над нашим кодом BaseActivity и его фрагментами.

Создайте частного слушателя на вершине своего класса BaseActivity

создать метод для установки слушателя в BaseActivity

в переопределении onBackPressed реализовать что-то подобное

в вашем фрагменте onCreateView вы должны добавить наш слушатель

Вуаля, теперь, когда ты щелкаешь обратно фрагментом, ты должен поймать свой метод на спине.

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

Изменить: я хотел бы добавить свой предыдущий ответ.

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

LocalBroadcastManager в библиотеке поддержки может помочь с этим, и вы просто отправляете трансляцию onBackPressed и подписываетесь на интересующие вас фрагменты. Я думаю, что Messaging является более изолированной реализацией и будет лучше масштабироваться, поэтому сейчас это будет моя официальная рекомендация по внедрению. Просто используйте Intent действие в качестве фильтра для вашего сообщения. отправьте только что созданное ACTION_BACK_PRESSED , отправьте его из своей деятельности и прослушайте в соответствующих фрагментах.

Ничто из этого не легко реализовать и не будет функционировать оптимальным образом.

Читайте также:  Msi afterburner android как настроить

У фрагментов есть вызов метода onDetach, который сделает эту работу.

ЭТО ДЕЛАЕТ РАБОТУ.

Если вы используете androidx.appcompat:appcompat:1.1.0 или выше, вы можете добавить OnBackPressedCallback к своему фрагменту, как показано ниже

Просто добавьте, addToBackStack пока вы переходите между фрагментами, как показано ниже:

если вы пишете addToBackStack(null) , он будет обрабатывать его сам, но если вы дадите тег, вы должны обработать его вручную.

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

ОБНОВИТЬ: В нижней части этой статьи я добавил альтернативную реализацию, использующую абстрактное расширение Fragment, которое вообще не будет включать Activity, что было бы полезно для любого с более сложной иерархией фрагментов, включающей вложенные фрагменты, которые требуют различного обратного поведения.

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

Сначала определите интерфейс

Этот интерфейс, который я называю Backable (я сторонник соглашений об именах), имеет единственный метод, onBackPressed() который должен возвращать boolean значение. Нам нужно ввести логическое значение, потому что нам нужно будет знать, «нажата» ли кнопка «назад», «поглотила» ли она событие назад. Возврат true означает, что он есть, и никаких дальнейших действий не требуется, в противном случае он false говорит, что обратное действие по умолчанию все еще должно иметь место. Этот интерфейс должен быть его собственным файлом (желательно в отдельном названном пакете interfaces ). Помните, что разделение ваших классов на пакеты — это хорошая практика.

Во-вторых, найдите верхний фрагмент

Я создал метод, который возвращает последний Fragment объект в заднем стеке. Я использую теги . если вы используете ID, внесите необходимые изменения. У меня есть этот статический метод в служебном классе, который имеет дело с состояниями навигации и т. Д., Но, конечно, поместите его там, где он вам больше подходит. Для назидания я поместил свой класс в класс NavUtils .

Удостоверьтесь, что число обратных стеков больше 0, иначе ArrayOutOfBoundsException может быть выброшено во время выполнения. Если оно не больше 0, вернуть ноль. Мы проверим нулевое значение позже .

В-третьих, реализовать в фрагменте

Реализуйте Backable интерфейс в любом фрагменте, где вам нужно переопределить поведение кнопки «Назад». Добавьте метод реализации.

Читайте также:  Лучшие видеоплееры для андроид телевизоров

В onBackPressed() переопределении поместите любую логику, которая вам нужна. Если вы хотите, чтобы кнопка «Назад» не вставляла задний стек (поведение по умолчанию), верните true , чтобы событие «Назад» было поглощено. В противном случае верните false.

Наконец, в вашей деятельности .

Переопределите onBackPressed() метод и добавьте к нему следующую логику:

Мы получаем текущий фрагмент в заднем стеке, затем делаем нулевую проверку и определяем, реализует ли он наш Backable интерфейс. Если это так, определите, было ли событие поглощено. Если это так, мы закончили onBackPressed() и можем вернуться. В противном случае рассматривайте это как обычное нажатие назад и вызывайте метод super.

Второй вариант — не привлекать активность

Иногда вы не хотите, чтобы Activity обрабатывал это вообще, и вам нужно обрабатывать это непосредственно внутри фрагмента. Но кто сказал, что у вас не может быть фрагментов с API для обратной печати? Просто расширьте свой фрагмент до нового класса.

Создайте абстрактный класс, который расширяет Fragment и реализует View.OnKeyListner интерфейс .

Как вы можете видеть, любой фрагмент, который расширяется, BackableFragment будет автоматически захватывать обратные клики, используя View.OnKeyListener интерфейс. Просто вызовите абстрактный onBackButtonPressed() метод из реализованного onKey() метода, используя стандартную логику, чтобы распознать нажатие кнопки назад. Если вам нужно зарегистрировать нажатия клавиш, отличные от кнопки «Назад», просто вызовите super метод при переопределении onKey() вашего фрагмента, иначе вы переопределите поведение в абстракции.

Прост в использовании, просто расширьте и внедрите:

Поскольку onBackButtonPressed() метод в суперклассе является абстрактным, после расширения вы должны реализовать его onBackButtonPressed() . Он возвращается, void потому что ему просто нужно выполнить действие внутри класса фрагмента, и ему не нужно ретранслировать поглощение прессы обратно в Activity. Убедитесь, что вы вызываете onBackPressed() метод Activity, если все, что вы делаете с кнопкой «назад», не требует обработки, в противном случае кнопка «Назад» будет отключена . и вам это не нужно!

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

Я надеюсь, что кто-то найдет это полезным. Удачного кодирования.

Источник

Оцените статью