How to make your Android app compatible with Gesture Navigation using Kotlin

How to make your Android app compatible with Gesture Navigation using Kotlin

In this tutorial, I’m going to show you how to fix your app, when an Android 10 (or above) device uses the Gesture Navigation, with some examples

Instead of the classic 2-3 button navigation bar, with the gesture navigation, we have to make some changes to look more beautiful.

Preparing the device/emulator for testing

Device

If you have an Android 10 device (or above) with a notch and you don’t have the Gesture navigation enabled, go to Settings > System > Gestures > System navigation and choose Gesture navigation

Emulator

Create a new emulator with Android Q (API 29) or above, choose Pixel 3 XL (or whatever pixel with a notch you like), and check the box Enable Device Frame.

Detecting if the Gesture Navigation is enabled

First, we need to detect when an Android 10 user has the Gesture navigation enabled.

To do that, we read the user’s settings system navigation option

fun isGestureNavigationEnabled(contentResolver: ContentResolver): Boolean {
      return Settings.Secure.getInt(contentResolver, "navigation_mode", 0) == 2
}

…and we use it like that:

if (isGestureNavigationEnabled(this.contentResolver)) {
    // Gesture Navigation is Enabled
}else{
    // 2-3 Buttons Navigation Bar is Enabled
}

Note: Some people reported thats not the safest way to detect it, because some devices might have the gesture navigation in a different number. Google hasn’t come up with any solution to this.

Fixing Full Screen Activity

When you have a Full Screen Activity and you want to expand this activity in all screen:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    if (isGestureNavigationEnabled(this.contentResolver)) {
        // Extends the PhotoView in the whole screen
        window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
        // Hides StatusBar and Navigation bar, you have to tap to appear
        // window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_IMMERSIVE or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION        
        // Fixes the Full Screen black bar in screen with notch
        window.attributes.layoutInDisplayCutoutMode =
            WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
    }
}

Fixing Activity with RecyclerView

In an Activity with Views, like RecyclerView, you want to expand the RecyclerView under the Gesture Navigation Bar and avoid hiding the last item.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    if (isGestureNavigationEnabled(this.contentResolver)) {
        // Disable clipping of the RecyclerView content when we use padding
        recycler_view.clipToPadding = false

        // Make the Gesture Navigation Bar transparent
        window.navigationBarColor = Color.TRANSPARENT

        // Expand the Views (RecyclerView) under the gesture navigation bar and toolbar
        window.decorView.systemUiVisibility =
            (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)

        // Set padding for the Views (RecyclerView and Relative Layout) from the System Views (Gesture Navigation Bar, Toolbar)
        recycler_view_content_id.setOnApplyWindowInsetsListener { v, insets ->
            val topPadding = insets.systemWindowInsetTop
            val bottomPadding = insets.systemWindowInsetBottom
            recycler_view_content_id.setPadding(0, topPadding, 0, 0)
            recycler_view.setPadding(0, 0, 0, bottomPadding)
            insets.consumeSystemWindowInsets()
        }
    }
}
You can find the final project here

If you have any questionsplease feel free to leave a comment below

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments