Reputation: 7581
WIthin my main activity I have a simple PlaceHolder Fragment.
Via the options menu (actionbar) I would like to replace that fragment with a user settings preference fragment. In this specific case this is a good way.
All works well, but a "back" button in the user settings fragment will exit the App. I would like to go back to the original fragment. How come?
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView( R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace( R.id.container, new PlaceholderFragment()).commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
getFragmentManager().beginTransaction()
.replace( R.id.container, new UserSettingsFragment()).addToBackStack(null).commit();
return true;
}
return super.onOptionsItemSelected(item);
}
The main layout file is:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="nl.deholtmans.usersettings.MainActivity"
tools:ignore="MergeRootFrame" />
The UserSettings fragment is:
public class UserSettingsFragment extends PreferenceFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = super.onCreateView(inflater, container, savedInstanceState);
view.setBackgroundColor( Color.WHITE);
addPreferencesFromResource( R.xml.preferences);
return view;
}
}
Upvotes: 0
Views: 718
Reputation: 38856
To add the fragment to your back stack change your fragment transaction to the following:
getSupportFragmentManager().beginTransaction().add(R.id.container, new UserSettingsFragment()).addToBackStack(null).commit();
The reason you want to use .add()
instead of .replace()
is because with add your fragment gets added to the stack but with replace all other fragments are removed and then yours is added. This is why the back button exits the app, when you use replace there aren't any other fragments for your app to navigate back to.
Upvotes: 0
Reputation: 39836
the issue is that getFragmentManager
and getSupportFragmentManager
returns different things. In one call you're using the native fragmentManager and the other the support one. You can't use both together.
Change both to the support that it will work fine:
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView( R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace( R.id.container, new PlaceholderFragment()).commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
getSupportFragmentManager().beginTransaction()
.replace( R.id.container, new UserSettingsFragment()).addToBackStack(null).commit();
return true;
}
return super.onOptionsItemSelected(item);
}
ps: that means that both fragments you're calling should use extend a Support fragment
Upvotes: 1
Reputation: 5551
Both of the other answers are incorrect. You're not adding the fragment to the backstack; therefore, the backstack will not retrieve that fragment onBackPressed.
Make the following edit to your fragment transaction:
.replace( R.id.container, new PlaceholderFragment()).commit();
.replace( R.id.container, new PlaceholderFragment()).addToBackStack("fragmentname").commit();
Upvotes: 1