Fragment transactions, actionbar & backstack - android

In my main activity, I have an actionbar with NAVIGATION_MODE_TABS. The contents of each tab is a listfragment.
I'd like to make it so that that when a listitem is clicked, a new fragment is brought into view, and the actionbar mode is changed to NAVIGATION_MODE_STANDARD (so that the tabs are now hidden).
I've managed to get this to work with the following code:
In the listitemclick method:
ActionBar actionBar = getActivity().getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
Fragment albumListFragment = new AlbumListFragment();
albumListFragment.setArguments(bundle);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(android.R.id.content, albumListFragment);
ft.addToBackStack(null);
// Commit the transaction
ft.commit();
Log.i("FragmentList", "Item clicked: " + id);
The problem is when I press the back button, the tabs are still gone, and the previous fragment doesn't come back into view.
Am I doing something wrong.. Is it something to do with the fragment backstack? Should I go about it another way, or even override the backpress?
--Edit--
For clarity - I am calling addToBackStack when I call fragmenttransaction.replace, but when I press the back button, the previous fragment is not restored.

Maybe this is a little late, I tried to re-construct your problem for hours but didnot succeed. I tried to switch from a listview in a fragment hosted by a ActionBar Tab to another view by the way described in your question(i.e. ft.replace(android.R.id.content, albumListFragment);) but with no effect. After some google and stackoverflow, I use this way to successfully switch the fragment within the tab, yet with no problem as you have.
As the "action bar is not showing correctly" problem, its probably caused by the backstack revert and UI change as describe in android developer guide. you might try to override the onBackStackChanged() callback and re-construct the UI.
As the "backstack does not bring the previous fragment back" problem, you may want to post a little more code to help others re-construct the problem to find the answer.
Wish helpful.

I experienced exactly the same issue and figured it out that the problem only occurs when you set the ActionBar back to NAVIGATION_MODE_STANDARD.
The only solution for me was to place the new fragment with no tabs in a helper activity which has NAVIGATION_MODE_STANDARD. Then you can easily use the back button functionality provided by Android to go back to the activity with NAVIGATION_MODE_TABS and retain its state.

FragmentTransaction.replace() actually removes the previous fragment in the layout and add new instance of the fragment.
Try using FragmentTransaction#show() and FragmentTransaction#hide() methods instead of replace.

The backstack ends the current activity and goes to the previous activity, not the previous fragment. (See the backstack guide: http://developer.android.com/guide/components/tasks-and-back-stack.html).
You could force, as you suggested, the behavior by overriding onBackPressed, however, I don't know that I would change the natural Android behavior in such a way. If you look at other apps, particularly core apps, that do similar things the back button does not go to a previous fragment, but a previous activity.
Also you do have total control on the behavior of the "up" button (that is your app icon on the action bar with a left arrow). You have to programatically set it up to be used as a button as described in the ActionBar guide (let me know if you need to know how to do this) and with that you could have it set up a previous fragment on a stack that you maintain somewhere.

Related

Hot to navigate to home fragment from another fragment

I am new to Android programming though I am coding in another languages. I am not able to navigate to home fragment in a particular scenario.
I have three fragments among few more viz., Settings, Capacity and About. All these can be reached via Overflow Toolbar menu items. Settings can be reached thru another button on home fragment.
Use case 1: Click Settings button on home fragment. Settings open. In Settings use either Up/Home or Back Button. On clicking any one of them, home fragment is reached.
Use case 2: Click Toolbar overflow menu(three dots). Three menu item appears. Select Settings menu item. Settings Open. In Settings, use either Up/Home or Back Button. On clicking any one of them, home fragment is reached.
Use Case 1 is working fine. I think nav_graph defined is used here where navigation between fragments is defined.
Use Case 2 fails. Upon pressing Up/Home button or Back button, I get white screen rather landing on home fragment.
I studied code in several websites including SO and official Android site. But could not make out what kind of code to be used when navigating back to home fragment from another fragment(which was particularly reached via Toolbar menu and outside of nav_graph).
I studied methods in stack in debug window. But did not help me either.
Please enlighten me the approach to be used.
First set Home Fragment in content view(frame view).
on top you can your next fragment kinda stack of fragments 1 above another.
create method in activity this method will popout all fragments except Home Fragment.
Add Fragment use below code
Fragment fragment = new FragmentHome();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame,fragment).addToBackStack(fragment.getClass().getSimpleName()).commit();
To go Home clearing all
public void goToHome()
{
FragmentManager fragmentManager = getSupportFragmentManager();
for(int i = 0; i < fragmentManager.getBackStackEntryCount()-1; ++i)
{
fragmentManager.popBackStack();
}
}
I continued searching for solution to my problem. I came across a solution in https://medium.com/mobile-app-development-publication/learn-android-navigation-component-through-coding-79dc47b240b3 It worked perfectly well and solved white screen issue and also not using explicit method using fragment manager for traversing to another fragment. It was about linking menu items to navigation graph.

Go to a specific fragment from anywhere keeping backstack

I'm updating the old navigation system from my app to jetpack navigation and I'm facing an issue:
From a DialogFragment which can be displayed from almost any fragment in the app, I have a button which leads to a specific Fragment. I've found in the documentation global actions, but it seems they clear the entire navigation backstack when you navigate with one of these and I need to keep my backstack, just add this new fragment to it from anywhere. What's the solution to this problem ?
Thanks

How do I exit a fragment and return to my drawer activity using the back button?

I'm trying to make an app which has the DrawerActivity as the main activity. I have implemented 8 fragments within it, which correspond to each item in the drawer. Now, the problem I have is, whenever I try to press the back button to go back to the DrawerActivity from the fragment, I end up exiting the app instead. I've been searching on forums for three days now, and have not found any solution to this. Quite frustrated, I stupidly deleted my code, so I can't really show it right now. Can anyone simply explain to me how I should exit a fragment using the back button, and return to my main activity?
Current scenario:
DrawerActivity contains eight fragments, all independent of each other. Let's call them fragments A through H. When I go to fragment A, I should be able to open the navigationDrawer and head to any other fragments from B to H. However, on pressing the back button, I should also be able to go back to the drawer activity's main page.
Things I have tried which didn't work are
1. Using onBackPressed and popBackStack.
2. Creating custom listener.
3. Using fragmentTransaction.
I can't believe how stupid I am. I was using my Gmail app on my phone when I suddenly realized that the first fragment in the drawer activity is always the default fragment, and the app should always revert to it on the back button press. What I was thinking was that the drawer activity would go back to the original state when back is pressed, but I didn't account for the fact that fragments are part of the activity itself.
Thank you all for trying to understand my problem, which wasn't really a problem at all... It seems I learned something in spite of myself.
Have you tried overriding onBackPressed() without calling the superclass method? (So that you prevent finish() from being called.)
#Override
public void onBackPressed() {
//show Fragment A
}
Call it without the "super.onBackPressed()" and it should work.
You must add your fragment to the android back Stack like this:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.your_container,fragment,fragment.TAG)
.addToBackStack(null)
.commit();

How to know if all fragments were detached?

On my app I am using a Main Activity, which has a Navigation Drawer, and as the user go to an options from the drawer, it will change the fragment beging displayed accordingly to the option selected.
If the user hit's "Back button" several times, it will go back to a point in which it will reach my Main Activity, which is a blank and empty layout.
When I reach this point (my main activit, empty), I would like to exit the app, or, open the Navigation Drawer.
The problem is, I don't know any event that shows me that I am back to the Main Activity. I checked the onResume, but it's never called, which makes sense, since the main activity has never been stopped.
I thought perhaps there would be an event from the fragment manager that would be called on the Main Activity when a fragment was detached, and from there I could check if there was no fragment at all attached?
When you push your first fragment, add a tag to it. Something like
transaction.replace( R.id.rootContainer, firstFragment, "rootFragment");
Whenever user presses back button, you can get your rootFragment from FragmentManager
FirstFragment myFragment = (FirstFragment) getSupportFragmentManager().findFragmentByTag("rootFragment");
And check if this fragment is visible or not, by myFragment.isVisible(), if not, then keep popping the stack, if it is visible, it means user is on the first fragment. Now you can either quit the app, or show your menu drawer.
Good night good sir. Thank you for your tip.
I used a different approach, based on your repply, that gave me quite a few insights.
On main activity, I Overrided the onKeyDown and check if it was pressed the Back Button. If yes, then I check the size of my Back Stack.
Uppon that, I decide if I want to finish my application.
Also, thanks for the tip of "labeling" the fragments on the back stack, didn't know I could do that.

Android - Navigate back to tabbed fragment

My Action bar consists of two tabs (a list of businesses and a map of businesses). If someone chooses from the list I would like to hide the tabs and show that business' page. If the user hits back, the business fragment is popped and the tabs should be displayed again.
What is the best approach to get this working? So far with the following code I have an inexplicable recursive loop if I pop the business fragment :(
So picture this, I'm displaying the BusinessListFragment tab. I choose a business, swap fragments and in onPause() I set the navigation mode to standard. Hit the back key, and in the onResume() of the BusinessListFragment I have this:
ActionBar ab = mHostingActivity.getSupportActionBar();
if (ab.getNavigationMode() == ActionBar.NAVIGATION_MODE_STANDARD)
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Which is supposed to bring back the tabs, but the app freezes with a loop. The tabs are definitely still present. Maybe I'm doing something else strange in my code (I'm sure I'm not though), or maybe Android does something strange when the naviagtion mode is set?
Edit: I've learnt that simply setting the navigation mode to tabs seems to actually select the first tab - which I believe would explain the recursion. Interesting!
Okay well this took a while to figure out but hopefully this will help future googlers :D
It seems the best practice is to never try and hide / show tabs by setting the navigation mode from within a tab fragment's onResume / onPause, or anywhere within it for that matter.
I therefore set the mode to Standard in the onResume() of the detail (business) fragment. Normally if there are no more hierarchical layers of navigation to traverse from within the detail fragment, it is fine to simply set the mode back to Tabs in the detail fragment's onPause() - accounting for back presses or up presses.
However in my case you can click on elements within the business page to launch another fragment (leaving a stack count of 3), meaning I cannot 'turn on' tabs within onPause(), and found the best solution was to do it within onDetach(). This should mean the tabs are only turned on when the detail fragment is actually popped from the stack.
Hopefully this solution is accurate, I have toyed with many ideas including back stack listeners and overriding onBackPressed, but for me this seems to be the best option.

Categories

Resources