After replacing Fragment, Activity still detects Fragment is visible - android

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?

Related

removing all fragments so that onBackPressed closes app

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
}

Android fragment simple backstack

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.

Exit from App only from the 1st fragment using onBackPressed

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();
}

Back from fragment to Activity onBackPressed

My question is that, i've one activity and one fragment,from activity open that fragment but when i pressed back button it close application.
i try with this code.
for open fragment.
case R.id.button_contact:
Fragment fragment = new FragmentContact();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container,fragment).addToBackStack("Frag1").commit();
break;
for back button.
#Override
public void onBackPressed() {
getSupportFragmentManager().popBackStackImmediate("Frag1",0);
super.onBackPressed();
}
I'm assuming you just want to remove the fragment and have the activity remain?
In that case modify your onBackPressed method to be
#Override
public void onBackPressed() {
if (getSupportFragmentManager().findFragmentByTag("Frag1") != null) {
getSupportFragmentManager().popBackStackImmediate("Frag1",0);
} else {
super.onBackPressed();
}
}
This will remove the fragment from the activity if it is added and if it isn't, then the back button will act as normal and destroy the activity.
Just remove this line from onBackPressed().
getSupportFragmentManager().popBackStackImmediate("Frag1",0);
Its work.
You can do something like this. It will work with your stack:
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
} else {
getSupportFragmentManager().popBackStack();
}
This piece of code will pop the stack if there is any fragment. Otherwise the back button will close the activity
What these two lines are doing:
1). getSupportFragmentManager().popBackStackImmediate("Frag1",0);
As you are adding you fragment in activity backstack, so when you are calling on back press,
it remove fragment from stack, now in your stack activity is left, means stack size is one.
2). super.onBackPressed();
I think you are aware of calling super.onbackpress funcionality, here it will finish
your activity and stack size is 0 now, and app will close immidately if stack size is 0.
so you have to remove super.onbackpress() Method.

Fragment replaced still catch backPressed

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.

Categories

Resources