I am currently building an application for Android (14 <= SDK <= 21) by using one ActionBarActivity
and more Fragments
, such as ListFragment
and MapFragment
, which are swapped within a single FrameLayout
view.
The ActionBarActivity automatically replace/commit fragment A. Then, when the user tap a button, the hosting Activity replace/commit a new different fragment B. My goal is to let the user go back on fragment A as soon as she presses the back button.
Some code now.
MainActivity
public class MainActivity extends ActionBarActivity implements StopFragment.OnFragmentInteractionListener,
StopItemFragment.OnFragmentInteractionListener {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getFragmentManager();
fragmentManager.enableDebugLogging(true);
...
if (fragmentManager.findFragmentById(R.id.content_frame) == null) {
StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment
fragmentManager.beginTransaction()
.replace(R.id.content_frame, list)
.addToBackStack(null)
.commit();
}
...
@Override
public void onFragmentInteraction(String id) {
selectItem(Integer.parseInt(id));
}
private void selectItem(int position) {
StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment
...
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
...
}
}
Problem
Even if addToBackStack()
is called, when I am on fragment B, I am not able to go back to fragment A. MainActivity is directly closed.
Yet I tried to manage the back stack by myself with no luck. I can see that the fragment is on the stack but if I call popBackStackImmediate()
, fragment A is popped out and the fragment transaction is not performed. (first back press nothing happen, second activity closed)
I attach also the FragmentManager logcat:
http://pastebin.com/hFLHprL8
For those, who are still looking for solution.
In the main Activity
class (which is hosting the fragments)just override onBackPressed()
.
@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0 ){
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
There is no onBackPressed()
method in fragment, and this method is just for the activity
. So,when we press the back key, the default behaviour of activity
is shown, which is
you will either go to previous activity(if there is any) or the app will exit.
Now we need to override this method to tell the activity
that when we press the back key, if there are any fragments in back stack, pop them out (and this is when the addToBackStack()
comes into picture). Otherwise follow the default behaviour.
Try this (Note add not replace for fragmentA, and addToBackStack() for fragmentB)
StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment
fragmentManager.beginTransaction()
.add(R.id.content_frame, list)
.commit();
and
StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment
...
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.addToBackStack("FragmentB")
.commit();
I had to call beginTransaction()
and commit()
of FragmentManager
manually.
Solved by overriding onBackPressed()
:
@Override
public void onBackPressed() {
...
if (fragmentManager.getBackStackEntryCount() > 1){
fragmentManager.popBackStackImmediate();
fragmentManager.beginTransaction().commit();
} else {
//handle finish
finish(); // Closes app
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With