Home > database >  Launching an Activity within a certain fragment, then going back to the previous Activity from where
Launching an Activity within a certain fragment, then going back to the previous Activity from where

Time:12-10

I've been struggling with a particular challenge which is as follows:

My app has an activity "A" which is considered the app's "main" activity. At a certain point, it launches an activity "B" which has an action available that should launch a fragment inside activity "A" (this won't always be the same fragment, it will depend on some data coming from our backend).

I can do this just fine by simply calling startActivity with the correct Intent, however, on pressing the back button, it goes back to A's "main fragment" (this is logic implemented inside of A's onBackButtonPressed()). Essentially, what should happen is as follows:

Activity A -> Activity B -> Activity A showing Fragment X -> press back -> Activity B

What happens when using startActivity to launch Activity A:

Activity A -> Activity B -> Activity A showing Fragment X -> press back -> Activity A showing the "main fragment". From here, if I press back again the app exits, which again is part of the implementation of A's onBackButtonPressed, however I've tried retrieving an extra from the intent which invoked A in order to conditionally bring back activity B but the Intent seemed to be empty of extras for reasons I can't figure out. I am sure I am correctly putting the extras in the Intent since activity A launches the correct fragment when invoked from B based on what I put there.

More things I've tried:

  • Launching the desired fragment directly from within B, however this way the fragment is not shown with the navigation bar that exists in A and seems to show the main contents of activity B behind the fragment's elements, which in user experience terms is undesirable.

  • Using the Intent.FLAG_ACTIVITY_REORDER_TO_FRONT flag, which seemed to make no difference whatsoever.

As this is part of my company's app which already has a decent degree of complexity, I'm not at liberty to provide you with useful code samples, and hopefully my description is sufficient for someone to aid me.

Additional information

targetApi="n"
Testing on Android 11
Activity A has launchMode "singleTask"
Activity B has launchMode "singleTop"

CodePudding user response:

For the intended behavior:

  1. Avoid using any launchMode, taskAffinity or activity flags, the default behavior is absolutely good for your requirements ("standard" is the default launch mode). So when you do the action in Activity B, a new instance of Activity A will be launched after putting B in backstack, which is the default behavior.

  2. You should have a logic in Activity A's onBackPressed() such that: if the fragment X is visible, then it will exit the whole activity, otherwise it passes by calling super(). Something like the following:

In Activity A

@Override
public void onBackPressed() {
    Fragment fragment = getFragmentManager().findFragmentByTag("yourTagForFragmentX");
    if (fragment instanceof XFragment) {
        // The fragment is available in the fragment manager
        finish()
    } else {
        super.onBackPressed();
    }
}

For more details, here

CodePudding user response:

I think you're overcomplicating things.

  1. Remove all of the launch mode flags for A and B - they should not be necessary.
  2. Remove custom handling of onBackPressed - default handling should suffice.
  3. Update A to initialize itself to the correct fragment based on the intent it's given:

For example:

onCreate(...) {
    if (getIntent().getAction() == "START_ON_X") {
        // Notice we REPLACE and DO NOT add to back stack
        getFragmentManager().replace(fragID, createXFragment()).commit()
    }
    else {
        getFragmentManager().replace(fragID, createDefaultFragment()).commit()
    }
}

Thus, you will have:

  1. Default launcher intent launches A.
  2. A launches B.
  3. B launches A with specific intent to show Fragment X

This will give you a stack of A -> B -> Ax

Then when you press back, DEFAULT BEHAVIOR will leave you on B.

Then pressing back again will leave you on A.

Then pressing back again will close your app.

Again this is all standard, default behavior. KISS.

  • Related