mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-18 22:01:42 +08:00

* cache page on forward navigation Still some failing navigation tests * Current page is kept alive when navigating forward Refactoring code and removing all hacks and flags Remove one module circular reference * Disable Page recycling because when there is transition between pages the nativeView stays animated (e.g. when transition is Fade the hidden page nativeView stays with Alpha 0) Disable recycling if there is native anitmation * Fix failing tests on ios & android API17 Fix wrong urls in http tests Made some timer tests async * Animations are not stored in BackstackEntry instead of Fragment because fragments could die (activity die) and recreated and we lose animations. * Fix android crash when activity is recreated. Refactoring transitionListener.
218 lines
7.6 KiB
TypeScript
218 lines
7.6 KiB
TypeScript
import { View, PageBase, Color, actionBarHiddenProperty, statusBarStyleProperty, androidStatusBarBackgroundProperty } from "./page-common";
|
|
import { ActionBar } from "../action-bar";
|
|
import { GridLayout } from "../layouts/grid-layout";
|
|
import { DIALOG_FRAGMENT_TAG } from "./constants";
|
|
import { device } from "../../platform";
|
|
import { profile } from "../../profiling";
|
|
|
|
export * from "./page-common";
|
|
|
|
const SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0x00002000;
|
|
const STATUS_BAR_LIGHT_BCKG = -657931;
|
|
const STATUS_BAR_DARK_BCKG = 1711276032;
|
|
|
|
interface DialogFragment {
|
|
new (owner: Page, fullscreen: boolean, shownCallback: () => void, dismissCallback: () => void): android.app.DialogFragment;
|
|
}
|
|
let DialogFragment: DialogFragment;
|
|
|
|
function initializeDialogFragment() {
|
|
if (DialogFragment) {
|
|
return;
|
|
}
|
|
|
|
class DialogFragmentImpl extends android.app.DialogFragment {
|
|
constructor(
|
|
private _owner: Page,
|
|
private _fullscreen: boolean,
|
|
private _shownCallback: () => void,
|
|
private _dismissCallback: () => void) {
|
|
super();
|
|
return global.__native(this);
|
|
}
|
|
|
|
public onCreateDialog(savedInstanceState: android.os.Bundle): android.app.Dialog {
|
|
const dialog = new android.app.Dialog(this._owner._context);
|
|
dialog.requestWindowFeature(android.view.Window.FEATURE_NO_TITLE);
|
|
|
|
// Hide actionBar and adjust alignment based on _fullscreen value.
|
|
this._owner.horizontalAlignment = this._fullscreen ? "stretch" : "center";
|
|
this._owner.verticalAlignment = this._fullscreen ? "stretch" : "middle";
|
|
this._owner.actionBarHidden = true;
|
|
|
|
const nativeView = <android.view.View>this._owner.nativeViewProtected;
|
|
let layoutParams = nativeView.getLayoutParams();
|
|
if (!layoutParams) {
|
|
layoutParams = new org.nativescript.widgets.CommonLayoutParams();
|
|
nativeView.setLayoutParams(layoutParams);
|
|
}
|
|
dialog.setContentView(this._owner.nativeViewProtected, layoutParams);
|
|
|
|
const window = dialog.getWindow();
|
|
window.setBackgroundDrawable(new android.graphics.drawable.ColorDrawable(android.graphics.Color.TRANSPARENT));
|
|
|
|
if (this._fullscreen) {
|
|
window.setLayout(android.view.ViewGroup.LayoutParams.FILL_PARENT, android.view.ViewGroup.LayoutParams.FILL_PARENT);
|
|
}
|
|
|
|
return dialog;
|
|
}
|
|
|
|
public onStart() {
|
|
super.onStart();
|
|
if (!this._owner.isLoaded) {
|
|
this._owner.onLoaded();
|
|
}
|
|
this._shownCallback();
|
|
}
|
|
|
|
public onDestroyView() {
|
|
super.onDestroyView();
|
|
|
|
if (this._owner.isLoaded) {
|
|
this._owner.onUnloaded();
|
|
}
|
|
|
|
this._owner._isAddedToNativeVisualTree = false;
|
|
this._owner._tearDownUI(true);
|
|
}
|
|
|
|
public onDismiss(dialog: android.content.IDialogInterface) {
|
|
super.onDismiss(dialog);
|
|
this._dismissCallback();
|
|
}
|
|
|
|
};
|
|
|
|
DialogFragment = DialogFragmentImpl;
|
|
}
|
|
|
|
export class Page extends PageBase {
|
|
nativeViewProtected: org.nativescript.widgets.GridLayout;
|
|
private _isBackNavigation = false;
|
|
|
|
public createNativeView() {
|
|
const layout = new org.nativescript.widgets.GridLayout(this._context);
|
|
layout.addRow(new org.nativescript.widgets.ItemSpec(1, org.nativescript.widgets.GridUnitType.auto));
|
|
layout.addRow(new org.nativescript.widgets.ItemSpec(1, org.nativescript.widgets.GridUnitType.star));
|
|
return layout;
|
|
}
|
|
|
|
public initNativeView(): void {
|
|
super.initNativeView();
|
|
this.nativeViewProtected.setBackgroundColor(-1); // White color.
|
|
}
|
|
|
|
public _addViewToNativeVisualTree(child: View, atIndex?: number): boolean {
|
|
// Set the row property for the child
|
|
if (this.nativeViewProtected && child.nativeViewProtected) {
|
|
if (child instanceof ActionBar) {
|
|
GridLayout.setRow(child, 0);
|
|
child.horizontalAlignment = "stretch";
|
|
child.verticalAlignment = "top";
|
|
}
|
|
else {
|
|
GridLayout.setRow(child, 1);
|
|
}
|
|
}
|
|
|
|
return super._addViewToNativeVisualTree(child, atIndex);
|
|
}
|
|
|
|
@profile
|
|
public onLoaded() {
|
|
super.onLoaded();
|
|
if (this.actionBarHidden !== undefined) {
|
|
this.updateActionBar();
|
|
}
|
|
}
|
|
|
|
/* tslint:disable */
|
|
private _dialogFragment: android.app.DialogFragment;
|
|
/* tslint:enable */
|
|
protected _showNativeModalView(parent: Page, context: any, closeCallback: Function, fullscreen?: boolean) {
|
|
super._showNativeModalView(parent, context, closeCallback, fullscreen);
|
|
if (!this.backgroundColor) {
|
|
this.backgroundColor = new Color("White");
|
|
}
|
|
|
|
this._setupUI(parent._context);
|
|
this._isAddedToNativeVisualTree = true;
|
|
|
|
initializeDialogFragment();
|
|
|
|
this._dialogFragment = new DialogFragment(this, !!fullscreen, () => this._raiseShownModallyEvent(), () => this.closeModal());
|
|
|
|
super._raiseShowingModallyEvent();
|
|
|
|
this._dialogFragment.show(parent.frame.android.activity.getFragmentManager(), DIALOG_FRAGMENT_TAG);
|
|
}
|
|
|
|
protected _hideNativeModalView(parent: Page) {
|
|
this._dialogFragment.dismissAllowingStateLoss();
|
|
this._dialogFragment = null;
|
|
|
|
parent._modal = undefined;
|
|
|
|
super._hideNativeModalView(parent);
|
|
}
|
|
|
|
private updateActionBar() {
|
|
this.actionBar.update();
|
|
}
|
|
|
|
[actionBarHiddenProperty.getDefault](): boolean {
|
|
return undefined;
|
|
}
|
|
[actionBarHiddenProperty.setNative](value: boolean) {
|
|
this.updateActionBar();
|
|
}
|
|
|
|
[statusBarStyleProperty.getDefault](): { color: number, systemUiVisibility: number } {
|
|
if (device.sdkVersion >= "21") {
|
|
let window = (<android.app.Activity>this._context).getWindow();
|
|
let decorView = window.getDecorView();
|
|
|
|
return {
|
|
color: (<any>window).getStatusBarColor(),
|
|
systemUiVisibility: decorView.getSystemUiVisibility()
|
|
};
|
|
}
|
|
|
|
return null;
|
|
}
|
|
[statusBarStyleProperty.setNative](value: "dark" | "light" | { color: number, systemUiVisibility: number }) {
|
|
if (device.sdkVersion >= "21") {
|
|
let window = (<android.app.Activity>this._context).getWindow();
|
|
let decorView = window.getDecorView();
|
|
|
|
if (value === "light") {
|
|
(<any>window).setStatusBarColor(STATUS_BAR_LIGHT_BCKG);
|
|
decorView.setSystemUiVisibility(SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
|
|
|
} else if (value === "dark") {
|
|
(<any>window).setStatusBarColor(STATUS_BAR_DARK_BCKG);
|
|
decorView.setSystemUiVisibility(0);
|
|
} else {
|
|
(<any>window).setStatusBarColor(value.color);
|
|
decorView.setSystemUiVisibility(value.systemUiVisibility);
|
|
}
|
|
}
|
|
}
|
|
|
|
[androidStatusBarBackgroundProperty.getDefault](): number {
|
|
if (device.sdkVersion >= "21") {
|
|
let window = (<android.app.Activity>this._context).getWindow();
|
|
return (<any>window).getStatusBarColor();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
[androidStatusBarBackgroundProperty.setNative](value: number | Color) {
|
|
if (device.sdkVersion >= "21") {
|
|
let window = (<android.app.Activity>this._context).getWindow();
|
|
let color = value instanceof Color ? value.android : value;
|
|
(<any>window).setStatusBarColor(color);
|
|
}
|
|
}
|
|
} |