tm1701
tm1701

Reputation: 7581

Android - back button leans to exit and not to the previously set fragment?

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

Answers (3)

MrEngineer13
MrEngineer13

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

Budius
Budius

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

Evan Bashir
Evan Bashir

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

Related Questions