Как очистить backstack в android
Очистить задний стек с помощью фрагментов
я портировал свое приложение для Android на honeycomb, и я сделал большой рефакторинг, чтобы использовать фрагменты. В моей предыдущей версии, когда я нажал кнопку Home я использовал, чтобы сделать ACTIVITY_CLEAR_TOP для того, чтобы сбросить резервную стопку.
Теперь мое приложение-это всего лишь одно действие с несколькими фрагментами, поэтому, когда я нажимаю кнопку Home, я просто заменяю один из фрагментов внутри него. Как я могу очистить свой задний стек без использования startActivity С ACTIVITY_CLEAR_TOP флаг?
12 ответов:
из ответа Иоахима, от Диана Hackborn:
Я закончил тем, что просто использовал:
но мог бы также использовать что-то вроде:
который выведет все состояния до названного. Затем вы можете просто заменить фрагмент на то, что вы хотите
чтобы сделать ответ на комментарий @Warpzit и сделать его легче для других, чтобы найти.
при всем уважении ко всем вовлеченным сторонам; я очень удивлен, увидев, как многие из вас могут очистить весь фрагмент обратно стека с помощью простого
Если null, только верхнее состояние выскочил
Теперь, я понимаю, что мне не хватает знаний о ваших конкретных реализации (например, сколько записей у вас есть в заднем стеке в данный момент времени), но я бы поставил все свои деньги на принятый ответ, ожидая четко определенного поведения на более широком диапазоне устройств и поставщиков:
(для справки, что-то вместе с этим)
принятого ответа мне было недостаточно. Я должен был использовать:
работает для меня и простой способ без использования цикла:
очистить backstack без петель
здесь имя является параметром addToBackStack ()
выскакивая из backstack, используя следующие
Это просто удаление фрагментов из транзакции, ни в коем случае он не собирается удалять фрагмент с экрана. Так что в идеале он может быть не виден вам, но может быть два или три фрагмента сложены друг на друга,а при нажатии клавиши «Назад» пользовательский интерфейс может выглядеть загроможденным, сложенным.
просто простой пример:-
Предположим, у вас есть fragmentA, который загружает фрагмента B, используя fragmentmanager.заменить() и затем мы делаем addToBackStack, чтобы сохранить эту транзакцию. Таким образом, поток:—
теперь вы выполняете некоторую работу в fragmentB и нажимаете кнопку Save-которая после сохранения должна вернуться к fragmentA.
Так что даже если мы очистим backstack вышеуказанными методами, транзакция будет очищена, но не фактические фрагменты. Так что в идеале в таком конкретном случае, при нажатии кнопки save вам просто нужно вернуться к fragmentA, просто сделав fm.popBackStack () или fm.popBackImmediate ().
чтение документация и изучая, что такое идентификатор фрагмента, он кажется просто индексом стека, поэтому это работает:
предостережение: хотя вышеизложенное работает в моей программе, я немного сомневаюсь, потому что документация FragmentManager никогда не утверждает, что идентификатор является индексом стека. Это имеет смысл, что это будет, и все мои отладки бревна обнажают, что это такое, но, возможно, в каких-то особых обстоятельствах этого не будет? Может ли кто-нибудь подтвердить это так или иначе? Если это так, то это лучшее решение. Если нет, то это вариант:
просто используйте этот метод и передайте тег Context & Fragment, до которого нам нужно удалить фрагменты backstake.
использование
Clear back stack using fragments
I ported my Android app to honeycomb and I did a big refactor in order to use fragments. In my previous version, when I pressed the Home button I used to do a ACTIVITY_CLEAR_TOP in order to reset the back stack.
Now my app is just a single Activity with multiple fragments, so when I press the Home button I just replace one of the fragments inside it. How can I clear my back stack without having to use startActivity with the ACTIVITY_CLEAR_TOP flag?
15 Answers 15
From Joachim’s answer, from Dianne Hackborn:
I ended up just using:
But could equally have used something like:
Which will pop all states up to the named one. You can then just replace the fragment with what you want
To make an answer for @Warpzit’s comment and make it easier for others to find.
With all due respect to all involved parties; I’m very surprised to see how many of you could clear the entire fragment back stack with a simple
If null, only the top state is popped
Now, I do realize that I’m lacking knowledge of your particular implementations (like how many entries you have in the back stack at the given point in time), but I would bet all my money on the accepted answer when expecting a well defined behaviour over a wider range of devices and vendors:
(for reference, something along with this)
Works for me and easy way without using loop:
Clear backstack without loops
Where name is the addToBackStack() parameter
Accepted answer was not enough for me. I had to use :
I found a solution which is much better,from: https://gist.github.com/ikew0ng/8297033
I just wanted to add :—
Popping out from backstack using following
is just about removing the fragments from the transaction, no way it is going to remove the fragment from the screen. So ideally, it may not be visible to you but there may be two or three fragments stacked over each other, and on back key press the UI may look cluttered,stacked.
Just taking a simple example:-
Suppose you have a fragmentA which loads Fragmnet B using fragmentmanager.replace() and then we do addToBackStack, to save this transaction. So the flow is :—
Now You do some work in fragmentB and press the Save button—which after saving should go back to fragmentA.
STEP 2-> On save of FragmentB, we go back to FragmentA.
How to clear navigation Stack after navigating to another fragment in Android
I am using The new Navigation Architecture Component in android and I am stuck in clearing the navigation stack after moving to a new fragment.
Example: I am in the loginFragment and I want this fragment to be cleared from the stack when I navigate to the home fragment so that the user will not be returned back to the loginFragment when he presses the back button.
I tried using the NavOptions in the navigate(), but the back button is still sending me back to the loginFragment
14 Answers 14
First, add attributes app:popUpTo=’your_nav_graph_id’ and app:popUpToInclusive=»true» to the action tag.
Second, navigate to the destination, using above action as parameter.
See the docs for more information.
I think your question specifically pertains on how to use the Pop Behavior / Pop To / app:popUpTo (in xml)
In documentation,
Pop up to a given destination before navigating. This pops all non-matching destinations from the back stack until this destination is found.
Example (Simple Job hunting app)
my start_screen_nav graph is like this:
if I want to navigate to EmployerMainFragment and pop all including startScreenFragment then the code will be:
if I want to navigate to EmployerMainFragment and pop all excluding startScreenFragment then the code will be:
if I want to navigate to EmployerMainFragment and pop loginFragment but not startScreenFragment then the code will be:
Как очистить стек навигации после перехода к другому фрагменту в Android
Я использую новый компонент архитектуры навигации в android, и я застрял в очистке стека навигации после перехода к новому фрагменту.
Пример: я нахожусь в loginFragment и хочу, чтобы этот фрагмент был очищен из стека, когда я перехожу к домашнему фрагменту, чтобы пользователь не возвращался обратно в loginFragment, когда он нажимает кнопку «Назад».
Сначала добавьте атрибуты app:popUpTo=’your_nav_graph_id’ и app:popUpToInclusive=»true» в тег действия.
Во-вторых, перейдите к месту назначения, используя указанное выше действие в качестве параметра.
Я думаю, ваш вопрос конкретно касается того, как использовать Pop Behavior / Pop To / app: popUpTo (в xml)
В документации
всплывающее окно до указанного пункта назначения перед навигацией. Это выталкивает все несовпадающие места назначения из заднего стека, пока это место назначения не будет найдено.
Пример (простое приложение для поиска вакансий)
мой график start_screen_nav выглядит следующим образом:
если я хочу перейти EmployerMainFragment и вывести все, включая, startScreenFragment тогда код будет:
если я хочу перейти EmployerMainFragment и вывести все, исключая, startScreenFragment тогда код будет:
если я хочу перейти EmployerMainFragment и открыть, loginFragment но не startScreenFragment тогда, код будет:
В моем случае мне нужно было удалить все из заднего стека, прежде чем я открою новый фрагмент, поэтому я использовал этот код
первая строка удаляет задний стек, пока он не достигнет фрагмента, указанного в моем случае, это домашний фрагмент, поэтому он полностью удаляет весь задний стек, и когда пользователь щелкает обратно в fragment_company, он закрывает приложение.
ПРИМЕЧАНИЕ. Очистить задачу устарело, официальное описание
Этот метод устарел. Используйте setPopUpTo (int, boolean) с идентификатором графа NavController и установите для него значение true.
Старый ответ
Если вы не хотите пройти через весь этот пух в коде, вы можете просто проверить Clear Task в Launch Options в свойствах действия.
Tasks и Back Stack в Android
Итак. Каждое Android приложение, как минимум, состоит из фундаментальных объектов системы — Activity. Activity — это отдельный экран который имеет свою отдельную логику и UI. Количество Activity в приложении бывает разное, от одного до много. При переходах между различными Activity пользователь всегда может вернуться на предыдущую, закрытую Activity при нажатии кнопки back на устройстве. Подобная логика реализована с помощью стека (Activity Stack). Его организация «last in, first out» — т.е. последний вошел, первый вышел. При открытии новой Activity она становится вершиной, а предыдущая уходит в режим stop. Стек не может перемешиваться, он имеет возможность добавления на вершину новой Activity и удаление верхней текущей. Одна и та же Activity может находиться в стеке, сколько угодно раз.
Task — это набор Activity. Каждый таск содержит свой стек. В стандартной ситуации, каждое приложение имеет свой таск и свой стек. При сворачивании приложения, таск уходит в background, но не умирает. Он хранит весь свой стек и при очередном открытии приложения через менеджер или через launcher, существующий таск восстановится и продолжит свою работу.
Ниже покажу картинку, как работает стек.
Если продолжать нажимать кнопку back, то стек будет удалять Activity до того, пока не останется главная корневая. Если же на ней пользователь нажмет back, приложение закроется и таск умрет. Кстати, я говорил о том, что когда мы сворачиваем наше приложение и запускам например новое, то наш таск просто уходит в background и будет ждать момента, пока мы его вызовем. На самом деле есть одно «но». Если мы будем иметь много задач в background или же просто сильно нагружать свое устройство, не мала вероятность того, что таск умрет из за нехватки системных ресурсов. Это не война конечно, но то что мы потеряем все наши текущие данные и наш стек очистится — это точно. Кстати для избежания потери данных в таком случаи, вам стоит почитать про SavingActivityState.
Маленький итог
Управление тасками
Существует два пути для изменения стандартной организации тасков. Мы можем устанавливать специальные атрибуты в манифесте для каждой Activity. Также мы можем устанавливать специальные флаги для Intent, который запускает новую Activity с помощью startActivity(). Заметьте, что иногда атрибуты в манифесте и флаги в Intent могут противоречить друг другу. В этом случаи флаги Intent будут более приоритетны.
Атрибут launchMode
Флаги
Affinity
Стандартно все Activity нашего приложения работают в одном таске. По желанию мы можем изменять такое поведение и указывать, чтобы в одном приложении Activity работали в разных тасках, или Activity разных приложений работали в одном. Для этого мы можем в манифесте для каждой Activity указывать название таска параметром taskAffinity. Это строковое значение, которое не должно совпадать с названием package, т.к. стандартный таск приложения называется именно как наш пакет. В общем случаи данный параметр указывает, что Activity будет гарантированно открываться в своём отдельном таске. Данный параметр актуален, если мы указываем флаг FLAG_ACTIVITY_NEW_TASK или устанавливаем для Activity атрибут allowTaskReparenting=«true». Этот атрибут указывает, что Activity может перемещаться между тасками, который её запустил и таском, который указан в taskAffinity, если один из них становится активным.
Чистка стека
Это всё для данного топика. Статья не импровизированная, а по сути является вольным переводом официальной документации. Рекомендую собрать легкий пример и поэксперементировать с флагами и атрибутами. Некоторые моменты, лично для меня были, неожиданно интересными. любые ошибки и недоработки учту в лс. Спасибо.


