Skip to content

Android 10 incorrect insets when navigation bar is translucent #63761

@jacek-marchwicki

Description

@jacek-marchwicki

First of all thanks for the great Flutter toolkit if you'll have some follow up questions to the issue, I'll be glad to answer.

Steps to Reproduce

The example app is available here: https://github.com/jacek-marchwicki/flutter-insets-bug

Changes to the example project that are necessary to reproduce the issue: jacek-marchwicki/flutter-insets-bug@f23e6d8

Diff
Index: lib/main.dart
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- lib/main.dart	(revision d3362aabdefa74cc479fc50b8994f00b57b230a8)
+++ lib/main.dart	(date 1597401415000)
@@ -72,6 +72,25 @@
     // fast, so that you can just rebuild anything that needs updating rather
     // than having to individually change instances of widgets.
     return Scaffold(
+      bottomNavigationBar: BottomNavigationBar(
+        items: const <BottomNavigationBarItem>[
+          BottomNavigationBarItem(
+            icon: Icon(Icons.home),
+            title: Text('Home'),
+          ),
+          BottomNavigationBarItem(
+            icon: Icon(Icons.business),
+            title: Text('Business'),
+          ),
+          BottomNavigationBarItem(
+            icon: Icon(Icons.school),
+            title: Text('School'),
+          ),
+        ],
+        currentIndex: 0,
+        selectedItemColor: Colors.amber[800],
+        onTap: (_) {},
+      ),
       appBar: AppBar(
         // Here we take the value from the MyHomePage object that was created by
         // the App.build method, and use it to set our appbar title.
Index: android/app/src/main/kotlin/com/example/insetstest/MainActivity.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- android/app/src/main/kotlin/com/example/insetstest/MainActivity.kt	(revision d3362aabdefa74cc479fc50b8994f00b57b230a8)
+++ android/app/src/main/kotlin/com/example/insetstest/MainActivity.kt	(date 1597397196000)
@@ -1,7 +1,17 @@
 package com.example.insetstest
 
+import android.graphics.Color
+import android.os.Build
+import android.view.View
 import io.flutter.embedding.android.FlutterActivity
 
-class MainActivity : FlutterActivity() {
-
+class MainActivity: FlutterActivity() {
+    override fun onWindowFocusChanged(hasFocus: Boolean) {
+        super.onWindowFocusChanged(hasFocus)
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+            window.navigationBarColor = Color.TRANSPARENT
+            window.statusBarColor = Color.TRANSPARENT
+        }
+    }
 }
  1. We need to enable transparent navigation bar. According to (the Android documentation: https://developer.android.com/training/gestures/gesturenav) we need to set:

         window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
         window.navigationBarColor = Color.TRANSPARENT
         window.statusBarColor = Color.TRANSPARENT
  2. We need to check if insets are updated correctly, In the example I'm using BottomNavigationBar but we could also use SafeArea to reproduce the same issue.

Expected results Actual results Actual results On iOS
We should see the BottomNavigationBar displayed right above system navigation bar. We see system navigation bar displayed on BottomNavigationBar. On Android, we can observe the same results when gestures navigation is disabled and standard 3 buttons navigation is set. The same code works perfectly fine on iOS
android-with-fix android android-no-gestures ios

Findings

After debugging I found out that Android sets Window.viewInsets.bottom to the height of the navigation bar.
The different is on iOS where Window.viewInsets.bottom is set to 0, but the height of the navigation bar is set in Window.padding.bottom and Window.padding.viewPadding. By looking through the window documentation and the following video looks like the iOS implementation is correct.

Workaround

I've created a widget that does workaround the issue: jacek-marchwicki/flutter-insets-bug@f5eb07a#diff-fe53fad46868a294b309fc85ed138997R143-R168
With the fix, the app looks correctly:

Gesture navigation standard 3 buttons navigation
android-with-fix android-with-fix-no-gestures

Logs

Logs

flutter run --verbose results:

logs.txt

flutter analyze results:

Analyzing insets_test...                                                
No issues found! (ran in 6.6s)

flutter doctor -v results:

doctor-result.txt

Related tickets:

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work lista: layoutSystemChrome and Framework's Layout Issuesengineflutter/engine related. See also e: labels.found in release: 1.22Found to occur in 1.22found in release: 1.26Found to occur in 1.26frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-androidAndroid applications specificallyr: fixedIssue is closed as already fixed in a newer version

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions