I have got a problem regarding android fragments. I have 3 fragments say A, B and C. From A I move to B and I have an if statement that checks a value from shared preferences if value exists it move to C. If i press back button on Fragment C, it navigates to Fragment A but fragment C is also visible in background. Don`t know how to fix it. I have tried almost every solution from SO questions.
Here is my code
In fragment A on button click
Fragment fragment = new MyAccount();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).addToBackStack(null)
.commit();
In fragment B
if(RegDetails.contains("MSISDN")&&RegDetails.contains("PIN")){
Fragment fragment = new ReferFriend();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment)
.commit();
}
From B it move to c and works fine. But when I click back button on C fragment A is visible but fragment C is also visible in background.
I see two options:
Add a solid background (color) to your A-fragment's root view
Use .show() and .hide()
Related
I have a problem with my fragments. I use this code to navigate between the fragments:
Between the "main" fragments (without backstack, because I want the user to exit when he presses back (it works)):
FragmentManager fragmentManager = getFragmentManager();
final FragmentTransaction ft = fragmentManager.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_up_honeycomb, R.anim.slide_out_up_honeycomb);
ft.replace(R.id.container, NewsFragment.newInstance(position + 1), NewsFragment.class.getSimpleName());
ft.commit();
and between the "inner" fragments (with backstack):
FragmentTransaction ft = ((Activity) getActivity()).getFragmentManager().beginTransaction();
Fragment nextFragment = LexikonDetailFragment
.newInstance(item);
ft.setCustomAnimations(R.anim.slide_in_up_honeycomb, R.anim.slide_out_up_honeycomb);
ft.replace(R.id.container, nextFragment);
ft.addToBackStack(LexikonDetailFragment.class.getSimpleName());
ft.commit();
But in the following case:
fragment A -> fragment A1
fragment A1 -> fragment B
Press back button (should end the app)
-> goes back to fragment A1
happens:
Image
It looks like the A1 fragment doesnt gets removed from the backstack and stays in the background. I thought one possible solution could be to set to all fragments a white background..but this wouldn't fix the problem, it would just hide it. So what could be a possible solution?
Okay, i found a solution:
I had to remove the inner fragments manualy via the command:
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
I call this command each time my "outer" fragment changes. The inner ones get removed and tada...it works like a charm :)
I have 4 Fragments A B C D.
how to use back stack and how to set fragments?
I want to add just Fragment A to stack and when I press back button from B C or D, I want to to set fragment A.
I dont want B C and D in back stack
Normally in your FragmentTransaction you should call addToBackstack(null) to add it into backstack.
The backstack is actually a stack where you pop a Fragment when user presses back.
So if A puts B, B puts C and C puts D; you cannot go from D to A directly.
You can override onBackPressed() and control the behavior yourself without using the Fragment's builtin back stack support.
You can popbackstack to clear any fragments in history and ad to backstack fragment A like so :
//create an instance of the fragment you want o be avilable on back press
FragmentA fragmentA = new FragmentA();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//Create instance of the fragment that is going to be loaded
FragmentD fragmentD = new FragmentD();
//Replace the current fragment with Fragment D
fragmentTransaction.replace(R.id.frame_container, fragmentD);
//Clear frgament history and include the fragment wanted on back press
fragmentManager.popBackStack();
fragmentTransaction.addToBackStack(fragmentA.getclass().getName());
fragmentTransaction.commit();
I have two fragments, A and B. Before, A and B were both top level and when I wanted to move from one to the other, I would use something like
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, BFragment.newInstance(), B_TAG)
.disallowAddToBackStack()
.commit();
Now the client wants that from B, hitting the back button, the app goes to A, so I needed to make B a child of A and therefore the transition looks like
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.container, BFragment.newInstance(), B_TAG)
.addToBackStack(null)
.commit();
and from B to A
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.executePendingTransactions();
fragmentManager.popBackStack();
fragmentManager.executePendingTransactions();
The problem is that if the user changes something in B, A still has the old data.
Is there a way of knowing that I arrived at A by clicking the "back" button and poping it from the backstack so I can refresh the data?
Also, do you see a better way of handling the movement between these two fragments?
I would store the common data either:
In a singleton that handles persistent state in the application if that data can be of interest withing the whole application
In a data fragment (a fragment without any UI) that each of your UI fragments can access and change the data.
Then in each UI fragment, you can update the views when resuming the fragments.
I've been working with fragments for a while now, but I regularly encounter a problem that just annoys me. Fragments remain drawn over each other some times. Now, I managed to isolate one use case for this, and it goes like this:
Add Fragment A (also use addToBackStack with a name "backstack_state")
Replace Fragment A with Fragment B (use addToBackStack)
Replace Fragment B with Fragment C WITHOUT using addToBackStack
at a given point use popBackStack("backstack_state", 0) and here comes the issue:
The backstack is popped until Fragment A but Fragment C is overlaid with Fragment A, both are visible at the same time. Is this normal behavior or is it me who makes a mistake?
Here's a remark also: all the fragments have transparent background.
Thanks!
This happens because the top fragment (in this case Fragment C) is not removed. You have to remove it first inside a fragment transaction. Try this:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment topFragment = fragmentManager.findFragmentById(R.id.fragment_container);
if (topFragment != null) {
fragmentTransaction.remove(topFragment);
}
fragmentTransaction.commit();
fragmentManager.popBackStack("backstack_state", 0);
When click the items of NavigationDrawer,The main activity container switch the fragments to show,It worked fine until I met this:
1.Switched to FragmentA, which CONTAINS A VIEWPAGER,it showed well.
2.Switched to fragmentB,fragmentB showed well.
3.Swiched back to
FragmentA,it shows as a Blank View
I tried to flip horizontally on it,I can see the viewpager index do changed(in log),But I don't know why it showed as a blank page.
*and,if fragmentA dose not contains viewpager,it worked well
Any suggestion would be appreciated.
I use replace() to switch between the fragments:
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, currentFragment)
.commit();
Possible reason might be not using replace transaction instead you mightbe adding fragments and adding it to backstack. Try using replace transaction, and see if it works.
Fragment1 firstFragment = new Fragment1();
Bundle bundle = new Bundle();
firstFragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction()
.replace(R.id.article_fragment, firstFragment)
.commit();
Learn More on Fragments adding to back stack:
Android Fragment transaction: FragmentManager and Backstack