My application currently has a single activity and a bunch of fragments. I want when the user presses the back button on their phone that they move backwards through the UI instead of exiting the application.
I override onBackPressed() in my main activity...
@Override
public void onBackPressed() {
FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 1) {
fragmentManager.popBackStackImmediate();
} else if(fragmentManager.findFragmentByTag("Seizure Tracker").isVisible()) {
if (backButtonPressed + 3000 > System.currentTimeMillis())
super.onBackPressed();
else {
backButtonPressed = System.currentTimeMillis();
Toast.makeText(this, "Press back again to exit.", Toast.LENGTH_SHORT).show();
}
} else{
super.onBackPressed();
}
}
This seems to work fine except for one transition. Basically I move from fragment A -> B -> C press back and fragment A shows up. Press back again and instead of the message "Press back again to exit" nothing happens. Press back again and the message shows up.
If I go
A -> B -> C back (now at A) -> B -> C back
I end up at B. If I press back again I stay at B. Press back again and I get to A. Press back again and the message "Press back again to exit" shows up.
If I go
A -> B -> C -> D back (now at C) back
I end up at A in the same state as if I went A -> B -> C back. So basically D back to C works fine as does every other back transition.
In my Main activity I have a listener for when the back state changes so I can update the actionBar
getSupportFragmentManager().addOnBackStackChangedListener(
new FragmentManager.OnBackStackChangedListener() {
public void onBackStackChanged() {
FragmentManager fragmentManager = getSupportFragmentManager();
System.out.println("changed: "+fragmentManager.getBackStackEntryCount());
for(int i = 0; i < fragmentManager.getBackStackEntryCount(); i++)
System.out.println("name: "+fragmentManager.getBackStackEntryAt(i).getName());
// Update your UI here.
getSupportActionBar().setTitle(getSupportFragmentManager()
.findFragmentById(R.id.container).getTag());
}
});
This updates the actionBar as if the back transitions were working as intended. I also added the print lines and they are telling me that the back transitions are working as intended and I can see nothing weird from printing:
for(int i = 0; i < fragmentManager.getBackStackEntryCount(); i++)
System.out.println("name:"+fragmentManager.getBackStackEntryAt(i).getName());
I am using a navigationDrawer maybe that has some effect on this...
switch (position) {
case 0:
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
System.out.println(fragmentManager.getBackStackEntryCount());
fragmentManager.beginTransaction()
.add(R.id.container, new SeizureTrackerFragment(), "Seizure Tracker")
.commit();
break;
case 2:
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
fragmentManager.beginTransaction()
.add(R.id.container, new SetupFragment(), "Setup")
.commit();
break;
case 3:
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
fragmentManager.beginTransaction()
.add(R.id.container, new AboutFragment(), "About")
.commit();
break;
}
If I start at any of the other fragments besides "case 0" everything works fine.
I always transition using the same code:
fragmentManager.beginTransaction()
.add(R.id.container, new AnalyzeFragment(), "Analyze")
.addToBackStack("Analyze").commit();
My fragment onCreate() all look the same:
View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
AppCompatActivity activity = (AppCompatActivity) getActivity();
ActionBar actionBar = activity.getSupportActionBar();
actionBar.setTitle("Analyze");
if(view == null)
view = inflater.inflate(R.layout.fragment_analyze, container, false);
return view;
}
Just to make this problem a little more confusing, every once in a while it will randomly start working perfectly even when I change absolutely nothing in my code.