I currently have an android app that flows A -> B -> C -> D Launched in activity 1.
After D, I have activity 2 start and the following code runs to remove all fragments from the stack.
List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
}
}
My problem is that when I return to activity 1 from activity 2, is that when I press the back key Fragment C animates back to screen. Fragment D does remove but A B C do not. I would like the app to close on backpress from activity 1.
I attached the code that removes my fragments here. Debugging shows that fragment does change with each loop.
Can anyone advise what is happening here?
You can overwrite backpressed method and close the app, like this:
#Override
public void onBackPressed() {
finish(); // finish activity
}
Related
I have an ACTIVITY that hosts two fragments A and B. By default fragment A is hosted. Fragment B is started from fragment A. When user presses back in fragment B, and assuming some data was changed, first I kill fragment B using following code in B:
if (getActivity() != null) {
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
if (fragmentManager != null) {
getActivity().getSupportFragmentManager().popBackStackImmediate();
}
}
My question:
How do I know that fragment B has been 'killed' from fragment A, or even from ACTIVITY?
I want to refresh data in A when B is killed.
Something like
if (B.isKilled()) {
refreshDataInA();
}
I want to be able to do both from ACTIVITY and fragment B.
Thanks !
In your A fragment, the onResume method add
#Override
public void onResume() {
super.onResume();
if(B.isDetached()){
refreshData();
}
}
try it.
I have one activity containing one container that will receive 2 fragments.
Once the activity initialises i start the first fragment with:
showFragment(new FragmentA());
private void showFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment, fragment.getTag())
.addToBackStack(fragment.getTag())
.commit();
}
Then when the user clicks on FragmentA, I receive this click on Activity level and I call:
showFragment(new FragmentB());
Now when I press back button it returns to fragment A (thats correct) and when i press again back button it show empty screen (but stays in the same activity). I would like it to just close the app (since the activity has no parent).
There are a lot of posts related with Fragments and backstack, but i can't find a simple solution for this. I would like to avoid the case where I have to check if im doing back press on Fragment A or Fragment B, since i might extend the number of Fragments and I will need to maintain that method.
You are getting blank screen because when you add first fragment you are calling addToBackStack() due to which you are adding a blank screen unknowingly!
now what you can do is call the following method in onBackPressed() and your problem will be solved
public void moveBack()
{
//FM=fragment manager
if (FM != null && FM.getBackStackEntryCount() > 1)
{
FM.popBackStack();
}else {
finish();
}
}
DO NOT CALL SUPER IN ONBACKPRESSED();
just call the above method!
addToBackStack(fragment.getTag())
use it for fragment B only, not for fragment A
I think your fragment A is not popped out correctly, try to use add fragment rather replace to have proper back navigation, however You can check count of back stack using:
FragmentManager fragmentManager = getSupportFragmentManager();
int count = fragmentManager.getBackStackEntryCount();
and you can also directly call finish() in activity onBackPressed() when you want your activity to close on certain fragment count.
I have my MainActivity which has 6 fragments in the Navigation Drawer. Now, whenever I am in any of the 6 fragments and if I press back button, my app is exiting. I want to exit only from the 1st fragment. If I am in other fragments, then if I press back, I want it to come to the 1st fragment and from there if I press back again, then I want to exit.
I have to replace the fragments to the 1st fragment when it is not in the 1st position. I know that. But how exactly can I implement the whole in onBackPressed ?
Please help !! Thanks in advance.
override the onBackPress method and add this code;
public void onBackPressed(){
int count = getFragmentManager().getBackStackEntryCount(); // if stack count is 0, it means no fragment left to pop back stack
if (count = 0) {
finish();
}
}
You can get the fragment name with the instance and we can check weather it is in home fragment or not. Paste this code in the onBackPressed method in main activity class.
Fragment f = getSupportFragmentManager().findFragmentById(R.id.frame_container);
/**
* Compare the instances based on fragment name to change the action bar
*/
if (f instanceof HomeFragment) {
finish();
System.exit(0);
} else {
super.onBackPressed();
}
I have one Activity that hosts many Fragments. In Fragment A, I am adding a dialog when the user presses the back button to ask if they are sure if they want to leave this fragment. I added this code in the Activity's onBackPressed to control this:
#Override
public void onBackPressed() {
FragmentA fragmentA = (FragmentA) getSupportFragmentManager().findFragmentByTag("fragmentA");
if (fragmentA != null && fragmentA.isVisible()) {
fragmentA.showExitDialog();
return;
}
else { super.onBackPressed(); }
}
And the dialog works perfectly in Fragment A, but when it leaves Fragment A and goes to Fragment B (same activity) with this code:
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container,
FragmentB.newInstance(), "fragmentB").commit();
And I press the back button in Fragment B, it shows the same exit dialog again.
Thus, from my code, it is saying that FragmentA is not null and still visible even after I did the Replace function.
Why is Fragment A still visible when I replaced it with Fragment B?
I'm using one Activity which contains one Fragment at a time. I use support.v4.
The "onBackPressed" of Activity and Fragment is override, so I can't use the original back button, I have to override it myself.
So I'm in fragment A, I go to fragment B. Fragment B displays a list of results, and when I pick a line, it goes to Fragment C.
When I'm on C and I press back button, I want to go back on B with the results displayed. And if I press back button again, I'll go to A.
It looks simple.
I manage the come back from C to B. The thing is when I hit the back button on B, it calls Fragment C backPressed.
A -> B -> C -> B (display B but BackButton don't work anymore).
Some code :
backPressed in Fragment C
public void backPressed() {
FragmentTransaction transaction = ((FragmentActivity)m_context).getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.mainactivity_fragmentcontainer,((FragmentActivity)m_context).getSupportFragmentManager().findFragmentByTag("customtag"), "customtag");
transaction.commitAllowingStateLoss();
}
Fragment B has the tag "customtag".
When I replace B by C:
FragmentC newFrag = new FragmentC(m_context);FragmentTransaction transac = ((FragmentActivity)m_context).getSupportFragmentManager().beginTransaction();
((FragmentContainerActivity)m_context).setCurrentFragment(newFrag);
transac.replace(R.id.mainactivity_fragmentcontainer, newFrag);
transac.addToBackStack(null);
transac.commitAllowingStateLoss();
Any idea why the fragmentC which is replaced (the display changes and I can see fragment B) still get the back button action?
Thanks for your help.
EDIT
Code of backPressed in Fragment B (however the application never goes there when it comes from Fragment C).
#Override
public void backPressed() {
Log.e("FragmentB", "backPressed");
//I have 2 views in FragB. If View2 is visible, I make it gone and display View1
if(mainView.findViewById(R.id.view2).getVisibility()==View.VISIBLE){
displayView1();
}else{
if(fromFragmentX){
FragmentX fragX = new FragmentX(ctx);
FragmentTransaction transac = ((FragmentActivity)ctx).getSupportFragmentManager().beginTransaction();
((FragmentContainerActivity)ctx).setCurrentFragment(fragX);
transac.replace(R.id.mainactivity_fragmentcontainer, fragX);
transac.commitAllowingStateLoss();
}else{
super.backPressed();
}
}
}
SECOND EDIT
I realize I forgot to precise something.
When I'm replacing fragment B by fragment C, I'm doing it in the ArrayAdapter of the ListView in Fragment B, but it shouldn't change anything.
Anyway, I tried something different somewhere else in the app.
In FragmentU, I replace FragmentU by Fragment C (always the same), and I'm setting an attribute in Fragment C which is :
private CustomFragment fragmentFrom;
So on backPressed in FragmentC, in case I'm from Fragment U, I call :
FragmentTransaction transaction = ((FragmentActivity)ctx).getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.mainactivity_fragmentcontainer, fragmentFrom);
transaction.commitAllowingStateLoss();
And I still got the same problem. When coming back from Fragment C, the Fragment U is displayed, and works well, but the back button call FragmentC.backPressed.