1. Introduction
In Android 13, we've added APIs that serve as the foundation of upcoming support for a predictive back gesture.
This feature will let a user preview the result of a Back gesture before they fully complete it – basically allowing them to decide whether to stay in the current view or complete the action and return to the Home screen, a previous activity, or a previously visited page in a WebView. Here's an example of what that's going to look like:
In the case of this codelab, we're going to fix a survey fragment that implements a WebView.
Goal of this codelab
This codelab shows you how to prepare an AndroidX app that intercepts system Back by migrating it to support predictive back gesture with a WebView, by using the APIs that implement the ahead-of-time back navigation model. In other words, for the new animations to work, the system needs to know ahead of time if the app is intercepting the back navigation gesture.
What you'll build
In this codelab, you'll use AndroidX API libraries to handle Back gestures in the Sunflower app.
What you'll learn
- How to intercept the on-back invocation for AndroidX
- How to return the Back event to the system
- Other options for handling Back gestures
- The new user experience coming in Android 13+ providing a more predictive back gesture navigation
What you'll need
- Android Studio
- An Android device enabled with Gesture navigation
- (Optional) Git
2. Plan support for predictive back gesture
Use AndroidX APIs to implement this feature
This codelab is designed for apps that already use AndroidX.
You'll be implementing OnBackPressedDispatcher
and OnBackPressedCallback
to support Back navigation.
Other options
We've got other options for handling this feature, depending on different needs your app may have:
- For apps unable to use AndroidX - If this is you, we've got you covered. Use the new
OnBackInvokedDispatcher
andOnBackInvokedCallback
platform classes we're introducing in Android 13, which enable you to use the ahead-of-time APIs without requiring AndroidX. See the documentation for details. - For apps temporarily unable to migrate - If this is you, we've also got you covered! You can opt out from the predictive back gesture if it's not possible to migrate to either the AndroidX libraries or the platform APIs at this time. See the documentation for details.
3. Before you begin
Install Android Studio
Install Android Studio and the Android 13 SDK.
Obtain a device
You can use a virtual or physical Android device to run the app you build using this codelab.
Enable gesture navigation
If you run a new emulator instance with API level 29, Gesture Navigation might not be turned on by default. To enable gesture navigation, select System settings > System > System Navigation > Gesture Navigation.
Get the code
Get the code in one of the following ways:
Download the zip
Download via Git
If you'd prefer to download the code using Git, follow these steps:
- Install Git.
- Clone
starter-code
ormain
branch to get the app for this exercise:
Terminal
// Get starter app.
git clone --branch starter-code \
https://github.com/android/codelab-handling-back-navigation.git
Run the app
Complete the following steps:
- Open and build the app in Android Studio.
- Create a new virtual device, and select Tiramisu. Alternatively, you can connect a physical device that runs API level 33 or higher.
- Run the Sunflower app.
Next you'll establish a baseline and walk through a poor experience that is part of the Sunflower app.
4. Establish a baseline
Our starting point is the Sunflower app, which includes a survey presented in a WebView that handles Back gestures poorly. When a user swipes from the left or right edge to go back in the WebView, the app returns them to a previous fragment instead of going back to the previous page, causing them to lose any unsubmitted data.
Explore the demo
Starting from the main screen, let's walk through main workflow of your app to review the poor experience with the WebView functionality.
- In the default screen of the Sunflower app, tap PLANT LIST.
- In the plant catalog, tap any plant. (For this example, we'll use the avocado fruit.)
- In the info screen for the plant you tapped, tap the thumbs-up icon (in the top right corner) to rate the plant.
- Start filling out the survey, but stop when you get to Question #3.
- Swipe inward from the left (or the right) edge of the screen to use the Back gesture. Note that, instead of taking you to Question #2 in the survey, swiping Back takes you to the plant detail fragment (in this example, the Avocado information page). This causes you to lose your answers, and makes for a poor user experience.
Let's now jump in to start to fix these issues!
5. Enable the predictive back gesture
Our app already uses AndroidX, so you'll use the Back navigation APIs. These already support the ahead-of-time model.
Target Android 13
In our app's Studio project, update the app's build configuration to target Android 13, as shown in the following code snippet.
build.gradle (Project)
buildscript {
ext {
// Sdk and tools
minSdkVersion = 29
compileSdkVersion = 33
targetSdkVersion = 33
}
...
}
Upgrade dependencies
In build.gradle, set appCompatVersion
to 1.6.0
or higher.
build.gradle (Project)
buildscript {
ext {
// App dependencies
appCompatVersion = '1.6.0-rc01' // Built original with changes
...
}
Upgrade to AndroidX Activity 1.6.0 or higher.
build.gradle (Module)
dependencies {
implementation "androidx.activity:activity-ktx:1.6.0"
...
}
Enable the predictive back gesture
To enable the predictive back gesture APIs, set enableOnBackInvokedCallback
to true
in the manifest.
AndroidManifest.xml
<application
...
android:enableOnBackInvokedCallback="true" // Enables this feature.
... >
...
</application>
Declare and register OnBackPressedCallback to handle Back gestures
Create the callback and override the handleOnBackPressed
method to handle Back gestures. For the WebView use case, let's use the Back gesture to go back in the page stack until there are no more pages.
SurveyFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
...
val OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
when {
webView.canGoBack() -> webView.goBack()
}
}
}
requireActivity().onBackPressedDispatcher
.addCallback(onBackPressedCallback)
}
Try out what you've built
Now you're going to test that the WebView navigation works properly.
- In Android Studio, build and run the app again.
- Just as you did when you first ran the demo, tap a plant of your choice and then tap the thumbs-up icon, then fill out the survey until you reach Question #3.
- Swipe inward from the left (or right) edge of the screen to use the Back gesture. The WebView should return you to Question #2 in the survey.
This is the exact behavior we want. However, we're only halfway there—it's still not completely fixed yet. Let's continue to see what we mean:
- From Question #2, swipe back to Question #1, then swipe back once more in an attempt to return to the plant detail fragment.
Notice that you can't go back from Question #1 to the plant detail fragment. This is because:
- Your WebView handles Back navigation by avoiding leaving the WebView when using on-Back navigation.
- Your app needs to return the Back navigation to the system once it no longer needs it. Let's go to the next section to fix that!
6. Fix the Back gesture
In the previous step, our app intercepted the Back gesture without returning it to the plant detail fragment in the previous steps. As a result, our users cannot leave the app and are stuck in the WebView with a poor user experience.
Enable or disable Back navigation with OnBackPressedCallback
- Override the
doUpdateVisitedHistory
method to determine if the Back navigation should be intercepted. The logic to handle Back navigation is the following:- If there are more pages to go back to in the WebView (
webView.canGoBack()
),OnBackPressedCallback
method should be enabled. - Conversely, if there are no more pages to go back to in the WebView, the
OnBackPressedCallback
method should be disabled. As a result, the Back gesture will go back to the topmost fragment in the back stack.
- If there are more pages to go back to in the WebView (
SurveyFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
...
requireActivity().onBackPressedDispatcher
.addCallback(onBackPressedCallback)
disableOnBackPressedCallback(webView, onBackPressedCallback)
}
}
private fun disableOnBackPressedCallback(webView: WebView, onBackPressedCallback: OnBackPressedCallback) {
webView.webViewClient = object: WebViewClient() {
override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) {
// Disable the on-back press callback if there are no more questions in the
// WebView to go back to, allowing us to exit the WebView and go back to
// the fragment.
onBackPressedCallback.isEnabled = webView.canGoBack()
}
}
}
- To test the WebView again, fill out the survey once again until you reach Question #3.
- Using Back gestures, navigate all the way back to the plant detail view. You should be able to do this without a problem.
Here's an example of how all this should look after you've fixed it:
Preview the new back to home gesture animation
In upcoming versions of Android, you'll start experiencing the predictive back gesture as shown in the following animation. We strongly recommend that you start implementing these changes as soon as possible!
You can preview the new back to home gesture navigation by enabling the developer option.
7. Congratulations
Congratulations! You covered a lot of content. We hope you've got a better understanding of the options and APIs to start updating your app toward the predictive back gesture offered in Android.
What we've covered
- How to enable your app to start using the APIs that support the predictive back gesture
- How to intercept on-back invocation for AndroidX
- How to return the Back navigation to the system
- Other options to handle Back gestures
- The new UX experience coming in Android 13, providing a more predictive back gesture
Completed codelab
// Get completed app.
git clone --branch main \
https://github.com/android/codelab-handling-back-navigation.git