179 lines
7.7 KiB
C#
179 lines
7.7 KiB
C#
#if ANDROID
|
|
|
|
using AndroidX.Core.View;
|
|
using AndroidX.AppCompat.App;
|
|
using Android.Views;
|
|
using Android.OS;
|
|
using AView = Android.Views.View;
|
|
using Microsoft.Maui.Handlers;
|
|
using Microsoft.Maui.Platform;
|
|
|
|
namespace gehGassi.Toolkit.Extensions.Window
|
|
{
|
|
// https://developer.android.com/develop/ui/views/layout/edge-to-edge
|
|
|
|
public static partial class WindowExtensions
|
|
{
|
|
private static Color defaultStatusBarColor = Colors.Transparent;
|
|
private static Color defaultNavigationBarColor = Colors.Black;
|
|
private static bool defaultStatusBarLightElements = false;
|
|
private static bool defaultNavigationBarLightElements = true;
|
|
|
|
/// <summary>
|
|
/// Forces application content to be displayed behind system bars (status and navigation bars) on Android and iOS.
|
|
/// </summary>
|
|
/// <param name="builder">The builder for your .NET MAUI application and services.</param>
|
|
/// <returns>The builder.</returns>
|
|
public static MauiAppBuilder DisplayContentBehindBars(this MauiAppBuilder builder)
|
|
{
|
|
WindowHandler.Mapper.AppendToMapping("DisplayContentBehindBars", (handler, window) =>
|
|
{
|
|
var activity = handler.PlatformView as AppCompatActivity;
|
|
|
|
WindowCompat.SetDecorFitsSystemWindows(activity.Window, false);
|
|
|
|
window.SetStatusBarAppearance();
|
|
});
|
|
|
|
WindowHandler.Mapper.AppendToMapping("Insets", (handler, window) =>
|
|
{
|
|
var activity = handler.PlatformView as AppCompatActivity;
|
|
|
|
if (window is not Element elmentWindow)
|
|
return;
|
|
|
|
// If I use just activity.Window.DecorView, set colors of the bars are overridden.
|
|
ViewCompat.SetOnApplyWindowInsetsListener(
|
|
(activity.Window.DecorView as ViewGroup).GetChildAt(0),
|
|
new SimpleOnApplyWindowInsetsListener(elmentWindow.Id, InvokeListenersIfChanged));
|
|
});
|
|
|
|
return builder;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Changes the status bar appearance of all windows.
|
|
/// </summary>
|
|
/// <param name="builder">The builder for your .NET MAUI application and services.</param>
|
|
/// <param name="color">New background color of the status bar.</param>
|
|
/// <param name="lightElements">Whether text and icons should be light or dark.</param>
|
|
/// <returns>The builder.</returns>
|
|
public static MauiAppBuilder SetDefaultStatusBarAppearance(this MauiAppBuilder builder, Color color = null, bool lightElements = true)
|
|
{
|
|
defaultStatusBarColor = color;
|
|
defaultStatusBarLightElements = lightElements;
|
|
|
|
WindowHandler.Mapper.AppendToMapping("DefaultStatusBarAppearance", (handler, window) =>
|
|
{
|
|
window.SetStatusBarAppearance(color, lightElements);
|
|
});
|
|
|
|
return builder;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Changes the navigation bar appearance of all windows.
|
|
/// </summary>
|
|
/// <param name="builder">The builder for your .NET MAUI application and services.</param>
|
|
/// <param name="color">New background color of the navigation bar.</param>
|
|
/// <param name="lightElements">Whether text and icons should be light or dark.</param>
|
|
/// <returns>The builder.</returns>
|
|
public static MauiAppBuilder SetDefaultNavigationBarAppearance(this MauiAppBuilder builder, Color color = null, bool lightElements = true)
|
|
{
|
|
defaultNavigationBarColor = color;
|
|
defaultNavigationBarLightElements = lightElements;
|
|
|
|
WindowHandler.Mapper.AppendToMapping("DefaultNavigationBarAppearance", (handler, window) =>
|
|
{
|
|
window.SetNavigationBarAppearance(color, lightElements);
|
|
});
|
|
|
|
return builder;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Changes the status bar appearance of a window.
|
|
/// </summary>
|
|
/// <param name="window">The window.</param>
|
|
/// <param name="color">New background color of the status bar.</param>
|
|
/// <param name="lightElements">Whether text and icons should be light or dark.</param>
|
|
public static void SetStatusBarAppearance(this IWindow window, Color color = null, bool? lightElements = null)
|
|
{
|
|
var activity = window.Handler.PlatformView as AppCompatActivity;
|
|
|
|
var windowInsetController = WindowCompat.GetInsetsController(activity.Window, activity.Window.DecorView);
|
|
if (windowInsetController is not null)
|
|
{
|
|
windowInsetController.AppearanceLightStatusBars = !(lightElements ?? defaultStatusBarLightElements);
|
|
}
|
|
else if (Build.VERSION.SdkInt < BuildVersionCodes.R)
|
|
{
|
|
int uiOptions = (int)activity.Window.DecorView.SystemUiVisibility;
|
|
|
|
if (!(lightElements ?? defaultStatusBarLightElements))
|
|
uiOptions |= (int)SystemUiFlags.LightStatusBar;
|
|
else
|
|
uiOptions &= ~(int)SystemUiFlags.LightStatusBar;
|
|
|
|
activity.Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
|
|
}
|
|
|
|
activity.Window.SetStatusBarColor((color ?? defaultStatusBarColor).ToPlatform());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Changes the navigation bar appearance of a window.
|
|
/// </summary>
|
|
/// <param name="window">The window.</param>
|
|
/// <param name="color">New background color of the navigation bar.</param>
|
|
/// <param name="lightElements">Whether text and icons should be light or dark.</param>
|
|
public static void SetNavigationBarAppearance(this IWindow window, Color color = null, bool? lightElements = null)
|
|
{
|
|
var activity = window.Handler.PlatformView as AppCompatActivity;
|
|
|
|
var windowInsetController = ViewCompat.GetWindowInsetsController(activity.Window.DecorView);
|
|
if (windowInsetController is not null)
|
|
{
|
|
windowInsetController.AppearanceLightNavigationBars = !(lightElements ?? defaultNavigationBarLightElements);
|
|
}
|
|
else if (Build.VERSION.SdkInt < BuildVersionCodes.R)
|
|
{
|
|
int uiOptions = (int)activity.Window.DecorView.SystemUiVisibility;
|
|
|
|
if (!(lightElements ?? defaultNavigationBarLightElements))
|
|
uiOptions |= (int)SystemUiFlags.LightNavigationBar;
|
|
else
|
|
uiOptions &= ~(int)SystemUiFlags.LightNavigationBar;
|
|
|
|
activity.Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
|
|
}
|
|
|
|
activity.Window.SetNavigationBarColor((color ?? defaultNavigationBarColor).ToPlatform());
|
|
}
|
|
}
|
|
|
|
internal class SimpleOnApplyWindowInsetsListener : Java.Lang.Object, IOnApplyWindowInsetsListener
|
|
{
|
|
private readonly Guid windowId;
|
|
private readonly Action<Guid, Thickness> action;
|
|
|
|
public SimpleOnApplyWindowInsetsListener(Guid windowId, Action<Guid, Thickness> action)
|
|
{
|
|
this.windowId = windowId;
|
|
this.action = action;
|
|
}
|
|
|
|
public WindowInsetsCompat OnApplyWindowInsets(AView v, WindowInsetsCompat insets)
|
|
{
|
|
var barsInsets = insets.GetInsets(WindowInsetsCompat.Type.SystemBars());
|
|
var density = DeviceDisplay.MainDisplayInfo.Density;
|
|
|
|
action?.Invoke(windowId, new Thickness(barsInsets.Left / density, barsInsets.Top / density, barsInsets.Right / density, barsInsets.Bottom / density));
|
|
|
|
return ViewCompat.OnApplyWindowInsets(v, insets.Inset(barsInsets));
|
|
//return ViewCompat.OnApplyWindowInsets(v, insets.Inset(0,0,0,0));
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif |