Skip to content

Commit bee761d

Browse files
authored
Merge pull request unoplatform#19501 from unoplatform/dev/mazi/android-insets-2
Android insets handling continued
2 parents d43a063 + 1cf85d7 commit bee761d

File tree

3 files changed

+49
-12
lines changed

3 files changed

+49
-12
lines changed

Diff for: src/Uno.UI/UI/Xaml/Application.Android.cs

+7-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Microsoft.UI.Xaml.Controls.Primitives;
1111
using Windows.UI.ViewManagement;
1212
using Colors = Microsoft.UI.Colors;
13+
using Uno.UI.Xaml.Controls;
1314

1415
namespace Microsoft.UI.Xaml;
1516

@@ -33,10 +34,11 @@ static partial void StartPartial(ApplicationInitializationCallback callback)
3334

3435
partial void ApplySystemOverlaysTheming()
3536
{
36-
var requestedTheme = InternalRequestedTheme;
37-
38-
StatusBar.GetForCurrentView().ForegroundColor = requestedTheme == ApplicationTheme.Dark
39-
? Colors.White
40-
: Colors.Black;
37+
// This is needed only due to the fact that currently Instance accessor creates the wrapper
38+
// eagerly - which could then happen too early. Will no longer be needed when un-singletoned.
39+
if (InitializationComplete)
40+
{
41+
NativeWindowWrapper.Instance.ApplySystemOverlaysTheming();
42+
}
4143
}
4244
}

Diff for: src/Uno.UI/UI/Xaml/Window/Native/NativeWindowWrapper.Android.cs

+41-6
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33
using Android.Runtime;
44
using Android.Util;
55
using Android.Views;
6-
using AndroidX.AppCompat.App;
76
using AndroidX.Core.View;
87
using Uno.Disposables;
98
using Uno.Foundation.Logging;
109
using Uno.UI.Extensions;
1110
using Windows.ApplicationModel.Core;
1211
using Windows.Foundation;
13-
using Windows.Graphics;
1412
using Windows.Graphics.Display;
1513
using Windows.UI.Core;
1614
using Windows.UI.ViewManagement;
@@ -78,6 +76,7 @@ internal void RaiseNativeSizeChanged()
7876
Bounds = new Rect(default, windowSize);
7977
VisibleBounds = visibleBounds;
8078
Size = new((int)(windowSize.Width * RasterizationScale), (int)(windowSize.Height * RasterizationScale));
79+
ApplySystemOverlaysTheming();
8180

8281
if (_previousTrueVisibleBounds != visibleBounds)
8382
{
@@ -88,7 +87,11 @@ internal void RaiseNativeSizeChanged()
8887
}
8988
}
9089

91-
protected override void ShowCore() => RemovePreDrawListener();
90+
protected override void ShowCore()
91+
{
92+
ApplySystemOverlaysTheming();
93+
RemovePreDrawListener();
94+
}
9295

9396
private (Size windowSize, Rect visibleBounds) GetVisualBounds()
9497
{
@@ -103,6 +106,9 @@ internal void RaiseNativeSizeChanged()
103106
Rect windowBounds;
104107
Rect visibleBounds;
105108

109+
var decorView = activity.Window.DecorView;
110+
var fitsSystemWindows = decorView.FitsSystemWindows;
111+
106112
if ((int)Android.OS.Build.VERSION.SdkInt < 35)
107113
{
108114
var opaqueInsetsTypes = insetsTypes;
@@ -134,9 +140,19 @@ internal void RaiseNativeSizeChanged()
134140
this.Log().LogDebug($"Insets: {insets}");
135141
}
136142

137-
// Edge-to-edge is default on Android 15 and above
138-
windowBounds = new Rect(default, GetWindowSize());
139-
visibleBounds = windowBounds.DeflateBy(insets);
143+
if (fitsSystemWindows)
144+
{
145+
// The window bounds are the same as the display size, as the system insets are already taken into account by the layout
146+
windowBounds = new Rect(default, GetWindowSize().Subtract(insets));
147+
visibleBounds = windowBounds;
148+
}
149+
else
150+
{
151+
// Edge-to-edge is default on Android 15 and above
152+
windowBounds = new Rect(default, GetWindowSize());
153+
visibleBounds = windowBounds.DeflateBy(insets);
154+
}
155+
140156
}
141157

142158
if (this.Log().IsEnabled(LogLevel.Debug))
@@ -178,6 +194,25 @@ private WindowInsetsCompat GetWindowInsets(Activity activity)
178194
return null;
179195
}
180196

197+
internal void ApplySystemOverlaysTheming()
198+
{
199+
if ((int)Android.OS.Build.VERSION.SdkInt >= 35)
200+
{
201+
// In edge-to-edge experience we want to adjust the theming of status bar to match the app theme.
202+
if ((ContextHelper.TryGetCurrent(out var context)) &&
203+
context is Activity activity &&
204+
activity.Window?.DecorView is { FitsSystemWindows: false } decorView)
205+
{
206+
var requestedTheme = Microsoft.UI.Xaml.Application.Current.RequestedTheme;
207+
208+
var insetsController = WindowCompat.GetInsetsController(activity.Window, decorView);
209+
210+
// "appearance light" refers to status bar set to light theme == dark foreground
211+
insetsController.AppearanceLightStatusBars = requestedTheme == Microsoft.UI.Xaml.ApplicationTheme.Light;
212+
}
213+
}
214+
}
215+
181216
private Size GetWindowSize()
182217
{
183218
if (ContextHelper.Current is not Activity activity)

Diff for: src/Uno.UWP/UI/ViewManagement/StatusBar/StatusBar.Android.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ internal void UpdateSystemUiVisibility()
143143
}
144144
}
145145

146-
// A bit confusingly, "appearance light" refers to light theme, so in dark foreground is used!
146+
// A bit confusingly, "appearance light" refers to light theme, so dark foreground is used!
147147
insetsController.AppearanceLightStatusBars = _foregroundType == StatusBarForegroundType.Dark;
148148
}
149149
}

0 commit comments

Comments
 (0)