Есть ли способ, которым мы можем реализовать onBackPressed()
в Android Fragment аналогично тому, как мы реализуем в Android Activity?
Так как Фрагмент жизненного цикла не имеет onBackPressed()
. Есть ли другой альтернативный способ перегрузки onBackPressed()
фрагментов Android 3.0?
android
android-fragments
onbackpressed
Android_programmer_camera
источник
источник
Ответы:
Я решил таким образом переопределить
onBackPressed
в Activity. ВсеFragmentTransaction
это ,addToBackStack
прежде чем совершить:источник
На мой взгляд, лучшее решение:
JAVA SOLUTION
Создать простой интерфейс:
И в вашей деятельности
Наконец в вашем фрагменте:
КОТЛИН РЕШЕНИЕ
1 - Создать интерфейс
2 - Подготовьте свою деятельность
3 - Внедрите в свой целевой фрагмент
источник
R.id.main_container
? Это идентификатор для FragmentPager?.?
) и принудительное использование ненулевых (!!
) может привести к NPE - приведение не всегда безопасно. Я лучше напишуif ((fragment as? IOnBackPressed)?.onBackPressed()?.not() == true) { ... }
или еще котлиней(fragment as? IOnBackPressed)?.onBackPressed()?.not()?.let { ... }
.onBackPressed()?.takeIf { !it }?.let{...}
?.not()
просто возвращает обратное.val fragment = this.supportFragmentManager.findFragmentById(R.id.flContainer) as? NavHostFragment val currentFragment = fragment?.childFragmentManager?.fragments?.get(0) as? IOnBackPressed currentFragment?.onBackPressed()?.takeIf { !it }?.let{ super.onBackPressed() }
Это для людей, которые используют Kotlin и NavigationControllerСогласно @HaMMeRed ответом здесь является псевдокод, как он должен работать. Допустим, называется ваша основная деятельность
BaseActivity
с дочерними фрагментами (как в примере с SlidingMenu lib). Вот шаги:Сначала нам нужно создать интерфейс и класс, который реализует его интерфейс, чтобы иметь универсальный метод
Создать интерфейс класса
OnBackPressedListener
Создать класс, который реализует навыки
OnBackPressedListener
С этого момента мы будем работать над нашим кодом
BaseActivity
и его фрагментами.Создайте частного слушателя на вершине своего класса
BaseActivity
создать метод для установки слушателя в
BaseActivity
в переопределении
onBackPressed
реализовать что-то подобноев вашем фрагменте
onCreateView
вы должны добавить наш слушательВуаля, теперь, когда ты щелкаешь обратно фрагментом, ты должен поймать свой метод на спине.
источник
onBackPressed()
, какой фрагмент отображался при нажатии кнопки «Назад»?((BaseActivity)activity).setOnBackPressedListener(new OnBackpressedListener(){ public void doBack() { //...your stuff here }});
Это сработало для меня: https://stackoverflow.com/a/27145007/3934111
источник
Если вам нужна такая функциональность, вам нужно переопределить ее в своей деятельности, а затем добавить
YourBackPressed
интерфейс для всех ваших фрагментов, который вы вызываете для соответствующего фрагмента при каждом нажатии кнопки «Назад».Изменить: я хотел бы добавить свой предыдущий ответ.
Если бы я делал это сегодня, я бы использовал трансляцию или, возможно, заказанную трансляцию, если бы ожидал, что другие панели будут обновляться в унисон на панель основного / основного контента.
LocalBroadcastManager
в библиотеке поддержки может помочь с этим, и вы просто отправляете трансляциюonBackPressed
и подписываетесь на интересующие вас фрагменты. Я думаю, что Messaging является более изолированной реализацией и будет лучше масштабироваться, поэтому сейчас это будет моя официальная рекомендация по внедрению. Просто используйтеIntent
действие в качестве фильтра для вашего сообщения. отправьте только что созданноеACTION_BACK_PRESSED
, отправьте его из своей деятельности и прослушайте в соответствующих фрагментах.источник
LocalBroadcastManager
не может делать заказанные трансляцииНичто из этого не легко реализовать и не будет функционировать оптимальным образом.
У фрагментов есть вызов метода onDetach, который сделает эту работу.
ЭТО ДЕЛАЕТ РАБОТУ.
источник
isRemoving()
как описано в stackoverflow.com/a/27103891/2914140 .Если вы используете
androidx.appcompat:appcompat:1.1.0
или выше, вы можете добавитьOnBackPressedCallback
к своему фрагменту, как показано нижеСм. Https://developer.android.com/guide/navigation/navigation-custom-back.
источник
androidx-core-ktx
, вы можете использоватьrequireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) { /* code to be executed when back is pressed */ }
LifecycleOwner
параметр должен быть добавлен как в этом примере. Без этого любые фрагменты, запущенные впоследствии, будут вызываться,handleBackPressed()
если нажата кнопка «Назад».Просто добавьте,
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, чтобы потерять фокус на спине.
Я надеюсь, что кто-то найдет это полезным. Удачного кодирования.
источник
super.onBackPressed();
дважды?currentFragment
. Если фрагмент не нулевой и фрагмент реализуетBackable
интерфейс, никаких действий не предпринимается. Если фрагмент не нулевой и он НЕ реализуетсяBackable
, мы вызываем метод super. Если фрагмент нулевой, он переходит к последнему супер вызову.currentFragment
не равно NULL и является экземпляром Backable, и он отсоединен (мы нажалиback
кнопку и закрыли фрагмент),super.onBackPressed();
вызывается первый вхождение , затем второй.Решение простое:
1) Если у вас есть базовый класс фрагмента, который расширяют все фрагменты, добавьте этот код в свой класс, в противном случае создайте такой базовый класс фрагмента.
2) В вашем классе Activity переопределите onBackPressed следующим образом:
3) В классе Your Fragment добавьте нужный код:
источник
onBackPressed()
привести к отрыву фрагмента от действия.Согласно ответу @Sterling Diaz, я думаю, что он прав. НО какая-то ситуация будет неправильной. (напр. поворот экрана)
Итак, я думаю, что мы могли бы определить, следует ли
isRemoving()
достичь целей.Вы можете написать это на
onDetach()
илиonDestroyView()
. Это работа.источник
Ну, я сделал это так, и это работает для меня
Простой интерфейс
FragmentOnBackClickInterface.java
Пример реализации
MyFragment.java
затем просто переопределить onBackPressed в активности
источник
Вы должны добавить интерфейс к вашему проекту, как показано ниже;
И затем, вы должны реализовать этот интерфейс на вашем фрагменте;
И вы можете вызвать это событие onBackPressed под вашим действием onBackPressed, как показано ниже;
источник
getActivity().onBackPressed();
его, так как он вызовет исключение: "java.lang.StackOverflowError: размер стека 8 МБ".Это всего лишь небольшой код, который сделает свое дело:
Надеюсь, это поможет кому-то :)
источник
Если вы используете EventBus, это, вероятно, гораздо более простое решение:
и в вашем классе деятельности вы можете определить:
BackPressedMessage.java это просто объект POJO
Это супер чистый и нет проблем с интерфейсом / реализацией.
источник
это мое решение:
источник
Используя компонент навигации, вы можете сделать это так :
источник
Как насчет использования onDestroyView ()?
источник
i = i
илиif (1 < 0) {}
.источник
в вашем фрагменте добавьте следующее, не забудьте реализовать интерфейс mainactivity.
источник
В моем решении (Kotlin);
Я использую функцию onBackAlternative в качестве параметра BaseActivity .
BaseActivity
У меня есть функция для установки onBackPressAlternative на BaseFragment .
BaseFragment
Тогда мой onBackPressAlternative готов к использованию на фрагментах.
Подфрагменты
источник
Не реализуйте метод ft.addToBackStack (), чтобы после нажатия кнопки «Назад» ваша деятельность была завершена.
источник
Просто следуйте этим шагам:
Всегда при добавлении фрагмента,
Затем в основной деятельности переопределить
onBackPressed()
Чтобы обработать кнопку возврата в вашем приложении,
Это оно!
источник
В жизненном цикле действия всегда кнопка «назад» для Android имеет дело с транзакциями FragmentManager, когда мы использовали FragmentActivity или AppCompatActivity.
Чтобы обработать backstack, нам не нужно обрабатывать его подсчет backstack или помечать что-либо, но мы должны сохранять фокус при добавлении или замене фрагмента. Пожалуйста, найдите следующие фрагменты, чтобы обработать кнопки возврата,
Здесь я не буду добавлять обратно стек для моего домашнего фрагмента, потому что это домашняя страница моего приложения. Если добавить addToBackStack в HomeFragment, то приложение будет ожидать удаления всех фрагментов в действии, тогда мы получим пустой экран, поэтому я соблюдаю следующее условие:
Теперь вы можете увидеть ранее добавленный фрагмент на acitvity и приложение выйдет при достижении HomeFragment. Вы также можете посмотреть на следующие фрагменты.
источник
Фрагмент: Сделать BaseFragment, поместив метод:
Деятельность:
Ваша активность будет проходить по прикрепленным и видимым фрагментам, вызывать onBackPressed () для каждого из них и прерывать работу, если один из них вернет true (это означает, что он был обработан, поэтому никаких дальнейших действий).
источник
Согласно примечаниям к выпуску AndroidX ,
androidx.activity 1.0.0-alpha01
выпущен и представленComponentActivity
новый базовый класс существующихFragmentActivity
иAppCompatActivity
. И этот релиз приносит нам новую функцию:Теперь вы можете зарегистрировать
OnBackPressedCallback
каналaddOnBackPressedCallback
для полученияonBackPressed()
обратных вызовов без необходимости переопределять метод в вашей деятельности.источник
Вы можете зарегистрировать фрагмент в действии, чтобы справиться с прессой:
Применение:
Во фрагменте:
В деятельности:
источник
Предоставление пользовательской обратной навигации с помощью onBackPressed теперь стало проще с обратными вызовами внутри фрагмента.
Если вы хотите обратное действие по умолчанию на основе какого-либо условия, вы можете использовать:
источник
Внутри метода onCreate фрагмента добавьте следующее:
источник
Лучшее решение,
источник