mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-14 18:12:09 +08:00
chore(edge-to-edge): refactor API
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
|
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page" androidOverflowEdge="none" >
|
||||||
<Page.actionBar>
|
<Page.actionBar>
|
||||||
<ActionBar title="Dev Toolbox" icon="" class="action-bar" iosLargeTitle="true" iosShadow="false">
|
<ActionBar title="Dev Toolbox" icon="" class="action-bar" iosLargeTitle="true" iosShadow="false">
|
||||||
</ActionBar>
|
</ActionBar>
|
||||||
@ -31,3 +31,4 @@
|
|||||||
</ScrollView>
|
</ScrollView>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Observable, Frame, StackLayout } from '@nativescript/core';
|
import { Observable, Frame, StackLayout, AndroidOverflowInsetData } from '@nativescript/core';
|
||||||
|
|
||||||
export class HelloWorldModel extends Observable {
|
export class HelloWorldModel extends Observable {
|
||||||
viewDemo(args) {
|
viewDemo(args) {
|
||||||
@ -6,4 +6,16 @@ export class HelloWorldModel extends Observable {
|
|||||||
moduleName: `pages/${args.object.text}`,
|
moduleName: `pages/${args.object.text}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onInset(args: AndroidOverflowInsetData) {
|
||||||
|
args.inset.top += 10; // add 10px to the top inset
|
||||||
|
args.inset.bottom += 10; // add 10px to the bottom inset
|
||||||
|
args.inset.left += 10; // add 10px to the left inset
|
||||||
|
args.inset.right += 10; // add 10px to the right inset
|
||||||
|
|
||||||
|
args.inset.topConsumed = true; // consume the top inset
|
||||||
|
args.inset.bottomConsumed = true; // consume the bottom inset
|
||||||
|
args.inset.leftConsumed = true; // consume the left inset
|
||||||
|
args.inset.rightConsumed = true; // consume the right inset
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -314,6 +314,120 @@ function getModalOptions(domId: number): DialogOptions {
|
|||||||
return modalMap.get(domId);
|
return modalMap.get(domId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const INSET_LEFT = 0;
|
||||||
|
const INSET_TOP = 4;
|
||||||
|
const INSET_RIGHT = 8;
|
||||||
|
const INSET_BOTTOM = 12;
|
||||||
|
const INSET_LEFT_CONSUMED = 16;
|
||||||
|
const INSET_TOP_CONSUMED = 20;
|
||||||
|
const INSET_RIGHT_CONSUMED = 24;
|
||||||
|
const INSET_BOTTOM_CONSUMED = 28;
|
||||||
|
|
||||||
|
const OverflowEdgeNone: number = 0;
|
||||||
|
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;
|
||||||
|
private data: ArrayBuffer;
|
||||||
|
constructor(data: java.nio.ByteBuffer) {
|
||||||
|
this.data = (<any>ArrayBuffer).from(data);
|
||||||
|
this.view = new DataView(this.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get left(): number {
|
||||||
|
return this.view.getInt32(INSET_LEFT, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public set left(value: number) {
|
||||||
|
this.view.setInt32(INSET_LEFT, value, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get top(): number {
|
||||||
|
return this.view.getInt32(INSET_TOP, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public set top(value: number) {
|
||||||
|
this.view.setInt32(INSET_TOP, value, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get right(): number {
|
||||||
|
return this.view.getInt32(INSET_RIGHT, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public set right(value: number) {
|
||||||
|
this.view.setInt32(INSET_RIGHT, value, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get bottom(): number {
|
||||||
|
return this.view.getInt32(INSET_BOTTOM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public set bottom(value: number) {
|
||||||
|
this.view.setInt32(INSET_BOTTOM, value, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get leftConsumed(): boolean {
|
||||||
|
return this.view.getInt32(INSET_LEFT_CONSUMED, true) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set leftConsumed(value: boolean) {
|
||||||
|
this.view.setInt32(INSET_LEFT_CONSUMED, value ? 1 : 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get topConsumed(): boolean {
|
||||||
|
return this.view.getInt32(INSET_TOP_CONSUMED, true) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set topConsumed(value: boolean) {
|
||||||
|
this.view.setInt32(INSET_TOP_CONSUMED, value ? 1 : 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get rightConsumed(): boolean {
|
||||||
|
return this.view.getInt32(INSET_RIGHT_CONSUMED, true) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set rightConsumed(value: boolean) {
|
||||||
|
this.view.setInt32(INSET_RIGHT_CONSUMED, value ? 1 : 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get bottomConsumed(): boolean {
|
||||||
|
return this.view.getInt32(INSET_BOTTOM_CONSUMED, true) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set bottomConsumed(value: boolean) {
|
||||||
|
this.view.setInt32(INSET_BOTTOM_CONSUMED, value ? 1 : 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return `Inset: left=${this.left}, top=${this.top}, right=${this.right}, bottom=${this.bottom}, ` + `leftConsumed=${this.leftConsumed}, topConsumed=${this.topConsumed}, ` + `rightConsumed=${this.rightConsumed}, bottomConsumed=${this.bottomConsumed}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON() {
|
||||||
|
return {
|
||||||
|
left: this.left,
|
||||||
|
top: this.top,
|
||||||
|
right: this.right,
|
||||||
|
bottom: this.bottom,
|
||||||
|
leftConsumed: this.leftConsumed,
|
||||||
|
topConsumed: this.topConsumed,
|
||||||
|
rightConsumed: this.rightConsumed,
|
||||||
|
bottomConsumed: this.bottomConsumed,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class View extends ViewCommon {
|
export class View extends ViewCommon {
|
||||||
public static androidBackPressedEvent = androidBackPressedEvent;
|
public static androidBackPressedEvent = androidBackPressedEvent;
|
||||||
|
|
||||||
@ -324,6 +438,8 @@ export class View extends ViewCommon {
|
|||||||
private layoutChangeListenerIsSet: boolean;
|
private layoutChangeListenerIsSet: boolean;
|
||||||
private layoutChangeListener: android.view.View.OnLayoutChangeListener;
|
private layoutChangeListener: android.view.View.OnLayoutChangeListener;
|
||||||
private _rootManager: androidx.fragment.app.FragmentManager;
|
private _rootManager: androidx.fragment.app.FragmentManager;
|
||||||
|
private insetListenerIsSet: boolean;
|
||||||
|
private needsInsetListener: boolean;
|
||||||
|
|
||||||
nativeViewProtected: android.view.View;
|
nativeViewProtected: android.view.View;
|
||||||
|
|
||||||
@ -342,6 +458,12 @@ export class View extends ViewCommon {
|
|||||||
if (this.isLoaded && !this.layoutChangeListenerIsSet && isLayoutEvent) {
|
if (this.isLoaded && !this.layoutChangeListenerIsSet && isLayoutEvent) {
|
||||||
this.setOnLayoutChangeListener();
|
this.setOnLayoutChangeListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isInsetEvent = typeof eventNames === 'string' ? eventNames.indexOf(ViewCommon.androidOverflowInsetEvent) !== -1 : false;
|
||||||
|
// only avaiable on LayoutBase
|
||||||
|
if (!this.insetListenerIsSet && isInsetEvent) {
|
||||||
|
this.setInsetListener();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeEventListener(eventNames: string, callback?: (data: EventData) => void, thisArg?: any) {
|
removeEventListener(eventNames: string, callback?: (data: EventData) => void, thisArg?: any) {
|
||||||
@ -353,6 +475,43 @@ export class View extends ViewCommon {
|
|||||||
this.nativeViewProtected.removeOnLayoutChangeListener(this.layoutChangeListener);
|
this.nativeViewProtected.removeOnLayoutChangeListener(this.layoutChangeListener);
|
||||||
this.layoutChangeListenerIsSet = false;
|
this.layoutChangeListenerIsSet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isInsetEvent = typeof eventNames === 'string' ? eventNames.indexOf(ViewCommon.androidOverflowInsetEvent) !== -1 : false;
|
||||||
|
|
||||||
|
if (this.insetListenerIsSet && isInsetEvent && this.nativeViewProtected && (this.nativeViewProtected as any).setInsetListener) {
|
||||||
|
(this.nativeViewProtected as any).setInsetListener(null);
|
||||||
|
this.insetListenerIsSet = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private setInsetListener() {
|
||||||
|
if (this.nativeViewProtected) {
|
||||||
|
if ((this.nativeViewProtected as any).setInsetListener) {
|
||||||
|
const ref = new WeakRef(this);
|
||||||
|
(this.nativeViewProtected as any).setInsetListener(
|
||||||
|
new org.nativescript.widgets.LayoutBase.WindowInsetListener({
|
||||||
|
onApplyWindowInsets(param0) {
|
||||||
|
const owner = ref.get();
|
||||||
|
if (!owner) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const inset = new Inset(param0);
|
||||||
|
const args = {
|
||||||
|
eventName: ViewCommon.androidOverflowInsetEvent,
|
||||||
|
object: this,
|
||||||
|
inset,
|
||||||
|
};
|
||||||
|
owner.notify(args);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
this.insetListenerIsSet = true;
|
||||||
|
}
|
||||||
|
this.needsInsetListener = false;
|
||||||
|
} else {
|
||||||
|
this.needsInsetListener = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public _getChildFragmentManager(): androidx.fragment.app.FragmentManager {
|
public _getChildFragmentManager(): androidx.fragment.app.FragmentManager {
|
||||||
@ -413,6 +572,134 @@ export class View extends ViewCommon {
|
|||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 (nativeView && nativeView.setOverflowEdge) {
|
||||||
|
if (value === 'none') {
|
||||||
|
nativeView.setOverflowEdge(OverflowEdgeNone);
|
||||||
|
} else {
|
||||||
|
const newValue = parseEdges(value);
|
||||||
|
if (newValue !== null) {
|
||||||
|
nativeView.setOverflowEdge(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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
|
@profile
|
||||||
public onLoaded() {
|
public onLoaded() {
|
||||||
this._manager = null;
|
this._manager = null;
|
||||||
@ -462,6 +749,17 @@ export class View extends ViewCommon {
|
|||||||
if (this.needsOnLayoutChangeListener()) {
|
if (this.needsOnLayoutChangeListener()) {
|
||||||
this.setOnLayoutChangeListener();
|
this.setOnLayoutChangeListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
public needsOnLayoutChangeListener() {
|
||||||
@ -1267,8 +1565,119 @@ export class View extends ViewCommon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseEdges(edges: string): number | null {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newValue === -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
|
||||||
export class ContainerView extends View {
|
export class ContainerView extends View {
|
||||||
public iosOverflowSafeArea: boolean;
|
public iosOverflowSafeArea: boolean;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this._defaultOverflowEdge = OverflowEdgeDontApply;
|
||||||
|
this._defaultOverflowEdgeValue = 'dont-apply';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CustomLayoutView extends ContainerView implements CustomLayoutViewDefinition {
|
export class CustomLayoutView extends ContainerView implements CustomLayoutViewDefinition {
|
||||||
|
33
packages/core/ui/core/view/index.d.ts
vendored
33
packages/core/ui/core/view/index.d.ts
vendored
@ -19,6 +19,17 @@ export * from '../properties';
|
|||||||
|
|
||||||
export function PseudoClassHandler(...pseudoClasses: string[]): MethodDecorator;
|
export function PseudoClassHandler(...pseudoClasses: string[]): MethodDecorator;
|
||||||
|
|
||||||
|
export interface Inset {
|
||||||
|
top: number;
|
||||||
|
right: number;
|
||||||
|
bottom: number;
|
||||||
|
left: number;
|
||||||
|
topConsumed: boolean;
|
||||||
|
rightConsumed: boolean;
|
||||||
|
bottomConsumed: boolean;
|
||||||
|
leftConsumed: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the type name for the instances of this View class,
|
* Specifies the type name for the instances of this View class,
|
||||||
* that is used when matching CSS type selectors.
|
* that is used when matching CSS type selectors.
|
||||||
@ -104,6 +115,16 @@ export interface ShownModallyData extends EventData {
|
|||||||
closeCallback?: Function;
|
closeCallback?: Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the data for the androidOverflowInset event.
|
||||||
|
*/
|
||||||
|
export interface AndroidOverflowInsetData extends EventData {
|
||||||
|
/**
|
||||||
|
* The inset values passed to the view to consume or update.
|
||||||
|
*/
|
||||||
|
inset?: Inset;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the base class for all UI components.
|
* This class is the base class for all UI components.
|
||||||
* A View occupies a rectangular area on the screen and is responsible for drawing and layouting of all UI components within.
|
* A View occupies a rectangular area on the screen and is responsible for drawing and layouting of all UI components within.
|
||||||
@ -152,6 +173,13 @@ export abstract class View extends ViewCommon {
|
|||||||
*/
|
*/
|
||||||
public static accessibilityFocusChangedEvent: string;
|
public static accessibilityFocusChangedEvent: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String value used when hooking to androidOverflowInset event.
|
||||||
|
*
|
||||||
|
* @nsEvent {EventDataValue} androidOverflowInset
|
||||||
|
*/
|
||||||
|
public static androidOverflowInsetEvent: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the android-specific native instance that lies behind this proxy. Will be available if running on an Android platform.
|
* Gets the android-specific native instance that lies behind this proxy. Will be available if running on an Android platform.
|
||||||
*/
|
*/
|
||||||
@ -846,6 +874,11 @@ export abstract class View extends ViewCommon {
|
|||||||
*/
|
*/
|
||||||
on(event: 'shownModally', callback: (args: ShownModallyData) => void, thisArg?: any);
|
on(event: 'shownModally', callback: (args: ShownModallyData) => void, thisArg?: any);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raised after the view is shown as a modal dialog.
|
||||||
|
*/
|
||||||
|
on(event: 'androidOverflowInset', callback: (args: ShownModallyData) => void, thisArg?: any);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current modal view that this page is showing (is parent of), if any.
|
* Returns the current modal view that this page is showing (is parent of), if any.
|
||||||
*/
|
*/
|
||||||
|
@ -86,6 +86,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
|||||||
public static accessibilityFocusEvent = accessibilityFocusEvent;
|
public static accessibilityFocusEvent = accessibilityFocusEvent;
|
||||||
public static accessibilityFocusChangedEvent = accessibilityFocusChangedEvent;
|
public static accessibilityFocusChangedEvent = accessibilityFocusChangedEvent;
|
||||||
public static accessibilityPerformEscapeEvent = accessibilityPerformEscapeEvent;
|
public static accessibilityPerformEscapeEvent = accessibilityPerformEscapeEvent;
|
||||||
|
public static androidOverflowInsetEvent = 'androidOverflowInset';
|
||||||
|
|
||||||
public accessibilityIdentifier: string;
|
public accessibilityIdentifier: string;
|
||||||
public accessibilityLabel: string;
|
public accessibilityLabel: string;
|
||||||
@ -986,6 +987,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
|||||||
public iosOverflowSafeArea: boolean;
|
public iosOverflowSafeArea: boolean;
|
||||||
public iosOverflowSafeAreaEnabled: boolean;
|
public iosOverflowSafeAreaEnabled: boolean;
|
||||||
public iosIgnoreSafeArea: boolean;
|
public iosIgnoreSafeArea: boolean;
|
||||||
|
public androidOverflowEdge: string;
|
||||||
|
|
||||||
get isLayoutValid(): boolean {
|
get isLayoutValid(): boolean {
|
||||||
return this._isLayoutValid;
|
return this._isLayoutValid;
|
||||||
|
@ -2,7 +2,7 @@ import '../../globals';
|
|||||||
import { setActivityCallbacks } from '.';
|
import { setActivityCallbacks } from '.';
|
||||||
import { Application } from '../../application';
|
import { Application } from '../../application';
|
||||||
import { isEmbedded } from '../embedding';
|
import { isEmbedded } from '../embedding';
|
||||||
|
import { enableEdgeToEdge } from '../../utils/android';
|
||||||
const EMPTY_FN = () => {};
|
const EMPTY_FN = () => {};
|
||||||
declare const com: any;
|
declare const com: any;
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ if (!isEmbedded()) {
|
|||||||
// Set isNativeScriptActivity in onCreate.
|
// Set isNativeScriptActivity in onCreate.
|
||||||
// The JS constructor might not be called because the activity is created from Android.
|
// The JS constructor might not be called because the activity is created from Android.
|
||||||
this.isNativeScriptActivity = true;
|
this.isNativeScriptActivity = true;
|
||||||
|
enableEdgeToEdge(this);
|
||||||
if (!this._callbacks) {
|
if (!this._callbacks) {
|
||||||
setActivityCallbacks(this);
|
setActivityCallbacks(this);
|
||||||
}
|
}
|
||||||
@ -78,6 +79,7 @@ if (!isEmbedded()) {
|
|||||||
// Set isNativeScriptActivity in onCreate.
|
// Set isNativeScriptActivity in onCreate.
|
||||||
// The JS constructor might not be called because the activity is created from Android.
|
// The JS constructor might not be called because the activity is created from Android.
|
||||||
activity.isNativeScriptActivity = true;
|
activity.isNativeScriptActivity = true;
|
||||||
|
enableEdgeToEdge(this);
|
||||||
if (!activity._callbacks) {
|
if (!activity._callbacks) {
|
||||||
setActivityCallbacks(activity);
|
setActivityCallbacks(activity);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ export { ControlStateChangeListener } from './core/control-state-change';
|
|||||||
export { ViewBase, eachDescendant, getAncestor, getViewById, booleanConverter, querySelectorAll } from './core/view-base';
|
export { ViewBase, eachDescendant, getAncestor, getViewById, booleanConverter, querySelectorAll } from './core/view-base';
|
||||||
export type { ShowModalOptions } from './core/view-base';
|
export type { ShowModalOptions } from './core/view-base';
|
||||||
export { View, CSSType, ContainerView, ViewHelper, AndroidHelper, IOSHelper, isUserInteractionEnabledProperty, PseudoClassHandler, CustomLayoutView } from './core/view';
|
export { View, CSSType, ContainerView, ViewHelper, AndroidHelper, IOSHelper, isUserInteractionEnabledProperty, PseudoClassHandler, CustomLayoutView } from './core/view';
|
||||||
export type { Template, KeyedTemplate, ShownModallyData, AddArrayFromBuilder, AddChildFromBuilder, Size } from './core/view';
|
export type { Template, KeyedTemplate, ShownModallyData, AddArrayFromBuilder, AddChildFromBuilder, Size, AndroidOverflowInsetData } from './core/view';
|
||||||
export { Property, CoercibleProperty, InheritedProperty, CssProperty, InheritedCssProperty, ShorthandProperty, CssAnimationProperty, unsetValue, makeParser, makeValidator } from './core/properties';
|
export { Property, CoercibleProperty, InheritedProperty, CssProperty, InheritedCssProperty, ShorthandProperty, CssAnimationProperty, unsetValue, makeParser, makeValidator } from './core/properties';
|
||||||
export { addWeakEventListener, removeWeakEventListener } from './core/weak-event-listener';
|
export { addWeakEventListener, removeWeakEventListener } from './core/weak-event-listener';
|
||||||
export { DatePicker } from './date-picker';
|
export { DatePicker } from './date-picker';
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { Color } from '../../color';
|
||||||
import { Application } from '../../application';
|
import { Application } from '../../application';
|
||||||
import { Trace } from '../../trace';
|
import { Trace } from '../../trace';
|
||||||
import { topmost } from '../../ui/frame/frame-stack';
|
import { topmost } from '../../ui/frame/frame-stack';
|
||||||
@ -172,3 +173,117 @@ export function isRealDevice(): boolean {
|
|||||||
|
|
||||||
return fingerprint != null && (fingerprint.indexOf('vbox') > -1 || fingerprint.indexOf('generic') > -1);
|
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);
|
||||||
|
|
||||||
|
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) {
|
||||||
|
enableEdgeToEdge(activity, {
|
||||||
|
statusBarLightColor: lightColor,
|
||||||
|
statusBarDarkColor: darkColor,
|
||||||
|
navigationBarLightColor,
|
||||||
|
navigationBarDarkColor,
|
||||||
|
handleDarkMode: darkModeHandler,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let navigationBarDarkColor: Color | null = null;
|
||||||
|
let navigationBarLightColor: Color | null = null;
|
||||||
|
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
enableEdgeToEdge(activity, {
|
||||||
|
statusBarLightColor,
|
||||||
|
statusBarDarkColor,
|
||||||
|
navigationBarLightColor,
|
||||||
|
navigationBarDarkColor,
|
||||||
|
handleDarkMode: handler,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = 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({
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -246,9 +246,37 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class LayoutBase extends android.view.ViewGroup {
|
export class LayoutBase extends android.view.ViewGroup {
|
||||||
|
public static OverflowEdgeNone: number;
|
||||||
|
public static OverflowEdgeLeft: number;
|
||||||
|
public static OverflowEdgeTop: number;
|
||||||
|
public static OverflowEdgeRight: number;
|
||||||
|
public static OverflowEdgeBottom: number;
|
||||||
|
public static OverflowEdgeDontApply: number;
|
||||||
|
public static OverflowEdgeLeftDontConsume: number;
|
||||||
|
public static OverflowEdgeTopDontConsume: number;
|
||||||
|
public static OverflowEdgeRightDontConsume: number;
|
||||||
|
public static OverflowEdgeBottomDontConsume: number;
|
||||||
|
public static OverflowEdgeAllButLeft: number;
|
||||||
|
public static OverflowEdgeAllButTop: number;
|
||||||
|
public static OverflowEdgeAllButRight: number;
|
||||||
|
public static OverflowEdgeAllButBottom: number;
|
||||||
constructor(context: android.content.Context);
|
constructor(context: android.content.Context);
|
||||||
|
public getOverflowEdge(): number;
|
||||||
|
public setOverflowEdge(value: number): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export module LayoutBase {
|
||||||
|
export class WindowInsetListener {
|
||||||
|
public constructor(implementation: {
|
||||||
|
onApplyWindowInsets(param0: java.nio.ByteBuffer): void;
|
||||||
|
});
|
||||||
|
public constructor();
|
||||||
|
public onApplyWindowInsets(param0: java.nio.ByteBuffer): void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export class AbsoluteLayout extends LayoutBase {
|
export class AbsoluteLayout extends LayoutBase {
|
||||||
constructor(context: android.content.Context);
|
constructor(context: android.content.Context);
|
||||||
}
|
}
|
||||||
@ -729,6 +757,10 @@ declare module org {
|
|||||||
public static saveToFileAsync(param0: globalAndroid.graphics.Bitmap, param1: string, param2: string, param3: number, param4: org.nativescript.widgets.Utils.AsyncImageCallback): void;
|
public static saveToFileAsync(param0: globalAndroid.graphics.Bitmap, param1: string, param2: string, param3: number, param4: org.nativescript.widgets.Utils.AsyncImageCallback): void;
|
||||||
public static toBase64StringAsync(param0: globalAndroid.graphics.Bitmap, param1: string, param2: number, param3: org.nativescript.widgets.Utils.AsyncImageCallback): void;
|
public static toBase64StringAsync(param0: globalAndroid.graphics.Bitmap, param1: string, param2: number, param3: org.nativescript.widgets.Utils.AsyncImageCallback): void;
|
||||||
public static resizeAsync(param0: globalAndroid.graphics.Bitmap, param1: number, param2: string, param3: org.nativescript.widgets.Utils.AsyncImageCallback): void;
|
public static resizeAsync(param0: globalAndroid.graphics.Bitmap, param1: number, param2: string, param3: org.nativescript.widgets.Utils.AsyncImageCallback): void;
|
||||||
|
public static enableEdgeToEdge(activity: androidx.activity.ComponentActivity): void;
|
||||||
|
public static enableEdgeToEdge(activity: androidx.activity.ComponentActivity, handleDarkMode: org.nativescript.widgets.Utils.HandleDarkMode): void;
|
||||||
|
public static enableEdgeToEdge(activity: androidx.activity.ComponentActivity, statusBarLight: java.lang.Integer, statusBarDark: java.lang.Integer, navigationBarLight: java.lang.Integer, navigationBarDark: java.lang.Integer): void;
|
||||||
|
public static enableEdgeToEdge(activity: androidx.activity.ComponentActivity, statusBarLight: java.lang.Integer, statusBarDark: java.lang.Integer, navigationBarLight: java.lang.Integer, navigationBarDark: java.lang.Integer, handleDarkMode: org.nativescript.widgets.Utils.HandleDarkMode): void;
|
||||||
public constructor();
|
public constructor();
|
||||||
}
|
}
|
||||||
export module Utils {
|
export module Utils {
|
||||||
@ -745,6 +777,25 @@ declare module org {
|
|||||||
public onSuccess(param0: any): void;
|
public onSuccess(param0: any): void;
|
||||||
public onError(param0: java.lang.Exception): void;
|
public onError(param0: java.lang.Exception): void;
|
||||||
}
|
}
|
||||||
|
export class HandleDarkMode {
|
||||||
|
public static class: java.lang.Class<org.nativescript.widgets.Utils.HandleDarkMode>;
|
||||||
|
/**
|
||||||
|
* Constructs a new instance of the org.nativescript.widgets.Utils$HandleDarkMode interface with the provided implementation. An empty constructor exists calling super() when extending the interface class.
|
||||||
|
*/
|
||||||
|
public constructor(implementation: {
|
||||||
|
onHandle(param0: number, param1: globalAndroid.content.res.Resources): boolean;
|
||||||
|
});
|
||||||
|
public constructor();
|
||||||
|
public onHandle(param0: number, param1: globalAndroid.content.res.Resources): boolean;
|
||||||
|
}
|
||||||
|
export class HandleDarkModeBar {
|
||||||
|
public static class: java.lang.Class<org.nativescript.widgets.Utils.HandleDarkModeBar>;
|
||||||
|
public static status: org.nativescript.widgets.Utils.HandleDarkModeBar;
|
||||||
|
public static navigation: org.nativescript.widgets.Utils.HandleDarkModeBar;
|
||||||
|
public static valueOf(name: string): org.nativescript.widgets.Utils.HandleDarkModeBar;
|
||||||
|
public static values(): androidNative.Array<org.nativescript.widgets.Utils.HandleDarkModeBar>;
|
||||||
|
public getValue(): number;
|
||||||
|
}
|
||||||
export class ImageAssetOptions {
|
export class ImageAssetOptions {
|
||||||
public static class: java.lang.Class<org.nativescript.widgets.Utils.ImageAssetOptions>;
|
public static class: java.lang.Class<org.nativescript.widgets.Utils.ImageAssetOptions>;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import android.widget.TextView
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.widget.NestedScrollView
|
import androidx.core.widget.NestedScrollView
|
||||||
import org.nativescript.widgets.CommonLayoutParams
|
import org.nativescript.widgets.CommonLayoutParams
|
||||||
|
import org.nativescript.widgets.ContentLayout
|
||||||
import org.nativescript.widgets.GridLayout
|
import org.nativescript.widgets.GridLayout
|
||||||
import org.nativescript.widgets.LayoutBase
|
import org.nativescript.widgets.LayoutBase
|
||||||
import org.nativescript.widgets.StackLayout
|
import org.nativescript.widgets.StackLayout
|
||||||
@ -18,24 +19,53 @@ class MainActivity : AppCompatActivity() {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
Utils.enableEdgeToEdge(this)
|
Utils.enableEdgeToEdge(this)
|
||||||
|
val frame = ContentLayout(this)
|
||||||
val page = GridLayout(this)
|
val page = GridLayout(this)
|
||||||
page.setBackgroundColor(Color.BLUE)
|
|
||||||
page.overflowEdge = LayoutBase.OverflowEdgeDontApply
|
|
||||||
page.layoutParams = CommonLayoutParams(
|
page.layoutParams = CommonLayoutParams(
|
||||||
ViewGroup.LayoutParams(
|
ViewGroup.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT
|
ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
page.setBackgroundColor(Color.MAGENTA)
|
||||||
|
page.overflowEdge = LayoutBase.OverflowEdgeAllButTop
|
||||||
|
// page.setInsetListener {
|
||||||
|
// val insets = it.asIntBuffer()
|
||||||
|
// insets.put(0,0)
|
||||||
|
// insets.put(1,0)
|
||||||
|
// insets.put(2,0)
|
||||||
|
// insets.put(3,0)
|
||||||
|
//// insets.put(3,0)
|
||||||
|
//// insets.put(5,1)
|
||||||
|
// }
|
||||||
|
|
||||||
|
frame.setBackgroundColor(Color.BLUE)
|
||||||
|
frame.overflowEdge = LayoutBase.OverflowEdgeDontApply
|
||||||
|
frame.layoutParams = CommonLayoutParams(
|
||||||
|
ViewGroup.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val svp = StackLayout(this)
|
val svp = StackLayout(this)
|
||||||
|
// svp.setBackgroundColor(Color.YELLOW)
|
||||||
svp.layoutParams = CommonLayoutParams(
|
svp.layoutParams = CommonLayoutParams(
|
||||||
ViewGroup.LayoutParams(
|
ViewGroup.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT
|
ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
svp.overflowEdge = StackLayout.OverflowEdgeDontApply
|
// svp.setInsetListener {
|
||||||
|
// val insets = it.asIntBuffer()
|
||||||
|
// insets.put(0,0)
|
||||||
|
// insets.put(1,0)
|
||||||
|
// insets.put(2,0)
|
||||||
|
// insets.put(3,0)
|
||||||
|
// // insets.put(7, 1)
|
||||||
|
// }
|
||||||
|
|
||||||
|
svp.overflowEdge = StackLayout.OverflowEdgeAllButBottom
|
||||||
val scrollView = NestedScrollView(this)
|
val scrollView = NestedScrollView(this)
|
||||||
scrollView.layoutParams = CommonLayoutParams(
|
scrollView.layoutParams = CommonLayoutParams(
|
||||||
ViewGroup.LayoutParams(
|
ViewGroup.LayoutParams(
|
||||||
@ -47,6 +77,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
val container = StackLayout(this)
|
val container = StackLayout(this)
|
||||||
container.setBackgroundColor(Color.RED)
|
container.setBackgroundColor(Color.RED)
|
||||||
|
container.overflowEdge = StackLayout.OverflowEdgeNone
|
||||||
|
|
||||||
val text = TextView(this)
|
val text = TextView(this)
|
||||||
text.text = getString(R.string.ipsum)
|
text.text = getString(R.string.ipsum)
|
||||||
@ -68,6 +99,16 @@ class MainActivity : AppCompatActivity() {
|
|||||||
params.width
|
params.width
|
||||||
btn.layoutParams = params
|
btn.layoutParams = params
|
||||||
btn.setOnClickListener {
|
btn.setOnClickListener {
|
||||||
|
val new_page = StackLayout(this)
|
||||||
|
new_page.setBackgroundColor(Color.BLUE)
|
||||||
|
new_page.layoutParams = CommonLayoutParams(
|
||||||
|
ViewGroup.LayoutParams(
|
||||||
|
300, 300
|
||||||
|
)
|
||||||
|
)
|
||||||
|
container.addView(new_page)
|
||||||
|
|
||||||
|
|
||||||
svp.overflowEdge = when (svp.overflowEdge) {
|
svp.overflowEdge = when (svp.overflowEdge) {
|
||||||
LayoutBase.OverflowEdgeNone -> {
|
LayoutBase.OverflowEdgeNone -> {
|
||||||
LayoutBase.OverflowEdgeDontApply
|
LayoutBase.OverflowEdgeDontApply
|
||||||
@ -89,6 +130,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
page.addView(btn)
|
page.addView(btn)
|
||||||
setContentView(page)
|
frame.addView(page)
|
||||||
|
setContentView(frame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,100 +5,5 @@
|
|||||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur euismod dictum purus, non tempor tortor fermentum vehicula. Donec condimentum eleifend lacus, non varius dui feugiat quis. Integer tincidunt, erat nec lacinia maximus, ante tortor placerat arcu, eu dignissim mauris ipsum et diam. Proin sed magna dui. Donec consequat volutpat mi, sed facilisis quam sollicitudin ac. Nullam pulvinar nunc nec diam molestie, sit amet semper lectus efficitur. Aenean ut lacus arcu. Donec non tempor risus.
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur euismod dictum purus, non tempor tortor fermentum vehicula. Donec condimentum eleifend lacus, non varius dui feugiat quis. Integer tincidunt, erat nec lacinia maximus, ante tortor placerat arcu, eu dignissim mauris ipsum et diam. Proin sed magna dui. Donec consequat volutpat mi, sed facilisis quam sollicitudin ac. Nullam pulvinar nunc nec diam molestie, sit amet semper lectus efficitur. Aenean ut lacus arcu. Donec non tempor risus.
|
||||||
|
|
||||||
Pellentesque blandit congue mattis. Proin eget nibh id nisl pellentesque elementum. Vestibulum neque arcu, luctus vitae pretium sed, venenatis quis odio. Quisque varius ligula id quam ullamcorper, ut gravida magna aliquam. Proin sit amet nibh tempus, aliquam justo ut, accumsan nibh. Curabitur non neque dui. Phasellus ac semper nunc. Aenean placerat lacinia suscipit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
Pellentesque blandit congue mattis. Proin eget nibh id nisl pellentesque elementum. Vestibulum neque arcu, luctus vitae pretium sed, venenatis quis odio. Quisque varius ligula id quam ullamcorper, ut gravida magna aliquam. Proin sit amet nibh tempus, aliquam justo ut, accumsan nibh. Curabitur non neque dui. Phasellus ac semper nunc. Aenean placerat lacinia suscipit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
</string>
|
||||||
Donec volutpat nec felis eu semper. Vestibulum efficitur dignissim nibh nec placerat. Donec auctor at turpis eu accumsan. Nunc pharetra lorem neque, vitae pulvinar eros viverra non. Etiam sodales orci pellentesque tortor ornare tempus. Duis turpis ligula, fermentum maximus porta at, convallis sed felis. Cras sit amet nibh a enim aliquet bibendum ac non velit. Vivamus dignissim commodo sem, et euismod neque euismod ac. In laoreet, massa sit amet lobortis fringilla, ipsum dui tincidunt lacus, sit amet consequat massa nulla quis quam. Praesent eleifend tellus a dui sollicitudin accumsan.
|
|
||||||
|
|
||||||
Vestibulum molestie leo ac lorem euismod, nec mattis massa feugiat. Suspendisse vel risus sapien. Mauris sed erat eget massa eleifend ultrices sit amet ut felis. Quisque vitae bibendum est. Morbi accumsan augue at nibh interdum, auctor condimentum arcu dapibus. Morbi mollis quam in orci egestas elementum. Praesent consequat scelerisque magna, ac cursus mi tristique in. Duis in ex et sapien sagittis cursus. Nam sed ultricies elit.
|
|
||||||
|
|
||||||
Pellentesque ut egestas purus, id commodo felis. Vivamus sed sollicitudin enim, nec egestas velit. Morbi auctor enim ut tortor interdum, volutpat auctor magna volutpat. Duis tincidunt nisl at dolor tempus, fringilla commodo metus luctus. Sed molestie nisi id fringilla dapibus. Sed est urna, commodo vel maximus sit amet, pellentesque nec dui. Phasellus elementum, massa ac ultrices tincidunt, est leo cursus dolor, eget tincidunt sapien ex et leo. Nunc id lorem vitae lectus finibus consequat quis at mauris. Vestibulum faucibus nibh libero, eget ullamcorper est semper a. Maecenas in volutpat tellus, sit amet rhoncus leo. Vivamus tristique bibendum tempor. Duis efficitur, nisl sit amet pulvinar ultricies, elit odio tincidunt magna, ac placerat est dui vel nibh. Sed condimentum, lorem et vestibulum tincidunt, lectus urna porttitor turpis, placerat auctor dolor est sed lacus. Pellentesque massa nisl, condimentum et pellentesque et, commodo tristique magna. Praesent iaculis porta lorem at vestibulum. Donec porttitor, ligula eget scelerisque ornare, arcu turpis vehicula elit, non hendrerit dolor ipsum a lacus.
|
|
||||||
|
|
||||||
Duis malesuada diam tempor turpis ornare, a tincidunt turpis hendrerit. Cras porta magna eu ante ultricies, eu euismod quam fermentum. Cras placerat nisi vel ipsum accumsan varius. Mauris vestibulum magna ex, vel condimentum felis suscipit nec. Proin consectetur feugiat nisi at luctus. Praesent ullamcorper lectus quis neque mollis euismod. Etiam blandit lorem ante, sed imperdiet mi convallis sed. Suspendisse vitae augue non est consectetur hendrerit. Integer luctus, metus id tincidunt ultricies, risus sem sagittis erat, et blandit tortor sem ut tellus. Integer ut elit tellus. Mauris tempor, leo vel efficitur elementum, quam sem gravida dui, et ornare dolor metus sed diam. Etiam nibh massa, ornare non nisl quis, pharetra semper nunc. Maecenas id consectetur felis.
|
|
||||||
|
|
||||||
Aenean molestie imperdiet commodo. In venenatis sem mauris, id ultricies ipsum pulvinar quis. Morbi in sodales nisl. Curabitur eget metus a augue auctor accumsan quis eget mi. Aenean faucibus at nisl ac sodales. Proin malesuada libero laoreet lobortis pharetra. Integer in suscipit est. Donec sed felis neque.
|
|
||||||
|
|
||||||
Vivamus sed libero vitae ipsum mattis vestibulum. Quisque lacinia tincidunt sodales. Nulla sed venenatis elit. Aliquam egestas nisl odio, sed hendrerit neque mollis sed. Vivamus quis metus ut enim lobortis ullamcorper. Etiam suscipit varius libero quis facilisis. Ut ac risus eget massa porta vulputate. Nulla facilisi.
|
|
||||||
|
|
||||||
Nam augue metus, lobortis vitae lacus at, vehicula aliquet tellus. Sed bibendum maximus neque, et finibus nisl sodales in. Maecenas et mattis sapien, scelerisque tristique urna. Nulla vulputate, justo eget porttitor tincidunt, ante odio fermentum lectus, eget dapibus odio ipsum tempor ligula. Sed viverra dolor nec dui tincidunt fermentum. Phasellus non volutpat nunc, in tincidunt augue. In bibendum, mauris vehicula gravida maximus, nisl eros tincidunt nisl, at consectetur nisi justo convallis nibh. Etiam consectetur condimentum neque, eget iaculis lectus elementum ut. Duis vitae lacus lacinia purus tincidunt lobortis. Donec sapien sem, fringilla ac varius at, luctus a velit. In interdum ac lectus id bibendum. Quisque volutpat faucibus dapibus. Proin vitae scelerisque diam. In at lorem luctus arcu ornare viverra. Maecenas sollicitudin elit eget erat tempor, ut laoreet lectus congue.
|
|
||||||
|
|
||||||
Vivamus placerat justo eget vulputate consequat. Vivamus mattis lorem euismod libero scelerisque, at mollis velit placerat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Vivamus purus arcu, luctus nec efficitur dapibus, faucibus vitae tellus. Nunc ut sollicitudin metus. In eu pretium nibh. Donec sapien sem, iaculis nec fermentum congue, ultricies maximus urna.
|
|
||||||
|
|
||||||
Nulla tristique justo tellus, quis eleifend augue maximus id. Nunc eu vestibulum diam, nec dignissim velit. Sed quis risus eu tortor tincidunt ullamcorper sed sit amet elit. Phasellus cursus mollis placerat. Suspendisse nec velit odio. Nullam vulputate mauris vel ante volutpat tempor. Donec posuere diam a vulputate vulputate. Donec sit amet leo risus. Fusce tincidunt, nisi id posuere tincidunt, dui dui fringilla quam, at sollicitudin dui nisi vel arcu. Etiam imperdiet mi vitae eros maximus egestas. Nam eget convallis justo, porta lacinia felis. Fusce convallis, sem in cursus egestas, massa felis tempor magna, ut tincidunt neque erat ut justo. Nunc at tempus odio. Mauris vehicula nulla ac sodales viverra. Morbi sed convallis ante, non dapibus felis. Fusce interdum volutpat dolor et viverra.
|
|
||||||
|
|
||||||
Proin scelerisque luctus lectus ac blandit. Nullam sit amet nulla elit. Donec sit amet varius quam. Donec condimentum purus non risus sagittis venenatis non et tellus. Suspendisse a ultrices ligula, non volutpat erat. Ut condimentum quis erat nec dapibus. Morbi dignissim magna blandit, semper odio nec, iaculis risus.
|
|
||||||
|
|
||||||
Nam suscipit, magna in mattis finibus, nisl mauris tempor massa, vel imperdiet nisi urna id urna. Nunc gravida mi ut pretium fringilla. Donec eget laoreet dui, id finibus sapien. Integer vestibulum odio orci, ut tincidunt urna sagittis quis. Mauris pharetra arcu enim, dictum scelerisque est vehicula ac. Phasellus lobortis sapien eget tortor venenatis facilisis. In eu porta tortor, ut ultrices arcu. Nulla pharetra faucibus libero quis imperdiet. Mauris magna libero, cursus ut auctor id, luctus in risus. Mauris venenatis ultricies malesuada. Quisque in neque metus. Praesent sed est rhoncus, mollis libero a, sollicitudin urna.
|
|
||||||
|
|
||||||
Fusce consectetur, libero sit amet facilisis scelerisque, lorem nunc consectetur erat, sed cursus nulla nibh a nisl. Nunc est massa, viverra vehicula tincidunt sit amet, maximus eget mauris. Pellentesque rutrum commodo risus, non bibendum urna tempus at. Vestibulum turpis enim, fermentum at aliquet non, facilisis ut metus. Pellentesque finibus neque ut aliquam sagittis. Aliquam eget bibendum velit, ut dictum ex. In at lorem feugiat, auctor orci in, efficitur metus.
|
|
||||||
|
|
||||||
Ut in enim in lectus iaculis convallis. Integer semper nunc nulla, ac tincidunt magna fermentum vel. Quisque aliquam consectetur vehicula. Proin id sem eget nulla lobortis maximus egestas at tellus. Praesent eu nisl porta, vehicula sem vel, efficitur lectus. Donec finibus consequat urna varius sollicitudin. Curabitur egestas mi vel laoreet porttitor. Mauris metus enim, tempor vel interdum vel, pharetra vitae purus. Duis sed luctus turpis, a pellentesque sapien. Nullam eget sapien non purus elementum dictum. Maecenas pretium rutrum volutpat. Suspendisse quis dui nunc. Duis sit amet metus turpis. Vivamus quis tellus in sapien maximus sollicitudin.
|
|
||||||
|
|
||||||
Curabitur feugiat neque nisi, ut vestibulum justo egestas non. Maecenas id sodales ligula, quis suscipit nulla. Nulla laoreet vitae est nec luctus. Sed vestibulum nisi in dui vehicula sollicitudin. Morbi auctor orci sit amet vehicula condimentum. Vivamus ut enim iaculis, malesuada sapien eget, lobortis purus. Proin imperdiet tortor ac lorem auctor auctor. Pellentesque volutpat nunc in nunc semper varius. Curabitur ornare venenatis sagittis. Fusce dictum urna id mollis dapibus. In hac habitasse platea dictumst. Etiam faucibus et sem bibendum vehicula. Pellentesque tincidunt faucibus varius. Sed a feugiat mauris. Mauris dictum ultricies lacus.
|
|
||||||
|
|
||||||
Fusce vitae suscipit lacus. Aenean interdum, ante eu mattis maximus, mauris justo bibendum enim, vitae ultricies velit nulla ut diam. Duis eleifend pulvinar nibh at tempor. Sed id lacinia dui, at dignissim ex. Aenean id iaculis nisl. Praesent vitae posuere leo. Ut tempor urna elit, id volutpat nibh accumsan at. Curabitur id lorem accumsan, pellentesque mi sed, sodales lorem. In ac dui pharetra, feugiat orci sit amet, finibus lacus. Fusce aliquet augue et mi maximus, ut convallis ex eleifend. Etiam vel augue viverra justo dictum blandit et non elit. Aliquam sagittis nisi vitae quam suscipit blandit. Maecenas sed malesuada nulla. Sed mattis aliquet lacus, eget pretium augue lobortis quis. Donec eget iaculis ipsum.
|
|
||||||
|
|
||||||
Praesent vitae sollicitudin enim. Nullam tempus fringilla faucibus. Aliquam pulvinar nunc magna, ac lacinia turpis porta ut. Duis sapien tellus, faucibus et commodo a, ornare et sapien. Aliquam eu lectus vehicula, venenatis nunc ut, egestas arcu. Ut laoreet semper egestas. Aenean magna mauris, suscipit sed mauris a, mollis ultrices leo. Proin in massa sit amet risus faucibus pharetra vitae vel dolor.
|
|
||||||
|
|
||||||
Mauris bibendum justo augue, quis fermentum ligula luctus placerat. Nunc nisl velit, pharetra quis velit sed, dictum sagittis eros. Ut id pulvinar leo. Aenean in pretium nisl. Curabitur eget urna efficitur, accumsan neque vel, condimentum metus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum metus ipsum, imperdiet vitae suscipit dictum, accumsan feugiat ex. Aenean pretium sem eros, id auctor purus pharetra eu. Nunc congue scelerisque felis a tristique. Cras ultricies eleifend nisl convallis cursus. Sed ullamcorper sit amet arcu sed facilisis.
|
|
||||||
|
|
||||||
Nam tristique lacus vitae lectus dapibus pharetra. Maecenas condimentum tincidunt dolor, sed euismod sem iaculis vel. Praesent sed sapien ut arcu ultricies fermentum a vitae dui. Morbi porttitor leo id orci aliquet convallis. Nulla magna nulla, elementum et nisl in, maximus scelerisque tortor. Ut commodo lorem non ultrices egestas. Donec maximus, ligula a semper elementum, nulla nibh facilisis neque, vitae ullamcorper lorem ex ac magna. Phasellus suscipit arcu scelerisque, pellentesque sem et, rhoncus nisl. Duis ut nibh dignissim, sagittis arcu sed, convallis nibh. Phasellus vel dapibus orci. Etiam suscipit augue non orci eleifend, sit amet molestie justo maximus. In egestas molestie felis, at fermentum est eleifend nec. Fusce sed dapibus mi, id ultrices lacus.
|
|
||||||
|
|
||||||
Praesent euismod augue viverra metus accumsan, ac blandit massa dapibus. Aenean vel posuere tortor. Fusce scelerisque volutpat nibh, dictum tincidunt lorem blandit et. Vestibulum euismod, nisi eleifend lacinia pretium, leo urna blandit diam, eu dignissim risus lectus eu arcu. Cras vitae nibh tincidunt tortor ullamcorper tristique. Phasellus tempor non nulla vitae pretium. Suspendisse in dapibus diam. Suspendisse eros urna, ornare eu felis nec, aliquam tincidunt est. In vehicula purus ac faucibus gravida. Nullam et quam tincidunt, varius sem commodo, egestas est. In hac habitasse platea dictumst. Fusce eleifend turpis lacus, quis ultrices nulla sagittis et. Fusce non sodales eros. Aenean eu justo velit. Quisque purus nisi, blandit et nisi sit amet, facilisis vulputate odio. Nam eleifend sapien blandit, bibendum magna ac, euismod felis.
|
|
||||||
|
|
||||||
Vestibulum tincidunt tortor neque, ut porttitor quam pharetra pretium. Etiam interdum aliquet ultrices. Aliquam blandit dolor ac purus auctor consectetur at et tortor. Fusce faucibus ipsum vel risus euismod, quis interdum orci ultrices. Fusce vitae sapien eget nisl accumsan facilisis. Fusce nunc tellus, faucibus pretium aliquam sed, accumsan vitae purus. Curabitur efficitur mollis neque, nec maximus sapien ultrices quis. Morbi eleifend bibendum sagittis. Maecenas convallis convallis nunc eu pulvinar.
|
|
||||||
|
|
||||||
Curabitur at augue tempor tortor faucibus mattis. Fusce vehicula urna non lacinia molestie. Nulla vestibulum odio eros, a interdum elit volutpat ut. Nulla hendrerit urna ac viverra eleifend. Donec dui sem, lacinia quis mollis in, tincidunt efficitur eros. Maecenas in est finibus, varius est id, ultrices purus. Duis hendrerit libero et nisl pretium, eget egestas urna porttitor. Fusce sit amet laoreet lacus, eu luctus justo. Fusce justo elit, vestibulum ut nulla eget, dictum posuere quam. Morbi quis ligula sapien. Pellentesque ultrices dui vitae nunc scelerisque, nec bibendum ante hendrerit. Donec viverra ante ipsum, sit amet blandit justo rutrum id.
|
|
||||||
|
|
||||||
Aenean ultrices et odio feugiat finibus. Pellentesque nisi velit, congue id imperdiet ut, sagittis vitae orci. Pellentesque sit amet nisl massa. Nam cursus, tellus id fermentum elementum, risus turpis iaculis nunc, eget varius odio dolor vel eros. Quisque eleifend tortor et magna tincidunt, sed placerat elit iaculis. Curabitur congue finibus risus, non efficitur leo varius nec. Aliquam venenatis risus tellus, sit amet condimentum neque accumsan non.
|
|
||||||
|
|
||||||
Ut sodales eros ut felis iaculis, sed eleifend lectus commodo. Integer ac augue placerat, semper velit ut, ullamcorper lectus. Integer tincidunt convallis enim non rutrum. Mauris condimentum magna nisi, eget efficitur lorem tincidunt sed. Fusce a eros ullamcorper odio placerat ultrices a sed enim. Nullam convallis vel turpis ultricies tempor. Vestibulum at turpis et felis iaculis auctor. Phasellus iaculis tortor in diam ornare, eleifend eleifend libero pretium. Integer et mauris pretium, egestas odio et, consectetur libero. Curabitur efficitur nisl in leo tempus, in tristique ipsum consectetur. Praesent luctus lorem rhoncus rhoncus bibendum. In elementum tincidunt quam, a laoreet metus egestas tincidunt. Donec luctus mattis congue.
|
|
||||||
|
|
||||||
In hac habitasse platea dictumst. Phasellus nec suscipit turpis, in maximus sem. Sed vulputate elit ac venenatis ornare. Aenean sagittis tortor et facilisis condimentum. Quisque vel neque nec libero efficitur ornare eget ut libero. Curabitur interdum ante eu lectus dictum, et bibendum justo lobortis. In in congue neque.
|
|
||||||
|
|
||||||
Nam rhoncus vitae metus ut volutpat. Maecenas sem mi, blandit vel fermentum id, pulvinar vitae orci. Curabitur eget condimentum orci, sed laoreet dolor. Suspendisse eleifend sapien eu ex molestie condimentum. Quisque porttitor tempor libero ac gravida. Curabitur sodales varius tortor eu pulvinar. Morbi dui orci, ornare et velit eget, rhoncus dignissim magna. Phasellus ut dolor ut elit eleifend congue. Cras suscipit erat venenatis sapien pellentesque, at sagittis neque semper. Quisque lacinia ac ligula ac rhoncus. Nunc bibendum ex mi, maximus volutpat lorem viverra quis. Duis ut elit vitae tellus dictum viverra ut quis urna. Sed quis neque luctus, malesuada lectus sit amet, iaculis tellus.
|
|
||||||
|
|
||||||
Sed luctus est nec arcu pellentesque, non lobortis lectus congue. Nunc suscipit enim a tortor convallis, ac laoreet nulla pretium. Integer a nisi id enim accumsan sollicitudin. Integer sagittis, nisi in tincidunt semper, nisl leo congue orci, eu euismod tortor ligula vestibulum dui. Nam nunc libero, luctus non mattis quis, egestas non odio. Quisque consectetur, lacus at hendrerit ornare, libero nunc facilisis ipsum, quis euismod nisl dolor vel mauris. Suspendisse felis tortor, tempus sit amet nulla id, tincidunt fermentum orci. Phasellus vel est ut eros varius lacinia. Curabitur lobortis mi libero, in tempor sem vulputate vitae. Proin vel ligula enim. Nullam elementum suscipit orci non porttitor. Vestibulum condimentum nunc magna, eu pulvinar nibh egestas imperdiet. Vivamus lacinia purus nisi, in euismod magna pellentesque ut. Nunc sed purus rhoncus, lacinia augue luctus, aliquet orci. Aliquam pellentesque eros sed erat interdum consectetur.
|
|
||||||
|
|
||||||
Praesent iaculis nunc dui, nec malesuada tellus feugiat a. Maecenas finibus ultricies tortor non varius. Morbi viverra justo a lectus venenatis, at ultricies quam commodo. Suspendisse facilisis tortor eget dui congue commodo. Aenean et cursus lorem. Nullam laoreet scelerisque diam. Nullam ullamcorper lacus sit amet interdum iaculis. Nullam vestibulum facilisis turpis. Nam vehicula, sapien eget feugiat sodales, eros turpis cursus lorem, bibendum auctor nunc massa nec urna.
|
|
||||||
|
|
||||||
Fusce fringilla, arcu vel rutrum sodales, mi quam laoreet tortor, sit amet sagittis nisi ligula et lacus. Donec ipsum augue, faucibus a dolor nec, semper pharetra justo. In hac habitasse platea dictumst. Nam non mauris quis dui pharetra rutrum. Nunc eu dolor lacus. Vestibulum congue sed lacus sed varius. Etiam tincidunt tempus felis. Pellentesque neque magna, suscipit a dolor eget, luctus blandit quam. Integer scelerisque dictum libero, vel vestibulum dui facilisis ut. Quisque porta dictum feugiat. Quisque id elit dui. Aenean tristique egestas porttitor. Mauris sem libero, laoreet at enim eu, dictum vehicula augue. Praesent sodales eget felis id elementum. Proin eget ultrices neque.
|
|
||||||
|
|
||||||
Curabitur sit amet ante orci. In scelerisque purus vitae pretium tincidunt. Sed arcu elit, elementum lacinia dolor at, porta hendrerit magna. Mauris id erat euismod tellus cursus blandit vitae commodo nibh. Phasellus varius ligula commodo vehicula elementum. Praesent viverra sem id porta laoreet. Maecenas in nibh maximus, tincidunt urna consectetur, lobortis velit.
|
|
||||||
|
|
||||||
Proin scelerisque ac ex at ornare. Aliquam sodales mauris in lacus scelerisque vulputate. Sed dictum enim magna, non scelerisque lacus sagittis eu. Aenean ut convallis odio. Nam vel maximus metus. Maecenas lacinia pretium feugiat. Morbi pulvinar arcu at ipsum cursus vulputate. Phasellus rhoncus dui sed accumsan porttitor. Maecenas tellus neque, ultrices facilisis pellentesque a, accumsan et ipsum. Cras vestibulum mi at mollis venenatis. Aenean at tortor non odio egestas convallis sit amet vitae erat. Nunc finibus, erat sit amet consequat facilisis, magna arcu iaculis libero, tempor eleifend eros erat sed felis. Sed id mi fringilla quam convallis dignissim. Donec velit felis, porttitor vel turpis sed, dictum posuere quam. Aliquam vestibulum rhoncus ligula in vulputate.
|
|
||||||
|
|
||||||
Donec laoreet, nibh in vehicula consectetur, erat diam molestie ante, rhoncus convallis odio lorem ac lectus. In libero elit, consequat lobortis ligula et, efficitur congue massa. Suspendisse semper faucibus purus, at molestie diam laoreet nec. Donec ultrices tincidunt ex ut efficitur. Fusce ac tincidunt nunc. Nunc non turpis ac lectus pharetra ornare ut in quam. Phasellus a maximus tellus. Phasellus faucibus tincidunt sagittis. Cras non quam diam.
|
|
||||||
|
|
||||||
Duis pellentesque, purus vitae sollicitudin pellentesque, mi magna elementum nulla, gravida feugiat arcu quam eget enim. Nullam maximus erat nec libero sagittis, vel maximus libero tincidunt. Vivamus iaculis quam et euismod dictum. Nulla ac pellentesque tortor, non molestie justo. Etiam venenatis at velit vel sollicitudin. Donec sollicitudin sapien vitae laoreet gravida. Aenean ultrices auctor velit eu suscipit. Quisque at augue ultrices, molestie nisl eget, pretium ante. Mauris semper tortor at ligula iaculis vulputate.
|
|
||||||
|
|
||||||
Morbi vehicula lacus a nibh imperdiet vehicula. Integer tempus at nunc a venenatis. Morbi dapibus, augue sed consequat ullamcorper, metus nisi sollicitudin lorem, a porttitor dui risus sit amet nunc. Etiam volutpat dignissim ex, ut gravida dolor volutpat ut. Aenean eget scelerisque odio, in luctus ipsum. Sed dapibus purus a imperdiet accumsan. Aenean venenatis nibh nulla, sed dapibus mauris porttitor quis. Aliquam commodo mauris vel metus pellentesque, sit amet porttitor tellus volutpat. Nam ac justo imperdiet, aliquet lectus id, posuere risus. Vestibulum non arcu arcu.
|
|
||||||
|
|
||||||
Vestibulum posuere consectetur tristique. Nulla et sagittis risus. Praesent felis nunc, ornare vulputate turpis quis, vulputate vehicula nulla. Mauris eget tempor elit. In nulla purus, posuere non fringilla eu, molestie quis ipsum. Donec in cursus nibh. Nullam fermentum sit amet eros at viverra. Sed viverra neque id lobortis condimentum. Duis ultricies varius ornare. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Nullam nec tortor interdum, volutpat ex in, laoreet massa. Donec iaculis libero id sollicitudin venenatis. Vestibulum sed odio vitae tellus hendrerit euismod. Quisque sed dapibus quam. Nulla ante augue, congue nec nulla et, eleifend sodales eros. Fusce volutpat vitae ante ut maximus.
|
|
||||||
|
|
||||||
Cras placerat dictum neque, vel bibendum nulla pellentesque quis. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam lacinia nisi ut aliquam condimentum. Vivamus et suscipit arcu, a semper orci. Aenean aliquam risus non risus dignissim, quis luctus purus rhoncus. Curabitur a eros nisl. In hac habitasse platea dictumst. Vestibulum volutpat massa in augue semper, ullamcorper elementum urna pellentesque. Vivamus feugiat sapien vitae nisi venenatis, vitae ultrices justo ornare. Aenean vestibulum nibh dolor, quis sodales nunc sodales et. Curabitur auctor sit amet velit at placerat. Phasellus libero ante, molestie vel enim a, auctor fermentum nibh. Praesent at nisl suscipit, sollicitudin turpis ac, tempor odio. Donec accumsan fermentum mi quis tempus. Vivamus commodo convallis tempus.
|
|
||||||
|
|
||||||
Nulla eget eros dictum, tincidunt felis quis, egestas elit. Vestibulum tristique nec enim ornare scelerisque. Aliquam vulputate augue eget iaculis sollicitudin. Suspendisse in viverra sem. Morbi ac lectus at quam aliquet tempor a sit amet ex. Aenean dui lorem, maximus sit amet lorem a, venenatis sollicitudin nulla. Vestibulum ac metus metus. Nam rutrum in nunc ut viverra. Morbi euismod dignissim sem, vehicula rutrum mauris hendrerit nec. Nullam euismod placerat mi quis porttitor. Pellentesque eget consectetur risus. Cras volutpat vulputate pretium. Nullam non dolor pellentesque, molestie neque scelerisque, pharetra neque.
|
|
||||||
|
|
||||||
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec ligula turpis, pharetra vitae pretium et, posuere semper dui. Pellentesque in quam sit amet lacus maximus sagittis. Aliquam velit tortor, efficitur nec elementum non, commodo non ex. Aliquam eget mauris a nisi faucibus venenatis non eu enim. Phasellus in risus nulla. Suspendisse nec lectus nec tortor gravida finibus in et mauris.
|
|
||||||
|
|
||||||
Sed nec tellus venenatis, ultricies neque ac, malesuada ligula. Mauris posuere eget nibh vitae tristique. Quisque eget ligula accumsan ante dictum semper ut in mi. Sed felis nulla, sollicitudin eu vulputate non, auctor vel lacus. Mauris lectus mauris, mollis id facilisis auctor, ultrices a enim. Quisque ultricies ullamcorper magna, et porttitor metus convallis sed. Nullam vitae tortor feugiat, rutrum leo quis, lobortis mi. Nullam id purus est. Vestibulum mollis molestie velit sed iaculis. Phasellus dictum velit quis varius rhoncus. Curabitur et lacus in felis blandit condimentum sit amet id ex. Fusce eget nisl ipsum.
|
|
||||||
|
|
||||||
Phasellus at lorem finibus, consequat dolor et, consectetur sem. Integer hendrerit lorem eget orci pulvinar, quis ullamcorper neque semper. Nullam quam nibh, dignissim eu odio quis, sagittis facilisis ante. Aliquam lobortis sem dui, ac semper felis sodales sed. Interdum et malesuada fames ac ante ipsum primis in faucibus. Vestibulum blandit vitae est in blandit. Quisque et lobortis sem, quis ultricies mi. Praesent lectus ante, pellentesque et volutpat id, tristique pretium magna. Nulla ac posuere eros. Nulla imperdiet maximus porta. Aliquam in laoreet turpis. Fusce congue dolor dignissim, malesuada odio et, tristique velit. Nam mattis, justo aliquet semper pretium, ligula purus tristique mauris, quis volutpat neque est non sem. Nulla interdum condimentum quam, vitae sagittis velit. Duis ullamcorper mollis ligula, at pellentesque mauris porttitor a.
|
|
||||||
|
|
||||||
Donec dignissim ante ex, a dignissim tellus efficitur ac. Cras posuere purus ac orci accumsan mattis. Maecenas interdum sem et venenatis iaculis. Ut lobortis velit eu sagittis sollicitudin. Duis vitae diam diam. Duis quis leo mauris. Ut a leo sollicitudin ipsum vulputate auctor eu in ante. Vestibulum vel sem mauris. Vivamus varius, purus eget efficitur rutrum, dolor sem rhoncus metus, vitae ultricies felis nunc vel nisl.
|
|
||||||
|
|
||||||
Etiam iaculis, dolor non feugiat fringilla, dolor turpis luctus nunc, eget porta tortor lacus id lectus. Duis ac libero magna. Nam tincidunt dapibus accumsan. Donec auctor cursus ex at pretium. Maecenas consectetur accumsan orci hendrerit dignissim. Vestibulum lectus neque, sodales in ultricies ultricies, tincidunt ut massa. Sed id scelerisque lacus, quis dapibus nibh. Sed ante sem, pharetra in ipsum eu, imperdiet dapibus lectus. Integer auctor tempor odio. Mauris sagittis ex enim, vel lobortis turpis pulvinar ac. Vestibulum vel tortor quis mi ultrices ultricies eu ut neque. Phasellus vel massa et ex sagittis laoreet quis nec tortor. Aliquam sed facilisis arcu, quis molestie libero. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean vestibulum sapien erat.
|
|
||||||
|
|
||||||
Etiam pharetra et magna nec convallis. Cras in felis a turpis luctus semper sed vel nisi. Ut dignissim velit ex, nec malesuada eros lobortis elementum. In non velit nec erat suscipit pharetra. Ut posuere varius mauris sed luctus. Donec et sapien nec turpis dictum ultricies et nec nibh. Aenean maximus urna ut tempus fermentum. Vestibulum vulputate mi sit amet odio feugiat, vel posuere nisl facilisis. In congue pharetra nibh, id rhoncus odio cursus non. Ut vehicula lacus ipsum, convallis convallis mi facilisis sit amet. Aenean pulvinar bibendum justo sed laoreet. Vestibulum scelerisque congue euismod. Praesent a dolor tincidunt, congue nisi ut, placerat arcu.
|
|
||||||
|
|
||||||
Nulla sodales massa non augue eleifend consectetur. Nullam vitae diam sit amet est mattis lacinia. Donec condimentum purus nibh, eu fringilla diam bibendum sed. Etiam accumsan justo elit, a euismod nunc hendrerit ut. Suspendisse dictum leo enim, id malesuada augue auctor sed. Pellentesque convallis, quam eget commodo congue, augue felis feugiat nibh, ut luctus lorem metus non dolor. Quisque a semper orci. In libero nisi, porttitor vitae vehicula nec, iaculis et est. Morbi nec luctus sem, a dictum sem. Pellentesque interdum lacus elementum ultrices iaculis. Vestibulum quis magna eu orci tristique molestie. Proin commodo, nulla nec tempus porttitor, nulla arcu molestie neque, in commodo mauris mauris vel leo. Nullam tempus mauris et nunc dignissim, nec pretium tortor ornare. Suspendisse enim sem, rutrum a suscipit eu, bibendum vel felis. Etiam vel massa sed diam fringilla maximus. Proin accumsan dolor massa, a gravida eros feugiat in.
|
|
||||||
|
|
||||||
Phasellus aliquet nec mauris eu ultricies. Etiam ac commodo nulla. Etiam nec pellentesque nibh, vitae cursus erat. Integer condimentum pellentesque eleifend. In sed nulla justo. Nulla id dictum leo. Quisque felis felis, bibendum id dapibus at, euismod accumsan nisi. Sed justo mauris, hendrerit id metus finibus, sollicitudin consectetur nisl. Sed eget pharetra est, quis molestie diam. Proin tristique, odio at aliquam vulputate, metus justo rhoncus lorem, nec condimentum tortor sem eu purus. Mauris ut laoreet lectus. Aliquam non lorem ut magna porta luctus. Phasellus sit amet nibh sollicitudin, congue metus eu, consectetur arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
|
||||||
|
|
||||||
Vivamus consectetur rutrum pretium. Morbi ut pretium justo. Praesent euismod maximus elit. Sed vitae tincidunt arcu. Maecenas metus nulla, blandit quis mauris nec, dignissim placerat ligula. Ut sit amet lacus massa. Pellentesque posuere condimentum fermentum. Proin id nunc vitae sapien dictum egestas. In hac habitasse platea dictumst. Fusce ac viverra felis. Etiam ac nulla orci.
|
|
||||||
|
|
||||||
Nullam eget neque tristique, varius augue suscipit, pellentesque augue. Morbi aliquet vestibulum varius. Nulla ultrices efficitur molestie. Nullam tincidunt metus eu eros elementum, tempus tristique diam posuere. Praesent est purus, placerat vel nulla ut, sagittis lacinia sapien. Vestibulum turpis enim, gravida id sagittis non, sollicitudin eu justo. Cras accumsan tempus quam, sit amet lobortis lorem. Sed ac dui ex. Donec vestibulum dui sed elit gravida, nec scelerisque odio finibus. Sed scelerisque neque quam, in accumsan ante tincidunt sit amet. Phasellus eu facilisis metus. Nullam vitae justo erat.
|
|
||||||
|
|
||||||
Donec orci nisi, porttitor sed massa id, eleifend ultrices libero. Pellentesque efficitur volutpat arcu, at condimentum lorem scelerisque nec. Vestibulum posuere tincidunt semper. Nam at mattis urna. Ut pharetra quam a elementum finibus. Maecenas dapibus iaculis eros, in euismod ex tristique rutrum. Proin feugiat diam magna, vitae fringilla ligula commodo quis. Aenean finibus erat nec ipsum scelerisque tempus id sit amet lorem. Pellentesque sollicitudin, arcu a porta sodales, purus sapien hendrerit felis, vel ornare nibh nulla eget nulla. Donec nec sollicitudin odio. Nulla pharetra mi non cursus aliquam. Duis at ipsum at libero consequat fermentum in sit amet arcu. Suspendisse luctus diam quam, ut faucibus eros sodales et. Aliquam ut iaculis ligula. Quisque nibh turpis, vehicula at sapien eget, commodo sagittis urna. Suspendisse potenti.
|
|
||||||
|
|
||||||
Vestibulum volutpat porttitor dui porttitor ornare. Praesent condimentum turpis nec dolor finibus, eget mattis sapien ullamcorper. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce finibus quam ut quam pretium, pharetra suscipit ante porttitor. Donec sodales felis turpis. Sed ultricies, nulla quis mattis pulvinar, sapien magna interdum tellus, a fermentum turpis elit ac nulla. Donec fringilla metus vitae commodo molestie. Pellentesque non rutrum risus, eu ultricies dui. </string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -2,14 +2,23 @@ package org.nativescript.widgets;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowInsets;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.graphics.Insets;
|
import androidx.core.graphics.Insets;
|
||||||
|
import androidx.core.view.ViewCompat;
|
||||||
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hhristov
|
* @author hhristov
|
||||||
@ -20,21 +29,279 @@ public abstract class LayoutBase extends ViewGroup {
|
|||||||
|
|
||||||
public static final int OverflowEdgeNone = 0;
|
public static final int OverflowEdgeNone = 0;
|
||||||
public static final int OverflowEdgeLeft = 1;
|
public static final int OverflowEdgeLeft = 1;
|
||||||
public static final int OverflowEdgeTop = 2;
|
public static final int OverflowEdgeTop = 1 << 1;
|
||||||
public static final int OverflowEdgeRight = 3;
|
public static final int OverflowEdgeRight = 1 << 2;
|
||||||
public static final int OverflowEdgeBottom = 4;
|
public static final int OverflowEdgeBottom = 1 << 3;
|
||||||
public static final int OverflowEdgeDontApply = 5;
|
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;
|
||||||
|
public static final int INSET_TOP = 4;
|
||||||
|
public static final int INSET_RIGHT = 8;
|
||||||
|
public static final int INSET_BOTTOM = 12;
|
||||||
|
|
||||||
|
public static final int INSET_LEFT_CONSUMED = 16;
|
||||||
|
public static final int INSET_TOP_CONSUMED = 20;
|
||||||
|
public static final int INSET_RIGHT_CONSUMED = 24;
|
||||||
|
public static final int INSET_BOTTOM_CONSUMED = 28;
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
int mPaddingLeft = 0;
|
||||||
|
int mPaddingTop = 0;
|
||||||
|
int mPaddingRight = 0;
|
||||||
|
int mPaddingBottom = 0;
|
||||||
|
|
||||||
Insets edgeInsets = Insets.NONE;
|
Insets edgeInsets = Insets.NONE;
|
||||||
|
|
||||||
int overflowEdge = OverflowEdgeNone;
|
int overflowEdge = OverflowEdgeNone;
|
||||||
|
|
||||||
|
private final ByteBuffer insetBuffer = ByteBuffer.allocateDirect(32);
|
||||||
|
|
||||||
|
private WindowInsetListener insetListener = null;
|
||||||
|
|
||||||
|
public void setInsetListener(@Nullable WindowInsetListener insetListener) {
|
||||||
|
this.insetListener = insetListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface WindowInsetListener {
|
||||||
|
void onApplyWindowInsets(ByteBuffer inset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final byte[] EMPTY_INSETS = new byte[32];
|
||||||
|
|
||||||
|
|
||||||
|
private boolean pendingInsetApply = false;
|
||||||
|
private final OnAttachStateChangeListener onAttachStateChangeListener = new OnAttachStateChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onViewAttachedToWindow(@NonNull View v) {
|
||||||
|
if (pendingInsetApply) {
|
||||||
|
pendingInsetApply = false;
|
||||||
|
removeOnAttachStateChangeListener(onAttachStateChangeListener);
|
||||||
|
ViewCompat.requestApplyInsets(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewDetachedFromWindow(@NonNull View v) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public LayoutBase(Context context, AttributeSet attrs, int defStyleAttr) {
|
public LayoutBase(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, 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 (overflowBottom) {
|
||||||
|
ret = WindowInsetsCompat.CONSUMED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base.setPadding(left, top, right, bottom);
|
||||||
|
|
||||||
|
base.applyingEdges = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return insets;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(this, windowInsetsListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
|
||||||
|
return super.onApplyWindowInsets(insets);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LayoutBase(Context context) {
|
public LayoutBase(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Insets getEdgeInsets() {
|
public Insets getEdgeInsets() {
|
||||||
@ -115,11 +382,6 @@ public abstract class LayoutBase extends ViewGroup {
|
|||||||
this.passThroughParent = value;
|
this.passThroughParent = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mPaddingLeft = 0;
|
|
||||||
int mPaddingTop = 0;
|
|
||||||
int mPaddingRight = 0;
|
|
||||||
int mPaddingBottom = 0;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPadding(int left, int top, int right, int bottom) {
|
public void setPadding(int left, int top, int right, int bottom) {
|
||||||
if (!applyingEdges) {
|
if (!applyingEdges) {
|
||||||
@ -128,22 +390,20 @@ public abstract class LayoutBase extends ViewGroup {
|
|||||||
mPaddingRight = right;
|
mPaddingRight = right;
|
||||||
mPaddingBottom = bottom;
|
mPaddingBottom = bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!applyingEdges) {
|
|
||||||
Utils.LayoutBaseInset data = Utils.edgeToEdgeMap.get((AppCompatActivity) getContext());
|
|
||||||
if (data != null) {
|
|
||||||
Insets inset = Utils.getFinalInset(data.insets, this, overflowEdge);
|
|
||||||
super.setPadding(inset.left, inset.top, inset.right, inset.bottom);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
super.setPadding(left, top, right, bottom);
|
super.setPadding(left, top, right, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOverflowEdge(int value) {
|
public void setOverflowEdge(int value) {
|
||||||
overflowEdge = value;
|
overflowEdge = value;
|
||||||
Utils.setEdgeToEdgeForView(this, value);
|
if (pendingInsetApply) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isAttachedToWindow()) {
|
||||||
|
ViewCompat.requestApplyInsets(this);
|
||||||
|
} else {
|
||||||
|
pendingInsetApply = true;
|
||||||
|
addOnAttachStateChangeListener(onAttachStateChangeListener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getOverflowEdge() {
|
public int getOverflowEdge() {
|
||||||
|
@ -2,6 +2,7 @@ package org.nativescript.widgets;
|
|||||||
|
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
@ -24,11 +25,10 @@ import android.view.ViewGroup;
|
|||||||
import android.view.ViewParent;
|
import android.view.ViewParent;
|
||||||
|
|
||||||
import androidx.activity.ComponentActivity;
|
import androidx.activity.ComponentActivity;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.activity.SystemBarStyle;
|
||||||
|
import androidx.annotation.ColorInt;
|
||||||
import androidx.appcompat.content.res.AppCompatResources;
|
import androidx.appcompat.content.res.AppCompatResources;
|
||||||
import androidx.core.graphics.Insets;
|
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
|
||||||
import androidx.exifinterface.media.ExifInterface;
|
import androidx.exifinterface.media.ExifInterface;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@ -39,159 +39,54 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.WeakHashMap;
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
static class LayoutBaseInset {
|
public interface HandleDarkMode {
|
||||||
Insets insets;
|
boolean onHandle(int bar, Resources resources);
|
||||||
final ArrayList<LayoutBase> views;
|
}
|
||||||
|
|
||||||
LayoutBaseInset(Insets insets, ArrayList<LayoutBase> views) {
|
enum HandleDarkModeBar {
|
||||||
this.insets = insets;
|
status(0),
|
||||||
this.views = views;
|
navigation(1);
|
||||||
|
|
||||||
|
private final int mValue;
|
||||||
|
|
||||||
|
HandleDarkModeBar(int i) {
|
||||||
|
this.mValue = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return this.mValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static WeakHashMap<ComponentActivity, LayoutBaseInset> edgeToEdgeMap = new WeakHashMap<>();
|
// The light scrim color used in the platform API 29+
|
||||||
|
// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/com/android/internal/policy/DecorView.java;drc=6ef0f022c333385dba2c294e35b8de544455bf19;l=142
|
||||||
|
static final int DefaultLightScrim = Color.argb(0xe6, 0xFF, 0xFF, 0xFF);
|
||||||
|
|
||||||
static void setEdgeToEdgeForView(LayoutBase base, int overflowEdge) {
|
// The dark scrim color used in the platform.
|
||||||
if (base.applyingEdges) {
|
// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/res/res/color/system_bar_background_semi_transparent.xml
|
||||||
return;
|
// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/res/remote_color_resources_res/values/colors.xml;l=67
|
||||||
}
|
static final int DefaultDarkScrim = Color.argb(0x80, 0x1b, 0x1b, 0x1b);
|
||||||
ComponentActivity activity = (ComponentActivity) base.getContext();
|
|
||||||
if (activity != null) {
|
|
||||||
LayoutBaseInset data = edgeToEdgeMap.get(activity);
|
|
||||||
if (data != null) {
|
|
||||||
if (!data.views.contains(base)) {
|
|
||||||
data.views.add(base);
|
|
||||||
}
|
|
||||||
|
|
||||||
applyEdges(data.insets, base, overflowEdge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void applyEdgeToEdge(Insets insets, ArrayList<LayoutBase> views) {
|
|
||||||
for (LayoutBase base : views) {
|
|
||||||
applyEdges(insets, base, base.overflowEdge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void applyEdges(Insets insets, LayoutBase view, int overflowEdge) {
|
|
||||||
int left = view.mPaddingLeft;
|
|
||||||
int top = view.mPaddingTop;
|
|
||||||
int right = view.mPaddingRight;
|
|
||||||
int bottom = view.mPaddingBottom;
|
|
||||||
switch (overflowEdge) {
|
|
||||||
case LayoutBase.OverflowEdgeNone:
|
|
||||||
left = left + insets.left;
|
|
||||||
top = top + insets.top;
|
|
||||||
right = right + insets.right;
|
|
||||||
bottom = bottom + insets.bottom;
|
|
||||||
break;
|
|
||||||
case LayoutBase.OverflowEdgeDontApply:
|
|
||||||
view.edgeInsets = insets;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
boolean consumeLeft = (view.overflowEdge & LayoutBase.OverflowEdgeLeft) == LayoutBase.OverflowEdgeLeft;
|
|
||||||
boolean consumeTop = (view.overflowEdge & LayoutBase.OverflowEdgeTop) == LayoutBase.OverflowEdgeTop;
|
|
||||||
boolean consumeRight = (view.overflowEdge & LayoutBase.OverflowEdgeRight) == LayoutBase.OverflowEdgeRight;
|
|
||||||
boolean consumeBottom = (view.overflowEdge & LayoutBase.OverflowEdgeBottom) == LayoutBase.OverflowEdgeBottom;
|
|
||||||
|
|
||||||
if (consumeLeft) {
|
|
||||||
left = left + insets.left;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consumeTop) {
|
|
||||||
top = top + insets.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consumeRight) {
|
|
||||||
right = right + insets.right;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consumeBottom) {
|
|
||||||
bottom = bottom + insets.bottom;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
view.applyingEdges = true;
|
|
||||||
view.setPadding(left, top, right, bottom);
|
|
||||||
view.applyingEdges = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Insets getFinalInset(Insets insets, LayoutBase view, int overflowEdge) {
|
|
||||||
int left = view.mPaddingLeft;
|
|
||||||
int top = view.mPaddingTop;
|
|
||||||
int right = view.mPaddingRight;
|
|
||||||
int bottom = view.mPaddingBottom;
|
|
||||||
switch (overflowEdge) {
|
|
||||||
case LayoutBase.OverflowEdgeNone:
|
|
||||||
left = left + insets.left;
|
|
||||||
top = top + insets.top;
|
|
||||||
right = right + insets.right;
|
|
||||||
bottom = bottom + insets.bottom;
|
|
||||||
break;
|
|
||||||
case LayoutBase.OverflowEdgeDontApply:
|
|
||||||
view.edgeInsets = insets;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
boolean consumeLeft = (view.overflowEdge & LayoutBase.OverflowEdgeLeft) == LayoutBase.OverflowEdgeLeft;
|
|
||||||
boolean consumeTop = (view.overflowEdge & LayoutBase.OverflowEdgeTop) == LayoutBase.OverflowEdgeTop;
|
|
||||||
boolean consumeRight = (view.overflowEdge & LayoutBase.OverflowEdgeRight) == LayoutBase.OverflowEdgeRight;
|
|
||||||
boolean consumeBottom = (view.overflowEdge & LayoutBase.OverflowEdgeBottom) == LayoutBase.OverflowEdgeBottom;
|
|
||||||
|
|
||||||
if (consumeLeft) {
|
|
||||||
left = left + insets.left;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consumeTop) {
|
|
||||||
top = top + insets.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consumeRight) {
|
|
||||||
right = right + insets.right;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consumeBottom) {
|
|
||||||
bottom = bottom + insets.bottom;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return Insets.of(left, top, right, bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void enableEdgeToEdge(ComponentActivity activity) {
|
public static void enableEdgeToEdge(ComponentActivity activity) {
|
||||||
androidx.activity.EdgeToEdge.enable(activity);
|
androidx.activity.EdgeToEdge.enable(activity);
|
||||||
if (!Utils.edgeToEdgeMap.containsKey(activity)) {
|
|
||||||
Utils.edgeToEdgeMap.put(activity, new Utils.LayoutBaseInset(Insets.NONE, new ArrayList<>()));
|
|
||||||
}
|
}
|
||||||
View view = activity.findViewById(android.R.id.content);
|
|
||||||
if (view != null) {
|
public static void enableEdgeToEdge(ComponentActivity activity, HandleDarkMode handleDarkMode) {
|
||||||
androidx.core.view.OnApplyWindowInsetsListener listener = new androidx.core.view.OnApplyWindowInsetsListener() {
|
androidx.activity.EdgeToEdge.enable(activity, SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT, resources -> handleDarkMode.onHandle(HandleDarkModeBar.status.getValue(), resources)), SystemBarStyle.auto(DefaultLightScrim, DefaultDarkScrim, resources -> handleDarkMode.onHandle(HandleDarkModeBar.navigation.getValue(), resources)));
|
||||||
@Override
|
|
||||||
public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) {
|
|
||||||
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
|
||||||
if (Utils.edgeToEdgeMap.containsKey(activity)) {
|
|
||||||
LayoutBaseInset data = Utils.edgeToEdgeMap.get(activity);
|
|
||||||
if (data != null) {
|
|
||||||
data.insets = systemBars;
|
|
||||||
Utils.applyEdgeToEdge(systemBars, data.views);
|
|
||||||
} else {
|
|
||||||
Utils.edgeToEdgeMap.put(activity, new LayoutBaseInset(systemBars, new ArrayList<>()));
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Utils.edgeToEdgeMap.put(activity, new LayoutBaseInset(systemBars, new ArrayList<>()));
|
public static void enableEdgeToEdge(ComponentActivity activity, @ColorInt Integer statusBarLight, @ColorInt Integer statusBarDark, @ColorInt Integer navigationBarLight, @ColorInt Integer navigationBarDark) {
|
||||||
}
|
androidx.activity.EdgeToEdge.enable(activity, SystemBarStyle.auto(statusBarLight, statusBarDark), SystemBarStyle.auto(navigationBarLight, navigationBarDark));
|
||||||
return insets;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(view, listener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void enableEdgeToEdge(ComponentActivity activity, @ColorInt Integer statusBarLight, @ColorInt Integer statusBarDark, @ColorInt Integer navigationBarLight, @ColorInt Integer navigationBarDark, HandleDarkMode handleDarkMode) {
|
||||||
|
androidx.activity.EdgeToEdge.enable(activity, SystemBarStyle.auto(statusBarLight, statusBarDark, resources -> handleDarkMode.onHandle(HandleDarkModeBar.status.getValue(), resources)), SystemBarStyle.auto(navigationBarLight, navigationBarDark, resources -> handleDarkMode.onHandle(HandleDarkModeBar.navigation.getValue(), resources)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Drawable getDrawable(String uri, Context context) {
|
public static Drawable getDrawable(String uri, Context context) {
|
||||||
|
Reference in New Issue
Block a user