Parent Navigation has always been a tough topic on Android. There are not a lot of apps that implement the guidelines correctly, maybe because they are hard to understand or complicated to implement. Even the Google apps don’t implement them: it’s always frustrating to take a screenshot, press Up on the preview and not be redirected to the Google Photo app 😞.
Unlike the Back button, which should come back to the previous screen – even if that screen was not from the same app –, the Up button should stay in the same app.
Let’s see how to implement this navigation.
Here is a simple music app, with 3 activities:
Forward navigation is pretty obvious:
On MainActivity
, users can go to AlbumActivity
or TrackActivity
.
Nothing special here. So what about back navigation?
Since we’re in the same task, Up navigation and Back navigation do the same thing: they come back to the previous activity. But if we don’t start from the main activity (for instance from a notification or a widget), Up and Back won’t have the same behavior:
No need to write anything in the Activity#onOptionsItemSelected
method! Everything is already done in the Android SDK.
We mainly just need to edit the AndroidManifest.xml
file to add some attributes to our activities.
parentActivityName
First, we need to declare a parent activity for each child activity:
TrackActivity
will come back to AlbumActivity
, which itself comes back to MainActivity
.
See also : getParentActivityIntent
But that’s not enough: now when pressing the Up button a new activity is created – even if we’re in the same task –, instead of dimissing the current activity.
launchMode
By declaring parent activities’ launchMode
as singleTop
, we prevent the system from creating a new activity each time we press Up.
Now we have the desired behavior, but we don’t cover all the cases. What if I start TrackActivity
from outside the app, and press Up? I want to be redirected to AlbumActivity
.
To do that, we have to declare a taskAffinity
.
taskAffinity
Declaring a taskAffinity
for TrackActivity
allows a new task to be created when starting this activity from outside the app. Thanks to that, Up navigation will switch to the main task and create an AlbumActivity
.
Curious about how it works? See Activity#onNavigateUp
One issue here: AlbumActivity
needs to know which album we want to display.
onPrepareSupportNavigateUpTaskStack
On TrackActivity
, we need to override onPrepareSupportNavigateUpTaskStack
to edit the intent that will start the parent activity when pressing Up:
See also onCreateNavigateUpTaskStack.
One last thing: because we create a new task when starting TrackActivity
from outside the app, TrackActivity
will remain on the Recents screen when pressing Up. It would be great to remove it automatically.
autoRemoveFromRecents
With autoRemoveFromRecents
, the activity will be removed from the Recents screen when its task is completed, for instance when coming back to the parent activity.
To sum up, this is what the AndroidManifest.xml
looks like:
Now that you know how to tune the AndroidManifest
to get a satisfying parent navigation, please don’t just finish()
the activity when pressing Up 😀