Skip to content

Commit

Permalink
Merge pull request #19501 from unoplatform/dev/mazi/android-insets-2
Browse files Browse the repository at this point in the history
Android insets handling continued
  • Loading branch information
jeromelaban authored Feb 11, 2025
2 parents d43a063 + 1cf85d7 commit bee761d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 12 deletions.
12 changes: 7 additions & 5 deletions src/Uno.UI/UI/Xaml/Application.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.UI.Xaml.Controls.Primitives;
using Windows.UI.ViewManagement;
using Colors = Microsoft.UI.Colors;
using Uno.UI.Xaml.Controls;

namespace Microsoft.UI.Xaml;

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

partial void ApplySystemOverlaysTheming()
{
var requestedTheme = InternalRequestedTheme;

StatusBar.GetForCurrentView().ForegroundColor = requestedTheme == ApplicationTheme.Dark
? Colors.White
: Colors.Black;
// This is needed only due to the fact that currently Instance accessor creates the wrapper
// eagerly - which could then happen too early. Will no longer be needed when un-singletoned.
if (InitializationComplete)
{
NativeWindowWrapper.Instance.ApplySystemOverlaysTheming();
}
}
}
47 changes: 41 additions & 6 deletions src/Uno.UI/UI/Xaml/Window/Native/NativeWindowWrapper.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
using Android.Runtime;
using Android.Util;
using Android.Views;
using AndroidX.AppCompat.App;
using AndroidX.Core.View;
using Uno.Disposables;
using Uno.Foundation.Logging;
using Uno.UI.Extensions;
using Windows.ApplicationModel.Core;
using Windows.Foundation;
using Windows.Graphics;
using Windows.Graphics.Display;
using Windows.UI.Core;
using Windows.UI.ViewManagement;
Expand Down Expand Up @@ -78,6 +76,7 @@ internal void RaiseNativeSizeChanged()
Bounds = new Rect(default, windowSize);
VisibleBounds = visibleBounds;
Size = new((int)(windowSize.Width * RasterizationScale), (int)(windowSize.Height * RasterizationScale));
ApplySystemOverlaysTheming();

if (_previousTrueVisibleBounds != visibleBounds)
{
Expand All @@ -88,7 +87,11 @@ internal void RaiseNativeSizeChanged()
}
}

protected override void ShowCore() => RemovePreDrawListener();
protected override void ShowCore()
{
ApplySystemOverlaysTheming();
RemovePreDrawListener();
}

private (Size windowSize, Rect visibleBounds) GetVisualBounds()
{
Expand All @@ -103,6 +106,9 @@ internal void RaiseNativeSizeChanged()
Rect windowBounds;
Rect visibleBounds;

var decorView = activity.Window.DecorView;
var fitsSystemWindows = decorView.FitsSystemWindows;

if ((int)Android.OS.Build.VERSION.SdkInt < 35)
{
var opaqueInsetsTypes = insetsTypes;
Expand Down Expand Up @@ -134,9 +140,19 @@ internal void RaiseNativeSizeChanged()
this.Log().LogDebug($"Insets: {insets}");
}

// Edge-to-edge is default on Android 15 and above
windowBounds = new Rect(default, GetWindowSize());
visibleBounds = windowBounds.DeflateBy(insets);
if (fitsSystemWindows)
{
// The window bounds are the same as the display size, as the system insets are already taken into account by the layout
windowBounds = new Rect(default, GetWindowSize().Subtract(insets));
visibleBounds = windowBounds;
}
else
{
// Edge-to-edge is default on Android 15 and above
windowBounds = new Rect(default, GetWindowSize());
visibleBounds = windowBounds.DeflateBy(insets);
}

}

if (this.Log().IsEnabled(LogLevel.Debug))
Expand Down Expand Up @@ -178,6 +194,25 @@ private WindowInsetsCompat GetWindowInsets(Activity activity)
return null;
}

internal void ApplySystemOverlaysTheming()
{
if ((int)Android.OS.Build.VERSION.SdkInt >= 35)
{
// In edge-to-edge experience we want to adjust the theming of status bar to match the app theme.
if ((ContextHelper.TryGetCurrent(out var context)) &&
context is Activity activity &&
activity.Window?.DecorView is { FitsSystemWindows: false } decorView)
{
var requestedTheme = Microsoft.UI.Xaml.Application.Current.RequestedTheme;

var insetsController = WindowCompat.GetInsetsController(activity.Window, decorView);

// "appearance light" refers to status bar set to light theme == dark foreground
insetsController.AppearanceLightStatusBars = requestedTheme == Microsoft.UI.Xaml.ApplicationTheme.Light;
}
}
}

private Size GetWindowSize()
{
if (ContextHelper.Current is not Activity activity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ internal void UpdateSystemUiVisibility()
}
}

// A bit confusingly, "appearance light" refers to light theme, so in dark foreground is used!
// A bit confusingly, "appearance light" refers to light theme, so dark foreground is used!
insetsController.AppearanceLightStatusBars = _foregroundType == StatusBarForegroundType.Dark;
}
}
Expand Down

0 comments on commit bee761d

Please sign in to comment.