Zeo
Zeo

Reputation: 109

Closing android application from fragment

I have only one activity in my application with multiple fragments. Whenever a user opens the app, it starts with startupFragment. Whenever user navigate through the fragments and presses back, it takes him back to startupFragment. But when in the startupFragment, I want user, when clicked back, to be able to close the application. Now, here is the code, when the application is started for creating the fragment.:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //Set starting fragment
    StartupFragment startupFragment = new StartupFragment();
    android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().add(R.id.content_main, startupFragment, "startupFragmentTag").commit();

}

As you can see, I have added the tag "startupFragmentTag" to be able to identify it. This is my code onBackPressed:

@Override
public void onBackPressed()
{

    Fragment startup = getFragmentManager().findFragmentByTag("startupFragmentTag");

    if(startup == null) {

        android.support.v4.app.FragmentManager manager = getSupportFragmentManager();
        StartupFragment startupFragment = new StartupFragment();
        manager.beginTransaction().replace(R.id.content_main, startupFragment, "startupFragmentTag").commit();

    } else {

        finish();

    }
}

So basically what I tried here, is when user is in another fragment, when the user presses back, it will take him/her back to startupFragment. But when in that fragment, when pressing back again, I want the user to be able to exit the application, which won't happen given the code now.

I find the startupFragment by its tag and check if it exists. If not, it will take back the user to it. But if it exists, user should be able to quit, that why finish() is called.

Does the previous fragments not get destroyed? But that shouldn't be the case, because even if I open the app and instantly press back, it won't exit the app.

What am I doing here wrong?

Upvotes: 2

Views: 4286

Answers (3)

Daniel Nugent
Daniel Nugent

Reputation: 43322

It looks like all you need to do is add each Fragment to the back stack on each FragmentTransaction, and then pop each Fragment from the back stack in onBackPressed().

First, modify onCreate() so that on each transaction, it calls addToBackStack():

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      //Set starting fragment
      StartupFragment startupFragment = new StartupFragment();
      android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
      fragmentManager.beginTransaction()
        .add(R.id.content_main, startupFragment, "startupFragmentTag")
        .addToBackStack(null)
        .commit();
  }

Then, in onBackPressed(), just pop from the back stack if you're not on the starting Fragment. If you're on the starting Fragment, and back is pressed, just call super.onBackPressed(), which will exit the app:

@Override
public void onBackPressed() {
    android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
    if (fragmentManager.getBackStackEntryCount() > 1) {
        //Go back to previous Fragment
        fragmentManager.popBackStackImmediate();
    } else {
        //Nothing in the back stack, so exit
        super.onBackPressed();
    }
}

Upvotes: 4

Wei WANG
Wei WANG

Reputation: 1776

Probably because you've used beginTransaction().add() to add the Fragments including startupFragment and other Fragments on top of it. Then you will always be able to find it using getFragmentManager().findFragmentByTag(), because all Fragments added will be in the Fragment stack (while the find method is actually to find the Fragment with the tag in the stack).

Tips based on what you want to impl:

  1. beginTransaction().replace() will replace instead of adding a Fragment, this way you will only be able to "find" one existing Fragment if you always replace it. i.e. always one Fragment in the stack.
  2. You may want to use getFragmentManager().findFragmentById() to get current showing Fragment (on top of the Fragment stack), instead of findFragmentByTag, if there're several Fragments in the stack which are added not replaced as mentioned above.
  3. When using beginTransaction().add(), you may want to use fragmentManager.addOnBackStackChangedListener() to monitor the Fragment stack changes. Then you probably don't have to handle onBackPressed(). Then in the in the listener you only need to retrieve current Fragment on top stack and see what it is and add your logic there.

Upvotes: 0

fdelafuente
fdelafuente

Reputation: 1122

You're working with fragments, so to finish your app you need to finish the parent activity.

Try this to finish the activity from startupfragment:

getActivity().finish();

Upvotes: 3

Related Questions