I’ve got an application with a layout consisting of two fragments. One menu fragment to the left and a content fragment to the right. When the user presses a menu item in the menu fragment the content fragment changes.
On a small device (phone) I only display the menu fragment initially. When the user presses a menu item the entire menu fragment is replaced by a content fragment. However, when the user then wants to go back to the menu by pressing the back button, the application closes (as if there is nothing in the back stack).
The following is a trimmed version of my code, what am I doing wrong?
public class MainActivity extends FragmentActivity implements IMenuListener {
private static final String TAG = MainActivity.class.getName();
private Fragment menuFragment = null;
private Fragment contentFragment = null;
private FragmentManager fm;
private ActionBar actionBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(fm == null) fm = getFragmentManager();
if(actionBar == null) actionBar = getActionBar();
menuFragment = (MenuFragment) fm.findFragmentById(R.id.menuFragment);
contentFragment = (Fragment) fm.findFragmentById(R.id.contentFragment);
if(menuFragment == null) {
menuFragment = new MenuFragment();
replaceFragment(R.id.menuFragment, menuFragment);
}
// If the content fragment has not been initiated, initiate it, as the view exists in XML.
if(contentFragment == null && findViewById(R.id.contentFragment) != null) {
actionBar.setSubtitle(getResources().getString(R.string.actionbar_subtitle_home));
contentFragment = new HomeFragment();
replaceFragment(R.id.contentFragment, contentFragment);
}
// If the content fragment has not been initiated and the view does not exist in XML, don't initiate it.
else if(contentFragment == null && findViewById(R.id.contentFragment) == null) {
// Basically do nothing.
actionBar.setSubtitle(getResources().getString(R.string.actionbar_subtitle_menu));
}
}
// Menu item clicked, change fragment
@Override
public void onMenuItemSelected(MenuItem item) {
if(contentFragment != null && contentFragment.isVisible()) {
// Custom MenuItem class has a Fragment field
replaceFragment(R.id.contentFragment, item.getFragment());
contentFragment = item.getFragment();
} else {
if(deviceIsPhoneInPortaitOrientation()) {
replaceFragment(R.id.menuFragment, item.getFragment());
}
}
}
/**
* Replace current fragment
* @param container The resource id of the container view
* @param newFragment The new fragment which should be placed in the given container
*/
private void replaceFragment(int container, Fragment newFragment) {
FragmentTransaction ft = fm.beginTransaction();
ft.addToBackStack(null); // TODO Not working as expected
ft.replace(container, newFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
}
/**
* Determines whether the current device is a phone with current orientation
* set to portrait or not.
* @return true if it is, false otherwise
*/
public boolean deviceIsPhoneInPortaitOrientation() {
return (!getResources().getBoolean(R.bool.isTablet) &&
getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
}
}
there is already nice demonstration of exactly what you are look for .
check the actionBarSherlock fragments sample (or the one provided by google, they are about the same) , in the “layout” demo .
also check out this tutorial and this lecture