mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
@@ -7,10 +7,6 @@ import { makeValidator, makeParser } from '../ui/core/properties';
|
||||
import { CubicBezierAnimationCurve } from '../ui/animation/animation-interfaces';
|
||||
|
||||
export namespace CoreTypes {
|
||||
type AndroidOverflowSingle = 'ignore' | 'none' | 'dont-apply';
|
||||
type AndroidOverflowMultiple = 'left' | 'right' | 'top' | 'bottom' | 'left-dont-consume' | 'top-dont-consume' | 'right-dont-consume' | 'bottom-dont-consume' | 'all-but-left' | 'all-but-top' | 'all-but-right' | 'all-but-bottom';
|
||||
type AndroidOverflowStacked = AndroidOverflowSingle | `${AndroidOverflowSingle},${AndroidOverflowMultiple}`;
|
||||
export type AndroidOverflow = AndroidOverflowSingle | AndroidOverflowStacked;
|
||||
export type CSSWideKeywords = 'initial' | 'inherit' | 'unset' | 'revert';
|
||||
|
||||
/**
|
||||
|
||||
Binary file not shown.
@@ -2,7 +2,7 @@
|
||||
import type { Point, CustomLayoutView as CustomLayoutViewDefinition, Position } from '.';
|
||||
import type { GestureTypes, GestureEventData } from '../../gestures';
|
||||
|
||||
import { ViewCommon, isEnabledProperty, originXProperty, originYProperty, isUserInteractionEnabledProperty, testIDProperty, AndroidHelper, androidOverflowEdgeProperty } from './view-common';
|
||||
import { ViewCommon, isEnabledProperty, originXProperty, originYProperty, isUserInteractionEnabledProperty, testIDProperty, AndroidHelper } from './view-common';
|
||||
import { paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, Length } from '../../styling/style-properties';
|
||||
import { layout } from '../../../utils';
|
||||
import { Trace } from '../../../trace';
|
||||
@@ -372,21 +372,20 @@ const INSET_TOP_CONSUMED = 20;
|
||||
const INSET_RIGHT_CONSUMED = 24;
|
||||
const INSET_BOTTOM_CONSUMED = 28;
|
||||
|
||||
const OverflowEdgeIgnore = -1;
|
||||
const OverflowEdgeNone: number = 0;
|
||||
const OverflowEdgeLeft: number = 1 << 1;
|
||||
const OverflowEdgeTop: number = 1 << 2;
|
||||
const OverflowEdgeRight: number = 1 << 3;
|
||||
const OverflowEdgeBottom: number = 1 << 4;
|
||||
const OverflowEdgeDontApply: number = 1 << 5;
|
||||
const OverflowEdgeLeftDontConsume: number = 1 << 6;
|
||||
const OverflowEdgeTopDontConsume: number = 1 << 7;
|
||||
const OverflowEdgeRightDontConsume: number = 1 << 8;
|
||||
const OverflowEdgeBottomDontConsume: number = 1 << 9;
|
||||
const OverflowEdgeAllButLeft: number = 1 << 10;
|
||||
const OverflowEdgeAllButTop: number = 1 << 11;
|
||||
const OverflowEdgeAllButRight: number = 1 << 12;
|
||||
const OverflowEdgeAllButBottom: number = 1 << 13;
|
||||
const OverflowEdgeLeft: number = 1;
|
||||
const OverflowEdgeTop: number = 1 << 1;
|
||||
const OverflowEdgeRight: number = 1 << 2;
|
||||
const OverflowEdgeBottom: number = 1 << 3;
|
||||
const OverflowEdgeDontApply: number = 1 << 4;
|
||||
const OverflowEdgeLeftDontConsume: number = 1 << 5;
|
||||
const OverflowEdgeTopDontConsume: number = 1 << 6;
|
||||
const OverflowEdgeRightDontConsume: number = 1 << 7;
|
||||
const OverflowEdgeBottomDontConsume: number = 1 << 8;
|
||||
const OverflowEdgeAllButLeft: number = 1 << 9;
|
||||
const OverflowEdgeAllButTop: number = 1 << 10;
|
||||
const OverflowEdgeAllButRight: number = 1 << 11;
|
||||
const OverflowEdgeAllButBottom: number = 1 << 12;
|
||||
|
||||
class Inset {
|
||||
private view: DataView;
|
||||
@@ -622,35 +621,134 @@ export class View extends ViewCommon {
|
||||
return manager;
|
||||
}
|
||||
|
||||
[androidOverflowEdgeProperty.setNative](value: CoreTypes.AndroidOverflow) {
|
||||
protected _defaultOverflowEdge: number = OverflowEdgeNone;
|
||||
protected _defaultOverflowEdgeValue: string = 'none';
|
||||
// @ts-ignore
|
||||
public set androidOverflowEdge(value: string) {
|
||||
if (typeof value !== 'string') {
|
||||
return;
|
||||
}
|
||||
const nativeView = this.nativeViewProtected as any;
|
||||
if (typeof value !== 'string' || nativeView === null || nativeView == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!('setOverflowEdge' in nativeView)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (value) {
|
||||
case 'none':
|
||||
if (nativeView && nativeView.setOverflowEdge) {
|
||||
if (value === 'none') {
|
||||
nativeView.setOverflowEdge(OverflowEdgeNone);
|
||||
break;
|
||||
case 'ignore':
|
||||
nativeView.setOverflowEdge(OverflowEdgeIgnore);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
const edge = parseEdges(value);
|
||||
|
||||
if (edge != null) {
|
||||
nativeView.setOverflowEdge(edge);
|
||||
}
|
||||
} else {
|
||||
const newValue = parseEdges(value);
|
||||
if (newValue !== null) {
|
||||
nativeView.setOverflowEdge(newValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
const edge = parseEdges(value);
|
||||
|
||||
if (edge === null) {
|
||||
return;
|
||||
}
|
||||
this._defaultOverflowEdgeValue = value;
|
||||
this._defaultOverflowEdge = edge;
|
||||
}
|
||||
}
|
||||
|
||||
public get androidOverflowEdge() {
|
||||
const nativeView = this.nativeViewProtected as any;
|
||||
if (nativeView && nativeView.getOverflowEdge) {
|
||||
const overflowEdge = nativeView.getOverflowEdge();
|
||||
switch (overflowEdge) {
|
||||
case OverflowEdgeNone:
|
||||
return 'none';
|
||||
case OverflowEdgeLeft:
|
||||
return 'left';
|
||||
case OverflowEdgeTop:
|
||||
return 'top';
|
||||
case OverflowEdgeRight:
|
||||
return 'right';
|
||||
case OverflowEdgeBottom:
|
||||
return 'bottom';
|
||||
case OverflowEdgeDontApply:
|
||||
return 'dont-apply';
|
||||
case OverflowEdgeLeftDontConsume:
|
||||
return 'left-dont-consume';
|
||||
case OverflowEdgeTopDontConsume:
|
||||
return 'top-dont-consume';
|
||||
case OverflowEdgeRightDontConsume:
|
||||
return 'right-dont-consume';
|
||||
case OverflowEdgeBottomDontConsume:
|
||||
return 'bottom-dont-consume';
|
||||
case OverflowEdgeAllButLeft:
|
||||
return 'all-but-left';
|
||||
case OverflowEdgeAllButTop:
|
||||
return 'all-but-top';
|
||||
case OverflowEdgeAllButRight:
|
||||
return 'all-but-right';
|
||||
case OverflowEdgeAllButBottom:
|
||||
return 'all-but-bottom';
|
||||
default:
|
||||
{
|
||||
let value = '';
|
||||
const overflowLeftConsume = (overflowEdge & OverflowEdgeLeft) == OverflowEdgeLeft;
|
||||
const overflowTopConsume = (overflowEdge & OverflowEdgeTop) == OverflowEdgeTop;
|
||||
const overflowRightConsume = (overflowEdge & OverflowEdgeRight) == OverflowEdgeRight;
|
||||
const overflowBottomConsume = (overflowEdge & OverflowEdgeBottom) == OverflowEdgeBottom;
|
||||
|
||||
const overflowLeft = (overflowEdge & OverflowEdgeLeftDontConsume) == OverflowEdgeLeftDontConsume;
|
||||
const overflowTop = (overflowEdge & OverflowEdgeTopDontConsume) == OverflowEdgeTopDontConsume;
|
||||
const overflowRight = (overflowEdge & OverflowEdgeRightDontConsume) == OverflowEdgeRightDontConsume;
|
||||
const overflowBottom = (overflowEdge & OverflowEdgeBottomDontConsume) == OverflowEdgeBottomDontConsume;
|
||||
|
||||
if (overflowLeftConsume) {
|
||||
value += 'left';
|
||||
}
|
||||
if (overflowTopConsume) {
|
||||
if (value.length > 0) {
|
||||
value += ',';
|
||||
}
|
||||
value += 'top';
|
||||
}
|
||||
if (overflowRightConsume) {
|
||||
if (value.length > 0) {
|
||||
value += ',';
|
||||
}
|
||||
value += 'right';
|
||||
}
|
||||
if (overflowBottomConsume) {
|
||||
if (value.length > 0) {
|
||||
value += ',';
|
||||
}
|
||||
value += 'bottom';
|
||||
}
|
||||
|
||||
if (overflowLeft) {
|
||||
value += 'left-dont-consume';
|
||||
}
|
||||
if (overflowTop) {
|
||||
if (value.length > 0) {
|
||||
value += ',';
|
||||
}
|
||||
value += 'top-dont-consume';
|
||||
}
|
||||
if (overflowRight) {
|
||||
if (value.length > 0) {
|
||||
value += ',';
|
||||
}
|
||||
value += 'right-dont-consume';
|
||||
}
|
||||
if (overflowBottom) {
|
||||
if (value.length > 0) {
|
||||
value += ',';
|
||||
}
|
||||
value += 'bottom-dont-consume';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (this._defaultOverflowEdgeValue) {
|
||||
return this._defaultOverflowEdgeValue;
|
||||
}
|
||||
}
|
||||
return 'none';
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
this._manager = null;
|
||||
@@ -704,6 +802,13 @@ export class View extends ViewCommon {
|
||||
if (!this.insetListenerIsSet && this.needsInsetListener) {
|
||||
this.setInsetListener();
|
||||
}
|
||||
|
||||
const nativeView = this.nativeViewProtected as any;
|
||||
if (typeof this._defaultOverflowEdge === 'number') {
|
||||
if (nativeView && nativeView.setOverflowEdge) {
|
||||
nativeView.setOverflowEdge(this._defaultOverflowEdge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public needsOnLayoutChangeListener() {
|
||||
@@ -1509,43 +1614,113 @@ export class View extends ViewCommon {
|
||||
}
|
||||
}
|
||||
|
||||
const edgeMap: Record<string, number> = {
|
||||
none: OverflowEdgeNone,
|
||||
left: OverflowEdgeLeft,
|
||||
top: OverflowEdgeTop,
|
||||
right: OverflowEdgeRight,
|
||||
bottom: OverflowEdgeBottom,
|
||||
'dont-apply': OverflowEdgeDontApply,
|
||||
'left-dont-consume': OverflowEdgeLeftDontConsume,
|
||||
'top-dont-consume': OverflowEdgeTopDontConsume,
|
||||
'right-dont-consume': OverflowEdgeRightDontConsume,
|
||||
'bottom-dont-consume': OverflowEdgeBottomDontConsume,
|
||||
'all-but-left': OverflowEdgeAllButLeft,
|
||||
'all-but-top': OverflowEdgeAllButTop,
|
||||
'all-but-right': OverflowEdgeAllButRight,
|
||||
'all-but-bottom': OverflowEdgeAllButBottom,
|
||||
};
|
||||
|
||||
function parseEdges(edges: string): number | null {
|
||||
let result = 0;
|
||||
const values = edges.split(',');
|
||||
for (const raw of values) {
|
||||
const value = edgeMap[raw.trim()];
|
||||
if (value === undefined) continue;
|
||||
// dont-apply overrides everything else
|
||||
if (value === OverflowEdgeDontApply) return value;
|
||||
result |= value;
|
||||
const values = edges.trim().split(',');
|
||||
let newValue = -1;
|
||||
for (let value of values) {
|
||||
const trimmedValue = value.trim();
|
||||
switch (trimmedValue) {
|
||||
case 'none':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeNone;
|
||||
} else {
|
||||
newValue |= OverflowEdgeNone;
|
||||
}
|
||||
break;
|
||||
case 'left':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeLeft;
|
||||
} else {
|
||||
newValue |= OverflowEdgeLeft;
|
||||
}
|
||||
break;
|
||||
case 'top':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeTop;
|
||||
} else {
|
||||
newValue |= OverflowEdgeTop;
|
||||
}
|
||||
break;
|
||||
case 'right':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeRight;
|
||||
} else {
|
||||
newValue |= OverflowEdgeRight;
|
||||
}
|
||||
break;
|
||||
case 'bottom':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeBottom;
|
||||
} else {
|
||||
newValue |= OverflowEdgeBottom;
|
||||
}
|
||||
break;
|
||||
case 'dont-apply':
|
||||
newValue = OverflowEdgeDontApply;
|
||||
break;
|
||||
case 'left-dont-consume':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeLeftDontConsume;
|
||||
} else {
|
||||
newValue |= OverflowEdgeLeftDontConsume;
|
||||
}
|
||||
break;
|
||||
case 'top-dont-consume':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeTopDontConsume;
|
||||
} else {
|
||||
newValue |= OverflowEdgeTopDontConsume;
|
||||
}
|
||||
break;
|
||||
case 'right-dont-consume':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeRightDontConsume;
|
||||
} else {
|
||||
newValue |= OverflowEdgeRightDontConsume;
|
||||
}
|
||||
break;
|
||||
case 'bottom-dont-consume':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeBottomDontConsume;
|
||||
} else {
|
||||
newValue |= OverflowEdgeBottomDontConsume;
|
||||
}
|
||||
case 'all-but-left':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeAllButLeft;
|
||||
} else {
|
||||
newValue |= OverflowEdgeAllButLeft;
|
||||
}
|
||||
case 'all-but-top':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeAllButTop;
|
||||
} else {
|
||||
newValue |= OverflowEdgeAllButTop;
|
||||
}
|
||||
case 'all-but-right':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeAllButRight;
|
||||
} else {
|
||||
newValue |= OverflowEdgeAllButRight;
|
||||
}
|
||||
case 'all-but-bottom':
|
||||
if (newValue === -1) {
|
||||
newValue = OverflowEdgeAllButBottom;
|
||||
} else {
|
||||
newValue |= OverflowEdgeAllButBottom;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result === 0 ? null : result;
|
||||
|
||||
if (newValue === -1) {
|
||||
return null;
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
||||
export class ContainerView extends View {
|
||||
public iosOverflowSafeArea: boolean;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.androidOverflowEdge = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomLayoutView extends ContainerView implements CustomLayoutViewDefinition {
|
||||
|
||||
@@ -987,7 +987,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
public iosOverflowSafeArea: boolean;
|
||||
public iosOverflowSafeAreaEnabled: boolean;
|
||||
public iosIgnoreSafeArea: boolean;
|
||||
public androidOverflowEdge: CoreTypes.AndroidOverflow;
|
||||
public androidOverflowEdge: string;
|
||||
|
||||
get isLayoutValid(): boolean {
|
||||
return this._isLayoutValid;
|
||||
@@ -1315,12 +1315,6 @@ export const iosIgnoreSafeAreaProperty = new InheritedProperty({
|
||||
});
|
||||
iosIgnoreSafeAreaProperty.register(ViewCommon);
|
||||
|
||||
export const androidOverflowEdgeProperty = new Property<ViewCommon, CoreTypes.AndroidOverflow>({
|
||||
name: 'androidOverflowEdge',
|
||||
defaultValue: 'ignore',
|
||||
});
|
||||
androidOverflowEdgeProperty.register(ViewCommon);
|
||||
|
||||
export const visionHoverStyleProperty = new Property<ViewCommon, string | VisionHoverOptions>({
|
||||
name: 'visionHoverStyle',
|
||||
valueChanged(view, oldValue, newValue) {
|
||||
|
||||
@@ -93,7 +93,8 @@ export class Frame extends FrameBase {
|
||||
constructor() {
|
||||
super();
|
||||
this._android = new AndroidFrame(this);
|
||||
this.androidOverflowEdge = 'ignore';
|
||||
this._defaultOverflowEdge = 1 << 4;
|
||||
this._defaultOverflowEdgeValue = 'dont-apply';
|
||||
}
|
||||
|
||||
public static reloadPage(context?: ModuleContext): void {
|
||||
|
||||
@@ -176,83 +176,56 @@ export function isRealDevice(): boolean {
|
||||
|
||||
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();
|
||||
let statusBarDarkColor: Color | null = null;
|
||||
let statusBarLightColor: Color | null = null;
|
||||
|
||||
export function setStatusBarColor(lightColor: Color | null = null, darkColor: Color | null = null): void {
|
||||
statusBarLightColor = lightColor;
|
||||
statusBarDarkColor = darkColor;
|
||||
const 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);
|
||||
enableEdgeToEdge(activity, {
|
||||
statusBarLightColor: lightColor,
|
||||
statusBarDarkColor: darkColor,
|
||||
navigationBarLightColor,
|
||||
navigationBarDarkColor,
|
||||
handleDarkMode: darkModeHandler,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
let navigationBarDarkColor: Color | null = null;
|
||||
let navigationBarLightColor: Color | null = null;
|
||||
|
||||
setEnableEdgeToEdge(activity, existingColors);
|
||||
export function setNavigationBarColor(lightColor: Color | null = null, darkColor: Color | null = null): void {
|
||||
navigationBarLightColor = lightColor;
|
||||
navigationBarDarkColor = darkColor;
|
||||
const activity = getCurrentActivity();
|
||||
if (activity) {
|
||||
enableEdgeToEdge(activity, {
|
||||
statusBarLightColor,
|
||||
statusBarDarkColor,
|
||||
navigationBarLightColor: navigationBarLightColor,
|
||||
navigationBarDarkColor: navigationBarDarkColor,
|
||||
handleDarkMode: darkModeHandler,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
let darkModeHandler: ((bar: 'status' | 'navigation', resources: android.content.res.Resources) => boolean) | null = null;
|
||||
|
||||
export function setDarkModeHandler(handler: (bar: 'status' | 'navigation', resources: android.content.res.Resources) => boolean): void {
|
||||
darkModeHandler = handler;
|
||||
const 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);
|
||||
enableEdgeToEdge(activity, {
|
||||
statusBarLightColor,
|
||||
statusBarDarkColor,
|
||||
navigationBarLightColor,
|
||||
navigationBarDarkColor,
|
||||
handleDarkMode: handler,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,10 +240,21 @@ export function enableEdgeToEdge(
|
||||
},
|
||||
): 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;
|
||||
let statusBarLight: number = statusBarLightColor?.android ?? 0;
|
||||
let statusBarDark: number = statusBarDarkColor?.android ?? 0;
|
||||
let navigationBarLight: number = navigationBarLightColor?.android ?? DefaultLightScrim.android;
|
||||
let navigationBarDark: number = navigationBarDarkColor?.android ?? DefaultDarkScrim.android;
|
||||
if (darkModeHandler) {
|
||||
handleDarkMode = new org.nativescript.widgets.Utils.HandleDarkMode({
|
||||
onHandle(bar, resources) {
|
||||
if (bar === 0) {
|
||||
return darkModeHandler('status', resources);
|
||||
} else {
|
||||
return darkModeHandler('navigation', resources);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
if (options) {
|
||||
if (typeof options.handleDarkMode === 'function') {
|
||||
handleDarkMode = new org.nativescript.widgets.Utils.HandleDarkMode({
|
||||
|
||||
@@ -26,21 +26,20 @@ public abstract class LayoutBase extends ViewGroup {
|
||||
private boolean passThroughParent;
|
||||
boolean applyingEdges;
|
||||
|
||||
public static final int OverflowEdgeIgnore = -1;
|
||||
public static final int OverflowEdgeNone = 0;
|
||||
public static final int OverflowEdgeLeft = 1 << 1;
|
||||
public static final int OverflowEdgeTop = 1 << 2;
|
||||
public static final int OverflowEdgeRight = 1 << 3;
|
||||
public static final int OverflowEdgeBottom = 1 << 4;
|
||||
public static final int OverflowEdgeDontApply = 1 << 5;
|
||||
public static final int OverflowEdgeLeftDontConsume = 1 << 6;
|
||||
public static final int OverflowEdgeTopDontConsume = 1 << 7;
|
||||
public static final int OverflowEdgeRightDontConsume = 1 << 8;
|
||||
public static final int OverflowEdgeBottomDontConsume = 1 << 9;
|
||||
public static final int OverflowEdgeAllButLeft = 1 << 10;
|
||||
public static final int OverflowEdgeAllButTop = 1 << 11;
|
||||
public static final int OverflowEdgeAllButRight = 1 << 12;
|
||||
public static final int OverflowEdgeAllButBottom = 1 << 13;
|
||||
public static final int OverflowEdgeLeft = 1;
|
||||
public static final int OverflowEdgeTop = 1 << 1;
|
||||
public static final int OverflowEdgeRight = 1 << 2;
|
||||
public static final int OverflowEdgeBottom = 1 << 3;
|
||||
public static final int OverflowEdgeDontApply = 1 << 4;
|
||||
public static final int OverflowEdgeLeftDontConsume = 1 << 5;
|
||||
public static final int OverflowEdgeTopDontConsume = 1 << 6;
|
||||
public static final int OverflowEdgeRightDontConsume = 1 << 7;
|
||||
public static final int OverflowEdgeBottomDontConsume = 1 << 8;
|
||||
public static final int OverflowEdgeAllButLeft = 1 << 9;
|
||||
public static final int OverflowEdgeAllButTop = 1 << 10;
|
||||
public static final int OverflowEdgeAllButRight = 1 << 11;
|
||||
public static final int OverflowEdgeAllButBottom = 1 << 12;
|
||||
|
||||
public static final class BufferOffset {
|
||||
public static final int INSET_LEFT = 0;
|
||||
@@ -54,6 +53,8 @@ public abstract class LayoutBase extends ViewGroup {
|
||||
public static final int INSET_BOTTOM_CONSUMED = 28;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
int mPaddingLeft = 0;
|
||||
int mPaddingTop = 0;
|
||||
int mPaddingRight = 0;
|
||||
@@ -61,12 +62,11 @@ public abstract class LayoutBase extends ViewGroup {
|
||||
|
||||
Insets edgeInsets = Insets.NONE;
|
||||
|
||||
int overflowEdge = OverflowEdgeIgnore;
|
||||
int overflowEdge = OverflowEdgeNone;
|
||||
|
||||
private final ByteBuffer insetBuffer = ByteBuffer.allocateDirect(32);
|
||||
|
||||
private WindowInsetListener insetListener = null;
|
||||
private androidx.core.view.OnApplyWindowInsetsListener windowInsetsListener = null;
|
||||
|
||||
public void setInsetListener(@Nullable WindowInsetListener insetListener) {
|
||||
this.insetListener = insetListener;
|
||||
@@ -98,6 +98,199 @@ public abstract class LayoutBase extends ViewGroup {
|
||||
public LayoutBase(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
insetBuffer.order(ByteOrder.nativeOrder());
|
||||
// if incoming inset is empty and previous inset is empty return consumed
|
||||
// an incoming empty inset is one way to detect a consumed inset e.g multiple views consumed top/bottom
|
||||
androidx.core.view.OnApplyWindowInsetsListener windowInsetsListener = new androidx.core.view.OnApplyWindowInsetsListener() {
|
||||
@NonNull
|
||||
@Override
|
||||
public WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) {
|
||||
if (insets.isConsumed()) {
|
||||
return insets;
|
||||
}
|
||||
if (v instanceof LayoutBase) {
|
||||
LayoutBase base = (LayoutBase) v;
|
||||
|
||||
Insets statusBar = insets.getInsets(WindowInsetsCompat.Type.statusBars());
|
||||
Insets navBar = insets.getInsets(WindowInsetsCompat.Type.navigationBars());
|
||||
Insets ime = insets.getInsets(WindowInsetsCompat.Type.ime());
|
||||
|
||||
int insetLeft = navBar.left;
|
||||
int insetRight = navBar.right;
|
||||
int insetBottom = Math.max(navBar.bottom, ime.bottom);
|
||||
|
||||
insetBuffer.put(EMPTY_INSETS, 0, 32);
|
||||
insetBuffer.rewind();
|
||||
|
||||
if (overflowEdge == OverflowEdgeNone) {
|
||||
base.applyingEdges = true;
|
||||
v.setPadding(mPaddingLeft + insetLeft, mPaddingTop + statusBar.top, mPaddingRight + insetRight, mPaddingBottom + insetBottom);
|
||||
edgeInsets = Insets.of(insetLeft, statusBar.top, insetRight, insetBottom);
|
||||
base.applyingEdges = false;
|
||||
return WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
|
||||
if (base.insetListener != null) {
|
||||
if (overflowEdge == OverflowEdgeDontApply) {
|
||||
// if incoming inset is empty and previous inset is empty return consumed
|
||||
// an incoming empty inset is one way to detect a consumed inset e.g multiple views consumed top/bottom
|
||||
if (Insets.NONE.equals(statusBar) && Insets.NONE.equals(navBar) && Insets.NONE.equals(ime) && Insets.NONE.equals(edgeInsets)) {
|
||||
return WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
|
||||
IntBuffer insetData = insetBuffer.asIntBuffer();
|
||||
|
||||
boolean leftPreviouslyConsumed = insetLeft == 0;
|
||||
boolean topPreviouslyConsumed = statusBar.top == 0;
|
||||
boolean rightPreviouslyConsumed = insetRight == 0;
|
||||
boolean bottomPreviouslyConsumed = insetBottom == 0;
|
||||
|
||||
|
||||
insetData.put(0, insetLeft).put(1, statusBar.top).put(2, insetRight).put(3, insetBottom).put(4, leftPreviouslyConsumed ? 1 : 0).put(5, topPreviouslyConsumed ? 1 : 0).put(6, rightPreviouslyConsumed ? 1 : 0).put(7, bottomPreviouslyConsumed ? 1 : 0);
|
||||
|
||||
base.insetListener.onApplyWindowInsets(insetBuffer);
|
||||
|
||||
int leftInset = insetData.get(0);
|
||||
int topInset = insetData.get(1);
|
||||
int rightInset = insetData.get(2);
|
||||
int bottomInset = insetData.get(3);
|
||||
|
||||
boolean leftConsumed = insetData.get(4) > 0;
|
||||
boolean topConsumed = insetData.get(5) > 0;
|
||||
boolean rightConsumed = insetData.get(6) > 0;
|
||||
boolean bottomConsumed = insetData.get(7) > 0;
|
||||
|
||||
if (leftConsumed && topConsumed && rightConsumed && bottomConsumed) {
|
||||
edgeInsets = Insets.of(leftInset, topInset, rightInset, bottomInset);
|
||||
base.setPadding(leftInset, topInset, rightInset, bottomInset);
|
||||
return new WindowInsetsCompat.Builder().setInsets(WindowInsetsCompat.Type.systemBars(), Insets.NONE).build();
|
||||
}
|
||||
|
||||
base.setPadding(leftPreviouslyConsumed ? 0 : leftInset, topPreviouslyConsumed ? 0 : topInset, rightPreviouslyConsumed ? 0 : rightInset, bottomPreviouslyConsumed ? 0 : bottomInset);
|
||||
|
||||
// restore inset edge if not consumed
|
||||
|
||||
if (!(leftPreviouslyConsumed || leftConsumed)) {
|
||||
leftInset = insetLeft;
|
||||
}
|
||||
|
||||
if (!(topPreviouslyConsumed || topConsumed)) {
|
||||
topInset = statusBar.top;
|
||||
}
|
||||
|
||||
if (!(rightPreviouslyConsumed || rightConsumed)) {
|
||||
rightInset = insetRight;
|
||||
}
|
||||
|
||||
if (!(bottomPreviouslyConsumed || bottomConsumed)) {
|
||||
bottomInset = insetBottom;
|
||||
}
|
||||
|
||||
edgeInsets = Insets.of(leftPreviouslyConsumed ? 0 : leftInset, topPreviouslyConsumed ? 0 : topInset, rightPreviouslyConsumed ? 0 : rightInset, bottomPreviouslyConsumed ? 0 : bottomInset);
|
||||
|
||||
return new WindowInsetsCompat.Builder().setInsets(WindowInsetsCompat.Type.systemBars(), Insets.of(leftPreviouslyConsumed || leftConsumed ? 0 : leftInset, topPreviouslyConsumed || topConsumed ? 0 : topInset, rightPreviouslyConsumed || rightConsumed ? 0 : rightInset, bottomPreviouslyConsumed || bottomConsumed ? 0 : bottomInset)).build();
|
||||
}
|
||||
}
|
||||
|
||||
boolean overflowLeftConsume = (overflowEdge & OverflowEdgeLeft) == OverflowEdgeLeft;
|
||||
boolean overflowTopConsume = (overflowEdge & OverflowEdgeTop) == OverflowEdgeTop;
|
||||
boolean overflowRightConsume = (overflowEdge & OverflowEdgeRight) == OverflowEdgeRight;
|
||||
boolean overflowBottomConsume = (overflowEdge & OverflowEdgeBottom) == OverflowEdgeBottom;
|
||||
|
||||
boolean overflowLeft = (overflowEdge & OverflowEdgeLeftDontConsume) == OverflowEdgeLeftDontConsume;
|
||||
boolean overflowTop = (overflowEdge & OverflowEdgeTopDontConsume) == OverflowEdgeTopDontConsume;
|
||||
boolean overflowRight = (overflowEdge & OverflowEdgeRightDontConsume) == OverflowEdgeRightDontConsume;
|
||||
boolean overflowBottom = (overflowEdge & OverflowEdgeBottomDontConsume) == OverflowEdgeBottomDontConsume;
|
||||
|
||||
|
||||
boolean overflowAllButLeft = (overflowEdge & OverflowEdgeAllButLeft) == OverflowEdgeAllButLeft;
|
||||
boolean overflowAllButTop = (overflowEdge & OverflowEdgeAllButTop) == OverflowEdgeAllButTop;
|
||||
boolean overflowAllButRight = (overflowEdge & OverflowEdgeAllButRight) == OverflowEdgeAllButRight;
|
||||
boolean overflowAllButBottom = (overflowEdge & OverflowEdgeAllButBottom) == OverflowEdgeAllButBottom;
|
||||
|
||||
|
||||
WindowInsetsCompat ret = insets;
|
||||
base.applyingEdges = true;
|
||||
int left = 0;
|
||||
int top = 0;
|
||||
int right = 0;
|
||||
int bottom = 0;
|
||||
|
||||
|
||||
if (overflowAllButLeft || overflowAllButTop || overflowAllButRight || overflowAllButBottom) {
|
||||
Insets newInset;
|
||||
if (overflowAllButLeft) {
|
||||
left = mPaddingLeft + insetLeft;
|
||||
edgeInsets = Insets.of(insetLeft, 0, 0, 0);
|
||||
newInset = Insets.of(0, statusBar.top, insetRight, insetBottom);
|
||||
} else if (overflowAllButTop) {
|
||||
top = mPaddingTop + statusBar.top;
|
||||
edgeInsets = Insets.of(0, statusBar.top, 0, 0);
|
||||
newInset = Insets.of(insetLeft, 0, insetRight, insetBottom);
|
||||
} else if (overflowAllButRight) {
|
||||
right = mPaddingRight + insetRight;
|
||||
edgeInsets = Insets.of(0, 0, insetRight, 0);
|
||||
newInset = Insets.of(insetLeft, statusBar.top, 0, insetBottom);
|
||||
} else {
|
||||
bottom = mPaddingBottom + insetBottom;
|
||||
edgeInsets = Insets.of(0, 0, 0, insetBottom);
|
||||
newInset = Insets.of(insetLeft, statusBar.top, insetRight, 0);
|
||||
}
|
||||
|
||||
ret = new WindowInsetsCompat.Builder().setInsets(WindowInsetsCompat.Type.systemBars(), newInset).build();
|
||||
base.setPadding(left, top, right, bottom);
|
||||
base.applyingEdges = false;
|
||||
if (newInset == Insets.NONE) {
|
||||
return WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (overflowLeftConsume || overflowLeft) {
|
||||
top = mPaddingTop + statusBar.top;
|
||||
right = mPaddingRight + insetRight;
|
||||
bottom = mPaddingBottom + insetBottom;
|
||||
edgeInsets = Insets.of(insetLeft, statusBar.top, insetRight, insetBottom);
|
||||
if (overflowRightConsume) {
|
||||
ret = WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
}
|
||||
if (overflowTopConsume || overflowTop) {
|
||||
left = mPaddingLeft + insetLeft;
|
||||
right = mPaddingRight + insetRight;
|
||||
bottom = mPaddingBottom + insetBottom;
|
||||
edgeInsets = Insets.of(insetLeft, statusBar.top, insetRight, insetBottom);
|
||||
if (overflowTopConsume) {
|
||||
ret = WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
}
|
||||
if (overflowRightConsume || overflowRight) {
|
||||
left = mPaddingLeft + insetLeft;
|
||||
top = mPaddingTop + statusBar.top;
|
||||
bottom = mPaddingBottom + insetBottom;
|
||||
edgeInsets = Insets.of(insetLeft, statusBar.top, insetRight, insetBottom);
|
||||
if (overflowRightConsume) {
|
||||
ret = WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
}
|
||||
if (overflowBottomConsume || overflowBottom) {
|
||||
left = mPaddingLeft + insetLeft;
|
||||
top = mPaddingTop + statusBar.top;
|
||||
right = mPaddingRight + insetRight;
|
||||
edgeInsets = Insets.of(insetLeft, statusBar.top, insetRight, insetBottom);
|
||||
if (overflowBottomConsume) {
|
||||
ret = WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
}
|
||||
|
||||
base.setPadding(left, top, right, bottom);
|
||||
|
||||
base.applyingEdges = false;
|
||||
return ret;
|
||||
}
|
||||
return insets;
|
||||
}
|
||||
};
|
||||
ViewCompat.setOnApplyWindowInsetsListener(this, windowInsetsListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,6 +300,7 @@ public abstract class LayoutBase extends ViewGroup {
|
||||
|
||||
public LayoutBase(Context context) {
|
||||
super(context);
|
||||
|
||||
}
|
||||
|
||||
public Insets getEdgeInsets() {
|
||||
@@ -200,210 +394,6 @@ public abstract class LayoutBase extends ViewGroup {
|
||||
|
||||
public void setOverflowEdge(int value) {
|
||||
overflowEdge = value;
|
||||
|
||||
if (value == OverflowEdgeIgnore) {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(this, null);
|
||||
} else if (windowInsetsListener == null) {
|
||||
// if incoming inset is empty and previous inset is empty return consumed
|
||||
// an incoming empty inset is one way to detect a consumed inset e.g multiple views consumed top/bottom
|
||||
windowInsetsListener = new androidx.core.view.OnApplyWindowInsetsListener() {
|
||||
@NonNull
|
||||
@Override
|
||||
public WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) {
|
||||
if (insets.isConsumed()) {
|
||||
return insets;
|
||||
}
|
||||
if (v instanceof LayoutBase) {
|
||||
LayoutBase base = (LayoutBase) v;
|
||||
|
||||
// should not occur but if it does return the inset
|
||||
if (overflowEdge == OverflowEdgeIgnore) {
|
||||
return insets;
|
||||
}
|
||||
|
||||
Insets statusBar = insets.getInsets(WindowInsetsCompat.Type.statusBars());
|
||||
Insets navBar = insets.getInsets(WindowInsetsCompat.Type.navigationBars());
|
||||
Insets ime = insets.getInsets(WindowInsetsCompat.Type.ime());
|
||||
|
||||
int insetLeft = navBar.left;
|
||||
int insetRight = navBar.right;
|
||||
int insetBottom = Math.max(navBar.bottom, ime.bottom);
|
||||
|
||||
insetBuffer.put(EMPTY_INSETS, 0, 32);
|
||||
insetBuffer.rewind();
|
||||
|
||||
if (overflowEdge == OverflowEdgeNone) {
|
||||
base.applyingEdges = true;
|
||||
v.setPadding(mPaddingLeft + insetLeft, mPaddingTop + statusBar.top, mPaddingRight + insetRight, mPaddingBottom + insetBottom);
|
||||
edgeInsets = Insets.of(insetLeft, statusBar.top, insetRight, insetBottom);
|
||||
base.applyingEdges = false;
|
||||
return WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
|
||||
if (base.insetListener != null) {
|
||||
if (overflowEdge == OverflowEdgeDontApply) {
|
||||
// if incoming inset is empty and previous inset is empty return consumed
|
||||
// an incoming empty inset is one way to detect a consumed inset e.g multiple views consumed top/bottom
|
||||
if (Insets.NONE.equals(statusBar) && Insets.NONE.equals(navBar) && Insets.NONE.equals(ime) && Insets.NONE.equals(edgeInsets)) {
|
||||
return WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
|
||||
IntBuffer insetData = insetBuffer.asIntBuffer();
|
||||
|
||||
boolean leftPreviouslyConsumed = insetLeft == 0;
|
||||
boolean topPreviouslyConsumed = statusBar.top == 0;
|
||||
boolean rightPreviouslyConsumed = insetRight == 0;
|
||||
boolean bottomPreviouslyConsumed = insetBottom == 0;
|
||||
|
||||
|
||||
insetData.put(0, insetLeft).put(1, statusBar.top).put(2, insetRight).put(3, insetBottom).put(4, leftPreviouslyConsumed ? 1 : 0).put(5, topPreviouslyConsumed ? 1 : 0).put(6, rightPreviouslyConsumed ? 1 : 0).put(7, bottomPreviouslyConsumed ? 1 : 0);
|
||||
|
||||
base.insetListener.onApplyWindowInsets(insetBuffer);
|
||||
|
||||
int leftInset = insetData.get(0);
|
||||
int topInset = insetData.get(1);
|
||||
int rightInset = insetData.get(2);
|
||||
int bottomInset = insetData.get(3);
|
||||
|
||||
boolean leftConsumed = insetData.get(4) > 0;
|
||||
boolean topConsumed = insetData.get(5) > 0;
|
||||
boolean rightConsumed = insetData.get(6) > 0;
|
||||
boolean bottomConsumed = insetData.get(7) > 0;
|
||||
|
||||
if (leftConsumed && topConsumed && rightConsumed && bottomConsumed) {
|
||||
edgeInsets = Insets.of(leftInset, topInset, rightInset, bottomInset);
|
||||
base.setPadding(leftInset, topInset, rightInset, bottomInset);
|
||||
return new WindowInsetsCompat.Builder().setInsets(WindowInsetsCompat.Type.systemBars(), Insets.NONE).build();
|
||||
}
|
||||
|
||||
base.setPadding(leftPreviouslyConsumed ? 0 : leftInset, topPreviouslyConsumed ? 0 : topInset, rightPreviouslyConsumed ? 0 : rightInset, bottomPreviouslyConsumed ? 0 : bottomInset);
|
||||
|
||||
// restore inset edge if not consumed
|
||||
|
||||
if (!(leftPreviouslyConsumed || leftConsumed)) {
|
||||
leftInset = insetLeft;
|
||||
}
|
||||
|
||||
if (!(topPreviouslyConsumed || topConsumed)) {
|
||||
topInset = statusBar.top;
|
||||
}
|
||||
|
||||
if (!(rightPreviouslyConsumed || rightConsumed)) {
|
||||
rightInset = insetRight;
|
||||
}
|
||||
|
||||
if (!(bottomPreviouslyConsumed || bottomConsumed)) {
|
||||
bottomInset = insetBottom;
|
||||
}
|
||||
|
||||
edgeInsets = Insets.of(leftPreviouslyConsumed ? 0 : leftInset, topPreviouslyConsumed ? 0 : topInset, rightPreviouslyConsumed ? 0 : rightInset, bottomPreviouslyConsumed ? 0 : bottomInset);
|
||||
|
||||
return new WindowInsetsCompat.Builder().setInsets(WindowInsetsCompat.Type.systemBars(), Insets.of(leftPreviouslyConsumed || leftConsumed ? 0 : leftInset, topPreviouslyConsumed || topConsumed ? 0 : topInset, rightPreviouslyConsumed || rightConsumed ? 0 : rightInset, bottomPreviouslyConsumed || bottomConsumed ? 0 : bottomInset)).build();
|
||||
}
|
||||
}
|
||||
|
||||
boolean overflowLeftConsume = (overflowEdge & OverflowEdgeLeft) == OverflowEdgeLeft;
|
||||
boolean overflowTopConsume = (overflowEdge & OverflowEdgeTop) == OverflowEdgeTop;
|
||||
boolean overflowRightConsume = (overflowEdge & OverflowEdgeRight) == OverflowEdgeRight;
|
||||
boolean overflowBottomConsume = (overflowEdge & OverflowEdgeBottom) == OverflowEdgeBottom;
|
||||
|
||||
boolean overflowLeft = (overflowEdge & OverflowEdgeLeftDontConsume) == OverflowEdgeLeftDontConsume;
|
||||
boolean overflowTop = (overflowEdge & OverflowEdgeTopDontConsume) == OverflowEdgeTopDontConsume;
|
||||
boolean overflowRight = (overflowEdge & OverflowEdgeRightDontConsume) == OverflowEdgeRightDontConsume;
|
||||
boolean overflowBottom = (overflowEdge & OverflowEdgeBottomDontConsume) == OverflowEdgeBottomDontConsume;
|
||||
|
||||
|
||||
boolean overflowAllButLeft = (overflowEdge & OverflowEdgeAllButLeft) == OverflowEdgeAllButLeft;
|
||||
boolean overflowAllButTop = (overflowEdge & OverflowEdgeAllButTop) == OverflowEdgeAllButTop;
|
||||
boolean overflowAllButRight = (overflowEdge & OverflowEdgeAllButRight) == OverflowEdgeAllButRight;
|
||||
boolean overflowAllButBottom = (overflowEdge & OverflowEdgeAllButBottom) == OverflowEdgeAllButBottom;
|
||||
|
||||
|
||||
WindowInsetsCompat ret = insets;
|
||||
base.applyingEdges = true;
|
||||
int left = 0;
|
||||
int top = 0;
|
||||
int right = 0;
|
||||
int bottom = 0;
|
||||
|
||||
|
||||
if (overflowAllButLeft || overflowAllButTop || overflowAllButRight || overflowAllButBottom) {
|
||||
Insets newInset;
|
||||
if (overflowAllButLeft) {
|
||||
left = mPaddingLeft + insetLeft;
|
||||
edgeInsets = Insets.of(insetLeft, 0, 0, 0);
|
||||
newInset = Insets.of(0, statusBar.top, insetRight, insetBottom);
|
||||
} else if (overflowAllButTop) {
|
||||
top = mPaddingTop + statusBar.top;
|
||||
edgeInsets = Insets.of(0, statusBar.top, 0, 0);
|
||||
newInset = Insets.of(insetLeft, 0, insetRight, insetBottom);
|
||||
} else if (overflowAllButRight) {
|
||||
right = mPaddingRight + insetRight;
|
||||
edgeInsets = Insets.of(0, 0, insetRight, 0);
|
||||
newInset = Insets.of(insetLeft, statusBar.top, 0, insetBottom);
|
||||
} else {
|
||||
bottom = mPaddingBottom + insetBottom;
|
||||
edgeInsets = Insets.of(0, 0, 0, insetBottom);
|
||||
newInset = Insets.of(insetLeft, statusBar.top, insetRight, 0);
|
||||
}
|
||||
|
||||
ret = new WindowInsetsCompat.Builder().setInsets(WindowInsetsCompat.Type.systemBars(), newInset).build();
|
||||
base.setPadding(left, top, right, bottom);
|
||||
base.applyingEdges = false;
|
||||
if (newInset == Insets.NONE) {
|
||||
return WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (overflowLeftConsume || overflowLeft) {
|
||||
top = mPaddingTop + statusBar.top;
|
||||
right = mPaddingRight + insetRight;
|
||||
bottom = mPaddingBottom + insetBottom;
|
||||
edgeInsets = Insets.of(insetLeft, statusBar.top, insetRight, insetBottom);
|
||||
if (overflowRightConsume) {
|
||||
ret = WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
}
|
||||
if (overflowTopConsume || overflowTop) {
|
||||
left = mPaddingLeft + insetLeft;
|
||||
right = mPaddingRight + insetRight;
|
||||
bottom = mPaddingBottom + insetBottom;
|
||||
edgeInsets = Insets.of(insetLeft, statusBar.top, insetRight, insetBottom);
|
||||
if (overflowTopConsume) {
|
||||
ret = WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
}
|
||||
if (overflowRightConsume || overflowRight) {
|
||||
left = mPaddingLeft + insetLeft;
|
||||
top = mPaddingTop + statusBar.top;
|
||||
bottom = mPaddingBottom + insetBottom;
|
||||
edgeInsets = Insets.of(insetLeft, statusBar.top, insetRight, insetBottom);
|
||||
if (overflowRightConsume) {
|
||||
ret = WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
}
|
||||
if (overflowBottomConsume || overflowBottom) {
|
||||
left = mPaddingLeft + insetLeft;
|
||||
top = mPaddingTop + statusBar.top;
|
||||
right = mPaddingRight + insetRight;
|
||||
edgeInsets = Insets.of(insetLeft, statusBar.top, insetRight, insetBottom);
|
||||
if (overflowBottomConsume) {
|
||||
ret = WindowInsetsCompat.CONSUMED;
|
||||
}
|
||||
}
|
||||
|
||||
base.setPadding(left, top, right, bottom);
|
||||
|
||||
base.applyingEdges = false;
|
||||
return ret;
|
||||
}
|
||||
return insets;
|
||||
}
|
||||
};
|
||||
ViewCompat.setOnApplyWindowInsetsListener(this, windowInsetsListener);
|
||||
}
|
||||
|
||||
if (pendingInsetApply) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user