Prevent DialogFragment 'A' reappearing when selection made on DialogFragment 'B' - android

I have a DialogFragment, call it A, which presents an option that leads to a second DialogFragment, B, being displayed. B provides further options.
The functionality I require is as follows:
Making a selection in A leads to B being displayed (as stated above).
If the user hits back while B is being displayed, A should be resumed into view.
If the user makes a selection in B, then B should dismiss and A should not reappear.
In A, inside an onItemClick() handler I cause B to appear using:
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.remove(DialogFragmentA.this);
transaction.addToBackStack("transaction_label");
DialogFragmentB dialogFragment = DialogFragmentB.newInstance( ...some args here...);
dialogFragment.show(transaction, "frag_B");
I call .addToBackStack() as I understand this will cause the back key to pop and reverse the transaction. That is, replace B with A again.
So far, requirements 1 and 2 are met.
B makes use of AlertDialog.Builder. A positive button is used with listener. When that positive button is pressed, I want requirement 3 to be met. That is, B should dismiss and A should not reappear. But what actually happens is A appears again.
I am assuming here that within the implementation of AlertDialog's positive button is a call to dismiss() which causes the back stack to be popped, resulting in A appearing again. Is this the case?
What I have tried to do is, within the positive button's onClick(), is to obtain the FragmentManager and call .popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE). But this has no apparent effect; A continues to appear. Using popBackStackImmediate() has no effect either.
Is this perhaps because the event loop has already somehow committed to popping the back stack by the time the positive button listener's onClick() executes?
I'd be grateful for an explanation for what is occurring and how I can make it work as intended.

I think I have nailed it, helped by the question and answer here.
The key point is that the sequence of transactions is nothing -> A -> B. I want to pop the back stack to the point where I have nothing. Therefore, as well as calling .addToBackStack() for the A -> B transaction, I also need to call .addToBackStack() for the nothing -> A transaction. Then, all of those transactions can be popped off the back stack again to get back to the point of nothing: The first pop does B -> A, then the next pop does A -> nothing.
For both transactions I am now calling .addToBackStack("some_transaction"). In B's positive onClick(), I call manager.popBackStack("some_transaction", FragmentManager.POP_BACK_STACK_INCLUSIVE);. I might rethink the tags I'm giving to the transactions, but this is now working as I want it to.
So the basic point seems to be that, if you want it to be possible to go back to a DialogFragment but also go back to the point where that DialogFragment wasn't shown at all, you have to add the transaction that put it there in the first place onto the back stack, so you can pop back to that point.
I previously thought it would be possible to achieve what I wanted by only adding the A -> B transaction to the back stack, and then somehow completely purging (rather than popping) the back stack to prevent A appearing again once a selection had been made in B. But it seems that there is no way to actually 'purge' the back stack; you can only pop and reverse the transactions.

Related

Make FragmentTransaction From Activity Started From Fragment

So right now I have a situation in which I have three fragments are committed in such an order:
Fragment A -> Fragment B -> Fragment C
Then, I start an Activity from Fragment C. The issue arises when I want to pop the back stack so the user is brought to Fragment B after the activity finishes. If I attempt to pop the back stack from the Activity before calling finish(), I get an IllegalStateException, saying that the action cannot be performed after onSaveInstanceState. Thus, is it even possible to make changes to the FragmentManager responsible for the fragments from the Activity?
How does this sound myrocks2? Android: how to make an activity return results to the activity which calls it?
First activity can start a second activity and expect a result. Upon getting back a result it knows second activity did its job, and now it's required to remove fragment c. (I don't know the logic of your app, but that can work)
Someone who thinks he is so smart gave you a negative vote, but I made sure to go away. There are no dumb questions.

Handle back pressed of multiple fragments in android

Hi Currently am developing application using fragments.Totally i have 15 fragments and loaded it in single Activity.While onBack Pressing on Each fragment will launch previous fragment.I google about it and also i got answers for it.but i just want to know which is more efficient way handle this.
By calling addToBackStack(), the replace transaction is saved to the back stack so the user can reverse the transaction and bring back the previous fragment by pressing the Back button. Reference
If you add multiple changes to the transaction (such as another add() or remove()) and call addToBackStack(), then all changes applied before you call commit() are added to the back stack as a single transaction and the Back button will reverse them all together.
Just add this transaction.addToBackStack(null);
For more information you may visit Handling back button press Inside Fragments

Android show back button depending on backstack count

I want to show or hide the back button of the action bar depending on the current backstack entry count. That means I want to show it when there is a fragment (or more) in the backstack, and hide when backstack is empty
getSupportActionBar().setDisplayHomeAsUpEnabled(b);
The problem is, when I start a new fragment and ask for the current backstack entry count, it's still the same like before. It refreshes after some milliseconds.
Also in the started fragment's onResume method, the replaced fragment still can not be found in backstack, backstack count is still the same.
Currently I have an AsyncTask that refreshes the button after 50 milliseconds. Working, but this can't be a good solution.
Any ideas?
Best regards
Edit:
Solution was
fragmentManager.addOnBackStackChangedListener(...)
There is no need for AsyncTask you already have a Backstack interface that triggers when a Fragment is being added or removed onBackStackChangeListener so instead of your call implement that and call getBackstackEntryCount() if its not 0 then you know what you will do
hen I start a new fragment and ask for the current backstack entry count, it's still the same like before
you need to add your transaction to the Backstack after your add() or replace() calls on your FragmentTransaction like this .addToBackstack("the identifier")
some indirect post
Hope it helps

How to avoid multiple instances of a fragment in back stack?

I want to avoid that in this navigation use case: A -> B -> A -> B -> A -> B ...
Where all the fragment instances are kept in the back stack. Reason: Avoid out of memory error.
I tried creating an own navigation workflow, like described here: https://stackoverflow.com/questions/18041583/fragments-backstack-issue?noredirect=1#comment26393904_18041583 (which is supposed to mimic activity behaviour calling always finish() after starting a new one, together with letting only the very first one (home) in the navigation stack).
But it seems to be either very wrong or ununderstandable.
So I thought, also, to implement a behaviour like activity "bring to front" flag. But I don't know how to do it. Maybe something with popBackStack - but I don't know how to ask the fragment if the transaction already is in the backstack. And I don't know if I'm on the right path.
This should be a quite standard task, since every navigation menu basically has this problem. But still, seems not to be straight forward to implement, and also can't find information about it.
Any idea?
Take a look at the FragmentManager backstack. It has facilities for looking at/popping entries in the fragment backstack. You might want logic something along the lines of: if the user is asking for a fragment that is at the top of the stack (the previous fragment) then exit this fragment (go back) otherwise start a new one.
That would produce:
A (user asks for B)
A->B (user asks for A again)
A
.. but would not prevent
A (user asks for B)
A->B (user asks for C)
A->B->C (user asks for A)
A->B->C->A
That would require rewinding the stack back to "A" from "C", which you can do.. but then if that is the case, perhaps you should be unconditionally popping the fragment stack before starting a new fragment (I.E. No back stack at all..)

Manually Access Android Back Stack

I'm having problems coming up with a solution to this problem.
Basically I have a load of tabs in my ActionBar. When each is touched the fragments from the previous tab are detached and the fragments for the new tab are added using replace (if they haven't been instantiated yet) or attached (if they have). I think I got this method from Google and it was working fine until now.
Example of adding a tab's fragments:
if(tab.getText().equals(context.getString(R.string.title_class_tab))) {
if(browser == null) {
browser = CourseBrowserFragment.newInstance(false);
fragmentTransaction.replace(leftContainerId, browser);
} else {
fragmentTransaction.attach(browser);
}
if(lessonViewer == null) {
lessonViewer = LessonViewerFragment.newInstance(false);
fragmentTransaction.replace(rightContainerId, lessonViewer);
} else {
fragmentTransaction.attach(lessonViewer);
}
}
and removing:
if(tab.getText().equals(context.getString(R.string.title_class_tab))) {
if(browser != null) {
fragmentTransaction.detach(browser);
}
if(lessonViewer != null) {
fragmentTransaction.detach(lessonViewer);
}
}
The problem arises from the layout I need for one of the tabs. Basically it's like the Gmail app. There are two fragments (let's say Panel A and Panel B) and when you push a button Panel A slides out, Panel B slides to Panel A's old position and a new, third one (Panel C) slides in from the right.
I had this working fine but now I've added the sliding-in FragmentTransaction to the back stack so that the user can touch the back button and Panel C will slide back out and Panel A will come back. Again, like Gmail.
Except when the user goes to a different tab this transaction is still on the back stack and executes if the user presses back. The fragments end up in crazy places. What I need to do is remove it from the back stack when the user navigates to a different tab. Is there any way I can do this? FragmentManager doesn't seem to let you manually remove things from the back stack and using the popBackStack() method doesn't just remove the transaction, it executes it. I want to remove it when the user navigates away and put it back when the user returns.
I think I can get a hold of the "Back Stack Entry" for this transaction using "getBackStackEntryAt" but it's not much good if I can't remove it and put it back in place when the user comes back to the tab.
The only possible solution I can think of is not using the back stack and overriding onBackButtonPressed instead. From there I could just do a reverse of the transaction if necessary.
Thanks for any help and sorry if I'm being incoherent.
Not sure if this would qualify as a solution but I ended up just not adding the transaction to the back stack and just doing a fresh transaction when the user swiped or pressed back. The transaction just did the reverse of the original one with animations etc.
The way I managed the back button is I set a boolean to true if I was in the layout showing Panel C. If the user swipes back into the Panel A layout or navigates away the boolean is set to false. I then overrode the onBackButtonPressed method in the Activity and if the boolean was true (ie: we're in the Panel C layout) I run that reverse transaction otherwise I just call super.onBackButtonPressed() (ie: perform standard back button behaviour).

Categories

Resources