-
Notifications
You must be signed in to change notification settings - Fork 6k
Remove usages of deprecated setSystemUiVisibility() #29493
Changes from all commits
d4ac98a
a3fc96c
ef971cf
136b0a5
6b0acd3
f34f876
15959f6
2dab838
66e1276
5d70fd6
6377d18
6c7c963
4521517
21ab396
8de6247
42419c5
968a33c
f3e0724
1e60656
c273413
19629c8
e9b106a
f0d0757
7c6c8f3
73b030d
03f8d3b
091cd5c
0f0fc71
ea9c1ea
2e00909
2a52158
95dba21
fd56253
b44129b
604a8a8
d02802e
85a0f78
cfbef5b
94ee3f6
2e2747d
881a2db
8db28bc
cf6159f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,8 @@ | |
| import androidx.annotation.NonNull; | ||
| import androidx.annotation.Nullable; | ||
| import androidx.annotation.VisibleForTesting; | ||
| import androidx.core.view.WindowCompat; | ||
| import androidx.core.view.WindowInsetsCompat; | ||
| import androidx.core.view.WindowInsetsControllerCompat; | ||
| import io.flutter.Log; | ||
| import io.flutter.embedding.engine.systemchannels.PlatformChannel; | ||
|
|
@@ -28,14 +30,13 @@ | |
|
|
||
| /** Android implementation of the platform plugin. */ | ||
| public class PlatformPlugin { | ||
| public static final int DEFAULT_SYSTEM_UI = | ||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; | ||
|
|
||
| private final Activity activity; | ||
| private final PlatformChannel platformChannel; | ||
| private final PlatformPluginDelegate platformPluginDelegate; | ||
| private PlatformChannel.SystemChromeStyle currentTheme; | ||
| private int mEnabledOverlays; | ||
| private PlatformChannel.SystemUiMode currentSystemUiMode; | ||
| private List<PlatformChannel.SystemUiOverlay> currentOverlays; | ||
| private static final String TAG = "PlatformPlugin"; | ||
|
|
||
| /** | ||
|
|
@@ -141,7 +142,7 @@ public PlatformPlugin( | |
| this.platformChannel.setPlatformMessageHandler(mPlatformMessageHandler); | ||
| this.platformPluginDelegate = delegate; | ||
|
|
||
| mEnabledOverlays = DEFAULT_SYSTEM_UI; | ||
| currentSystemUiMode = PlatformChannel.SystemUiMode.EDGE_TO_EDGE; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a new default?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only difference between this mode and the |
||
| } | ||
|
|
||
| /** | ||
|
|
@@ -240,105 +241,98 @@ public void onSystemUiVisibilityChange(int visibility) { | |
| private void setSystemChromeEnabledSystemUIMode(PlatformChannel.SystemUiMode systemUiMode) { | ||
| int enabledOverlays; | ||
|
|
||
| if (systemUiMode == PlatformChannel.SystemUiMode.LEAN_BACK | ||
| && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { | ||
| Window window = activity.getWindow(); | ||
| View view = window.getDecorView(); | ||
| WindowInsetsControllerCompat windowInsetsControllerCompat = | ||
| new WindowInsetsControllerCompat(window, view); | ||
|
|
||
| if (systemUiMode == PlatformChannel.SystemUiMode.LEAN_BACK) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why don't we check for the build version here anymore?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A CI failure indicated that the minimum version is 16 (Jelly Bean) so this was unneeded. Do we need to keep the check in case someone bumps it down?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh ok, that makes sense!
Now that you mention it, that would probably be a situation we would want to have covered by it. I'll defer to @blasten though :) |
||
| // LEAN BACK | ||
| // Available starting at SDK 16 | ||
| // Available starting at SDK 20, due to the backwards compatibility provided by the | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be great if we can eventually migrate from the deprecated APIs to use AndroidX's compat libraries, but according to https://docs.flutter.dev/development/tools/sdk/release-notes/supported-platforms we are also supporting API 19. Seems like everything here and below will require API 20+. We might need to rethink a bit on the supported modes and the default mode (especially if edge-to-edge, which works best on API 29+, is going to be the new default). |
||
| // WindowInsetsControllerCompat class for setting the behavior of system bars. | ||
| // Should not show overlays, tap to reveal overlays, needs onChange callback | ||
| // When the overlays come in on tap, the app does not receive the gesture and does not know | ||
| // the system overlay has changed. The overlays cannot be dismissed, so adding the callback | ||
| // support will allow users to restore the system ui and dismiss the overlays. | ||
| // Not compatible with top/bottom overlays enabled. | ||
| enabledOverlays = | ||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE | ||
| | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | ||
| | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | ||
| | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | ||
| | View.SYSTEM_UI_FLAG_FULLSCREEN; | ||
| } else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE | ||
| && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | ||
| windowInsetsControllerCompat.setSystemBarsBehavior( | ||
| WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_TOUCH); | ||
| windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars()); | ||
| WindowCompat.setDecorFitsSystemWindows(window, false); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Are all the values in https://github.com/flutter/flutter/blob/61a0add2865c51bfee33939c1820709d1115c77d/packages/flutter/lib/src/services/system_chrome.dart#L90 equivalent edge-to-edge? @Piinks
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure I understand the question, are all the values in >what< equivalent to edge to edge? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the enum SystemUiMode
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, only one is edge to edge, the rest are different? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. It sounds like only the case
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That call replaces the flag SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN which is also a part of other modes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the videos. It does seem like all the modes that Flutter supports are edge-to-edge in Android terminology. https://developer.android.com/training/gestures/edge-to-edge - I didn't see any example where the opposite to that definition is true.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems like to implement edge to edge mode like that shown in the guide, you have to do some further style customization besides using this method (like to get the transparent bars). |
||
| } else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE) { | ||
| // IMMERSIVE | ||
| // Available starting at 19 | ||
| // Available starting at SDK 20, due to the backwards compatibility provided by the | ||
| // WindowInsetsControllerCompat class for setting the behavior of system bars. | ||
| // Should not show overlays, swipe from edges to reveal overlays, needs onChange callback | ||
| // When the overlays come in on swipe, the app does not receive the gesture and does not know | ||
| // the system overlay has changed. The overlays cannot be dismissed, so adding callback | ||
| // support will allow users to restore the system ui and dismiss the overlays. | ||
| // Not compatible with top/bottom overlays enabled. | ||
| enabledOverlays = | ||
| View.SYSTEM_UI_FLAG_IMMERSIVE | ||
| | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | ||
| | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | ||
| | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | ||
| | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | ||
| | View.SYSTEM_UI_FLAG_FULLSCREEN; | ||
| } else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE_STICKY | ||
| && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | ||
| windowInsetsControllerCompat.setSystemBarsBehavior( | ||
| WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_SWIPE); | ||
| windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars()); | ||
| WindowCompat.setDecorFitsSystemWindows(window, false); | ||
| } else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE_STICKY) { | ||
| // STICKY IMMERSIVE | ||
| // Available starting at 19 | ||
| // Available starting at SDK 20, due to the backwards compatibility provided by the | ||
| // WindowInsetsControllerCompat class for setting the behavior of system bars. | ||
| // Should not show overlays, swipe from edges to reveal overlays. The app will also receive | ||
| // the swipe gesture. The overlays cannot be dismissed, so adding callback support will | ||
| // allow users to restore the system ui and dismiss the overlays. | ||
| // Not compatible with top/bottom overlays enabled. | ||
| enabledOverlays = | ||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | ||
| | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | ||
| | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | ||
| | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | ||
| | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | ||
| | View.SYSTEM_UI_FLAG_FULLSCREEN; | ||
| windowInsetsControllerCompat.setSystemBarsBehavior( | ||
| WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); | ||
| windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars()); | ||
| WindowCompat.setDecorFitsSystemWindows(window, false); | ||
| } else if (systemUiMode == PlatformChannel.SystemUiMode.EDGE_TO_EDGE | ||
| && Build.VERSION.SDK_INT >= 29) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This version check can probably be removed now
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, it seems like there's a test that ensures this is not enabled for versions below this. @Piinks any insight on this?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is restricted on purpose, see flutter/flutter#89774 for context. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Piinks For the comment below, "SDK 29 and up will apply..." are these things set somewhere else? I'm trying to understand where the differences are between the Flutter implementation and the internal Android implementation.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for budding in here, but I did ask @Piinks about this yesterday, and it's my understanding that this comment is a bit misleading. The call made when the edge to edge mode is set in Flutter is just to lay out the app behind the system bars, same for Android. The remaining steps to achieve edge to edge mode like in Android (shown in the guide) in Flutter are done beyond a call to |
||
| // EDGE TO EDGE | ||
| // Available starting at 29 | ||
| // SDK 29 and up will apply a translucent body scrim behind 2/3 button navigation bars | ||
| // Available starting at SDK 29. See issue for context: | ||
| // https://github.com/flutter/flutter/issues/89774. | ||
| // Will apply a translucent body scrim behind 2/3 button navigation bars | ||
| // to ensure contrast with buttons on the nav and status bars, unless the contrast is not | ||
| // enforced in the overlay styling. | ||
| enabledOverlays = | ||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE | ||
| | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | ||
| | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; | ||
| WindowCompat.setDecorFitsSystemWindows(window, false); | ||
| } else { | ||
| // When none of the conditions are matched, return without updating the system UI overlays. | ||
| return; | ||
| } | ||
|
|
||
| mEnabledOverlays = enabledOverlays; | ||
| updateSystemUiOverlays(); | ||
| currentSystemUiMode = systemUiMode; | ||
| } | ||
|
|
||
| private void setSystemChromeEnabledSystemUIOverlays( | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that this method is deprecated now. |
||
| List<PlatformChannel.SystemUiOverlay> overlaysToShow) { | ||
| Window window = activity.getWindow(); | ||
| View view = window.getDecorView(); | ||
| WindowInsetsControllerCompat windowInsetsControllerCompat = | ||
| new WindowInsetsControllerCompat(window, view); | ||
|
|
||
| // Start by assuming we want to hide all system overlays (like an immersive | ||
| // game). | ||
| int enabledOverlays = | ||
| DEFAULT_SYSTEM_UI | ||
| | View.SYSTEM_UI_FLAG_FULLSCREEN | ||
| | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | ||
| | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; | ||
|
|
||
| // The SYSTEM_UI_FLAG_IMMERSIVE_STICKY flag was introduced in API 19, so we | ||
| // apply it | ||
| // if desired, and if the current Android version is 19 or greater. | ||
| if (overlaysToShow.size() == 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | ||
| enabledOverlays |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; | ||
| windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars()); | ||
| WindowCompat.setDecorFitsSystemWindows(window, false); | ||
|
|
||
| // We apply sticky immersive mode if desired. Available starting at SDK 20. | ||
| if (overlaysToShow.size() == 0) { | ||
| currentSystemUiMode = PlatformChannel.SystemUiMode.IMMERSIVE_STICKY; | ||
|
|
||
| windowInsetsControllerCompat.setSystemBarsBehavior( | ||
| WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); | ||
| } | ||
|
|
||
| // Re-add any desired system overlays. | ||
| for (int i = 0; i < overlaysToShow.size(); ++i) { | ||
| PlatformChannel.SystemUiOverlay overlayToShow = overlaysToShow.get(i); | ||
| switch (overlayToShow) { | ||
| case TOP_OVERLAYS: | ||
| enabledOverlays &= ~View.SYSTEM_UI_FLAG_FULLSCREEN; | ||
| windowInsetsControllerCompat.show(WindowInsetsCompat.Type.statusBars()); | ||
| break; | ||
| case BOTTOM_OVERLAYS: | ||
| enabledOverlays &= ~View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; | ||
| enabledOverlays &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; | ||
| windowInsetsControllerCompat.show(WindowInsetsCompat.Type.navigationBars()); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| mEnabledOverlays = enabledOverlays; | ||
| updateSystemUiOverlays(); | ||
| currentOverlays = overlaysToShow; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -350,8 +344,11 @@ private void setSystemChromeEnabledSystemUIOverlays( | |
| * PlatformPlugin}. | ||
| */ | ||
| public void updateSystemUiOverlays() { | ||
| activity.getWindow().getDecorView().setSystemUiVisibility(mEnabledOverlays); | ||
| if (currentTheme != null) { | ||
| setSystemChromeEnabledSystemUIMode(currentSystemUiMode); | ||
|
|
||
| if (currentOverlays != null) { | ||
| setSystemChromeEnabledSystemUIOverlays(currentOverlays); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Is what situation
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If someone decides to make a call to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right, but wouldn't an external call to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I see what you mean. In that case, if |
||
| } else if (currentTheme != null) { | ||
| setSystemChromeSystemUIOverlayStyle(currentTheme); | ||
| } | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line means edge-to-edge mode will become the default mode (related to flutter/flutter#86248 ?). It would be great if we can eventually land this, but do note that it will be a breaking change for apps that don't handle paddings/safe area properly. My team had to manually apply non-trivial fixes (e.g. cl/397106186 and cl/397283284) before enabling this.