Onbackpressed fragment android studio

Android – handle back press in Fragment

This article describes how our FragmentBack works under the hood. If you are looking for ready to use solution than it is much better to use this tiny (1.5 kB) library instead of doing it yourself. In addition to the functionality described here, in FragmentBack library, you can also define a priority for your fragments.

BaseFragment

The first step to create back-sensitive fragments is to define the interface that we can call to notify particular fragments about back-press. It contains only one method onBackPressed() which returns a value that indicates if back-press event was consumed by the fragment.

In this example, we use the base class, but you can define it via the interface as well.

BaseActivity

The next step is an activity with the overwritten Activity.onBackPressed() method. In its body, we list all fragments attached to activity and for this implementing our BaseFragment class/interface we notify them about the new back-press event. The notified fragment can indicate event consumption by returning true , in this case, we stop iterating and leave the method. If no fragment consumed the event we invoke standard Activity.onBackPressed() implementation to dismiss activity.

Now simply by extending this BaseActivity all back-press events will be propagated to all your BaseFragments placed in it.

MyFragment

The last step is to implement such back-sensitive fragment. There is nothing simpler, just extend/implement your BaseFragment class/interface and handle back-press events in onBackPressed() properly or just return false to ignore it.

Do you need more detailed help? Book a consultation:
Let’s chat about it

Do you want more?

We share the world of software development on our Instagram. Join us 🙂

We also tend to look for Android dev (iOS as well), but there are also chances for a project manager or a tester. Send us an e-mail: skoumal@skoumal.net.

10 Entrepreneurship Lessons Worth Thousands of Dollars

Instead of great success we have experienced great entrepreneurship lessons (for now). It also transformed me, a person who has …

Unique Czech words reflecting coronavirus now also with English explanations as Flashcard quiz in Vocabulary Miner

Project Čestina 2.0 covering a variety of the modern Czech language with its slangs and new words has joined …

Performance of built-in higher-order functions Map, Filter, Reduce, and flatMap vs. for-in loop in Swift

The most popular higher-order functions are map, filter, and reduce. We all use them since we think that syntax …

Generate JSON key for Google Play deployment

In order to allow our CI server to deploy applications on Google Play automatically, we have to generate the JSON …

Invoice details

SKOUMAL s.r.o.
Jaurisova 515/4, Praha 4, 140 00
IČ: 035 29 151
DIČ: CZ 035 29 151

Společnost je zapsána v obchodním rejstříku vedeném Městským soudem v Praze, oddíl C, vložka 233182. Identifikátor datové schránky: qpctc9u

Praha Office

Prvního Pluku 12, Praha 8 – Karlín, 186 00
Show on map

Brno Office

Jana Babáka 11, Brno – Královo pole, 512 00
Show on map

Источник

Onbackpressed fragment android studio

28 октября 2014

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

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

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

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

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

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

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

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

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

Читайте также:  Файловый менеджер с root для андроида

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

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

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

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

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

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

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

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

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

Спасибо за статью! Очень наглядный пример как ловить 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 , отправьте его из своей деятельности и прослушайте в соответствующих фрагментах.

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

У фрагментов есть вызов метода 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, чтобы потерять фокус на спине.

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

Источник

Фрагменты

Существует два основных подхода в использовании фрагментов.

Первый способ основан на замещении родительского контейнера. Создаётся стандартная разметка и в том месте, где будут использоваться фрагменты, размещается контейнер, например, FrameLayout. В коде контейнер замещается фрагментом. При использовании подобного сценария в разметке не используется тег fragment, так как его нельзя менять динамически. Также вам придётся обновлять ActionBar, если он зависит от фрагмента. Здесь показан такой пример.

Второй вариант — используются отдельные разметки для телефонов и планшетов, которые можно разместить в разных папках ресурсов. Например, если в планшете используется двухпанельная разметка с двумя фрагментами на одной активности, мы используем эту же активность для телефона, но подключаем другую разметку, которая содержит один фрагмент. Когда нам нужно переключиться на второй фрагмент, то запускаем вторую активность.

Второй подход является наиболее гибким и в целом предпочтительным способом использования фрагментов. Активность проверяет в каком режиме (свои размеры) он запущен и использует разную разметку из ресурсов. Графически это выглядит следующим образом.

Основные классы

Сами фрагменты наследуются от androidx.fragment.app.Fragment. Существует подклассы фрагментов: ListFragment, DialogFragment, PreferenceFragment, WebViewFragment и др. Не исключено, что число классов будет увеличиваться, например, появился ещё один класс MapFragment.

Для взаимодействия между фрагментами используется класс android.app.FragmentManager — специальный менеджер по фрагментам.

Как в любом офисе, спецманагер не делает работу своими руками, а использует помощников. Например, для транзакций (добавление, удаление, замена) используется класс-помощник android.app.FragmentTransaction.

Для сравнения приведу названия классов из библиотеки совместимости:

  • android.support.v4.app.FragmentActivity
  • android.support.v4.app.Fragment
  • android.support.v4.app.FragmentManager
  • android.support.v4.app.FragmentTransaction

Как видите, разница в одном классе, который я привёл первым. Он используется вместо стандартного Activity, чтобы система поняла, что придётся работать с фрагментами. На данный момент студия создаёт проект на основе ActionBarActivity, который является подклассом FragmentActivity.

В одном приложении нельзя использовать новые фрагменты и фрагменты из библиотеки совместимости.

В 2018 году Гугл объявила фрагменты из пакета androd.app устаревшими. Заменяйте везде на версию из библиотеки совместимости. В 2020 году уже используют пакет androidx.fragment.app.

В версии Support Library 27.1.0 появились новые методы requireActivity() и requireContext(), которые пригодятся при написании кода, когда требуется наличие активности и нужно избежать ошибки на null.

Читайте также:  Ggj файл чем открыть андроид

Общий алгоритм работы с фрагментами будет следующим:

У каждого фрагмента должен быть свой класс. Класс наследуется от класса Fragment или схожих классов, о которых говорилось выше. Это похоже на создание новой активности или нового компонента.

Также, как в активности, вы создаёте различные методы типа onCreate() и т.д. Если фрагмент имеет разметку, то используется метод onCreateView() — считайте его аналогом метода setContentView(), в котором вы подключали разметку активности. При этом метод onCreateView() возвращает объект View, который является корневым элементом разметки фрагмента.

Разметку для фрагмента можно создать программно или декларативно через XML.

Создание разметки для фрагмента ничем не отличается от создания разметки для активности. Вот отрывок кода из метода onCreateView():

Глядя на этот код, вы должные понять, что фрагмент использует разметку из файла res/layout/first_fragment.xml, которая содержит кнопку с идентификатором android:id=»@+id/button_first». Здесь также прослеживается сходство с подключением компонентов в активности. Обратите внимание, что перед методом findViewById() используется view, так как этот метод относится к компоненту, а не к активности, как мы обычно делали в программах, когда просто опускали имя активности. Т.е. в нашем случае мы ищем ссылку на кнопку не среди разметки активности, а внутри разметки самого фрагмента.

Нужно помнить, что в методе inflate() последний параметр должен иметь значение false в большинстве случаев.

FragmentManager

Класс FragmentManager имеет два метода, позволяющих найти фрагмент, который связан с активностью:

findFragmentById(int id) Находит фрагмент по идентификатору findFragmentByTag(String tag) Находит фрагмент по заданному тегу

Методы транзакции

Мы уже использовали некоторые методы класса FragmentTransaction. Познакомимся с ними поближе

add() Добавляет фрагмент к активности remove() Удаляет фрагмент из активности replace() Заменяет один фрагмент на другой hide() Прячет фрагмент (делает невидимым на экране) show() Выводит скрытый фрагмент на экран detach() (API 13) Отсоединяет фрагмент от графического интерфейса, но экземпляр класса сохраняется attach() (API 13) Присоединяет фрагмент, который был отсоединён методом detach()

Методы remove(), replace(), detach(), attach() не применимы к статичным фрагментам.

Перед началом транзакции нужно получить экземпляр FragmentTransaction через метод FragmentManager.beginTransaction(). Далее вызываются различные методы для управления фрагментами.

В конце любой транзакции, которая может состоять из цепочки вышеперечисленных методов, следует вызвать метод commit().

Аргументы фрагмента

Фрагменты должны сохранять свою модульность и не должны общаться друг с другом напрямую. Если один фрагмент хочет докопаться до другого, он должен сообщить об этом своему менеджеру активности, а он уже передаст просьбу другому фрагменту. И наоборот. Это сделано специально для того, чтобы было понятно, что менеджер тут главный и он не зря зарплату получает. Есть три основных способа общения фрагмента с активностью.

  • Активность может создать фрагмент и установить аргументы для него
  • Активность может вызвать методы экземпляра фрагмента
  • Фрагмент может реализовать интерфейс, который будет использован в активности в виде слушателя

Фрагмент должен иметь только один пустой конструктор без аргументов. Но можно создать статический newInstance с аргументами через метод setArguments().

Доступ к аргументам можно получить в методе onCreate() фрагмента:

Динамически загружаем фрагмент в активность.

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

Вызываем метод в активности:

Если фрагмент должен сообщить о своих действиях активности, то следует реализовать интерфейс.

Управление стеком фрагментов

Фрагменты, как и активности, могут управляться кнопкой Back. Вы можете добавить несколько фрагментов, а потом через кнопку Back вернуться к первому фрагменту. Если в стеке не останется ни одного фрагмента, то следующее нажатие кнопки закроет активность.

Чтобы добавить транзакцию в стек, вызовите метод FragmentTransaction.addToBackStack(String) перед завершением транзакции (commit). Строковый аргумент — опциональное имя для идентификации стека или null. Класс FragmentManager имеет метод popBackStack(), возвращающий предыдущее состояние стека по этому имени.

Если вы вызовете метод addToBackStack() при удалении или замещении фрагмента, то будут вызваны методы фрагмента onPause(), onStop(), onDestroyView().

Когда пользователь нажимает на кнопку возврата, то вызываются методы фрагмента onCreateView(), onActivityCreated(), onStart() и onResume().

Рассмотрим пример реагирования на кнопку Back в фрагменте без использования стека. Активность имеет метод onBackPressed(), который реагирует на нажатие кнопки. Мы можем в этом методе сослаться на нужный фрагмент и вызвать метод фрагмента.

Теперь в классе фрагмента прописываем метод с нужным кодом.

Более желательным вариантом является использование интерфейсов. В некоторых примерах с фрагментами такой приём используется.

Интеграция Action Bar/Options Menu

Фрагменты могут добавлять свои элементы в панель действий или меню активности. Сначала вы должны вызвать метод Fragment.setHasOptionsMenu() в методе фрагмента onCreate(). Затем нужно задать настройки для методов фрагмента onCreateOptionsMenu() и onOptionsItemSelected(), а также при необходимости для методов onPrepareOptionsMenu(), onOptionsMenuClosed(), onDestroyOptionsMenu(). Работа методов фрагмента ничем не отличается от аналогичных методов для активности.

В активности, которая содержит фрагмент, данные методы автоматически сработают.

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

Код для активности:

Код для фрагмента:

Связь между фрагментом и активностью

Экземпляр фрагмента связан с активностью. Активность может вызывать методы фрагмента через ссылку на объект фрагмента. Доступ к фрагменту можно получить через методы findFragmentById() или findFragmentByTag().

Источник

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