feat(android): edge to edge (#10774)

This commit is contained in:
Osei Fortune
2025-11-04 23:13:15 -04:00
committed by GitHub
parent 55d111c19d
commit 248ff4bcae
51 changed files with 1737 additions and 256 deletions

View File

@@ -1,3 +1,4 @@
import { Color } from '../color';
import { numberHasDecimals, numberIs64Bit } from './types';
import { getNativeApp } from '../application/helpers-common';
import { androidGetCurrentActivity } from '../application/helpers';
@@ -294,3 +295,133 @@ export function isRealDevice(): boolean {
return fingerprint != null && (fingerprint.indexOf('vbox') > -1 || fingerprint.indexOf('generic') > -1);
}
const DefaultLightScrim = new Color(0xe6, 0xff, 0xff, 0xff);
const DefaultDarkScrim = new Color(0x80, 0x1b, 0x1b, 0x1b);
const DefaultStatusBarLight = new Color(0);
const DefaultStatusBarDark = new Color(0);
interface ISystemColor {
navigationBarLight: Color;
navigationBarDark: Color;
statusBarLight: Color;
statusBarDark: Color;
handler?: (bar: 'status' | 'navigation', resources: android.content.res.Resources) => boolean;
}
const systemColors = new WeakMap<androidx.appcompat.app.AppCompatActivity, ISystemColor>();
function setEnableEdgeToEdge(activity: androidx.appcompat.app.AppCompatActivity, existingColors: ISystemColor) {
enableEdgeToEdge(activity, {
statusBarLightColor: existingColors.statusBarLight,
statusBarDarkColor: existingColors.statusBarDark,
navigationBarLightColor: existingColors.navigationBarLight,
navigationBarDarkColor: existingColors.navigationBarDark,
handleDarkMode: existingColors?.handler ?? null,
});
}
export function setStatusBarColor(options?: { activity?: androidx.appcompat.app.AppCompatActivity; lightColor?: Color; darkColor?: Color }): void {
const statusBarLightColor = options?.lightColor ?? null;
const statusBarDarkColor = options?.darkColor ?? null;
const activity = options?.activity ?? getCurrentActivity();
if (activity) {
const existingColors = systemColors.get(activity) ?? {
navigationBarLight: DefaultLightScrim,
navigationBarDark: DefaultDarkScrim,
statusBarLight: DefaultStatusBarLight,
statusBarDark: DefaultStatusBarDark,
};
existingColors.statusBarLight ??= statusBarLightColor;
existingColors.statusBarDark ??= statusBarDarkColor;
systemColors.set(getCurrentActivity(), existingColors);
setEnableEdgeToEdge(activity, existingColors);
}
}
export function setNavigationBarColor(options?: { activity?: androidx.appcompat.app.AppCompatActivity; lightColor?: Color; darkColor?: Color }): void {
const navigationBarLightColor = options?.lightColor ?? null;
const navigationBarDarkColor = options?.darkColor ?? null;
const activity = options?.activity ?? getCurrentActivity();
if (activity) {
const existingColors = systemColors.get(activity) ?? {
navigationBarLight: DefaultLightScrim,
navigationBarDark: DefaultDarkScrim,
statusBarLight: DefaultStatusBarLight,
statusBarDark: DefaultStatusBarDark,
};
existingColors.navigationBarLight ??= navigationBarLightColor;
existingColors.navigationBarDark ??= navigationBarDarkColor;
systemColors.set(getCurrentActivity(), existingColors);
setEnableEdgeToEdge(activity, existingColors);
}
}
export function setDarkModeHandler(options?: { activity?: androidx.appcompat.app.AppCompatActivity; handler: (bar: 'status' | 'navigation', resources: android.content.res.Resources) => boolean }): void {
const darkModeHandler = options?.handler ?? null;
const activity = options?.activity ?? getCurrentActivity();
if (activity) {
const existingColors = systemColors.get(activity) ?? {
navigationBarLight: DefaultLightScrim,
navigationBarDark: DefaultDarkScrim,
statusBarLight: DefaultStatusBarLight,
statusBarDark: DefaultStatusBarDark,
};
existingColors.handler ??= darkModeHandler;
systemColors.set(getCurrentActivity(), existingColors);
setEnableEdgeToEdge(activity, existingColors);
}
}
export function enableEdgeToEdge(
activity: androidx.appcompat.app.AppCompatActivity,
options?: {
statusBarLightColor?: Color;
statusBarDarkColor?: Color;
navigationBarLightColor?: Color;
navigationBarDarkColor?: Color;
handleDarkMode?: (bar: 'status' | 'navigation', resources: android.content.res.Resources) => boolean;
},
): void {
let handleDarkMode: org.nativescript.widgets.Utils.HandleDarkMode;
let statusBarLight: number = 0;
let statusBarDark: number = 0;
let navigationBarLight: number = DefaultLightScrim.android;
let navigationBarDark: number = DefaultDarkScrim.android;
if (options) {
if (typeof options.handleDarkMode === 'function') {
handleDarkMode = new org.nativescript.widgets.Utils.HandleDarkMode({
onHandle(bar, resources) {
if (bar === 0) {
return options.handleDarkMode('status', resources);
} else {
return options.handleDarkMode('navigation', resources);
}
},
});
}
if (options.statusBarLightColor instanceof Color) {
statusBarLight = options.statusBarLightColor.android;
}
if (options.statusBarDarkColor instanceof Color) {
statusBarDark = options.statusBarDarkColor.android;
}
if (options.navigationBarLightColor instanceof Color) {
navigationBarLight = options.navigationBarLightColor.android;
}
if (options.navigationBarDarkColor instanceof Color) {
navigationBarDark = options.navigationBarDarkColor.android;
}
}
if (handleDarkMode) {
org.nativescript.widgets.Utils.enableEdgeToEdge(activity, java.lang.Integer.valueOf(statusBarLight), java.lang.Integer.valueOf(statusBarDark), java.lang.Integer.valueOf(navigationBarLight), java.lang.Integer.valueOf(navigationBarDark), handleDarkMode);
} else {
org.nativescript.widgets.Utils.enableEdgeToEdge(activity, java.lang.Integer.valueOf(statusBarLight), java.lang.Integer.valueOf(statusBarDark), java.lang.Integer.valueOf(navigationBarLight), java.lang.Integer.valueOf(navigationBarDark));
}
}