mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 11:01:21 +08:00
feat(android): migrate to support library apis (#6129)
Switch Activity / Fragment / FragmentManager implementation from native framework to support library APIs BREAKING CHANGE: NativeScript core framework now extends support library APIs versus native framework classes as per Google's latest guidelines: - NativeScript activities now extend `android.support.v7.app.AppCompatActivity` (vs android.app.Activity) - NativeScript fragments now extend `android.support.v4.app.Fragment` (vs android.app.Fragment) - NativeScript now works internally with `android.support.v4.app.FragmentManager` (vs android.app.FragmentManager) The implications of these changes should be mostly transparent to the developer except for the fact that the support library Fragment / FragmentManager work with Animation APIs versus Animator APIs. For Android API Levels lower than 28 the new Fragment API uses a different fragment enter animation by default. You can customise the transition per navigation entry or globally via the [navigation transitions API](https://docs.nativescript.org/core-concepts/navigation#navigation-transitions) Before: Default fragment enter animation was fade animation After: Default fragment enter animation for API levels lower than 28 is now a fast "push fade" animation; default fragment enter animation for API levels equal to or greater than 28 remains fade animation Before: AndroidFragmentCallbacks interface exposed the following `onCreateAnimator(...)` method ``` ts export interface AndroidFragmentCallbacks { onCreateAnimator(fragment: any, transit: number, enter: boolean, nextAnim: number, superFunc: Function): any; // ... } ``` After: AndroidFragmentCallbacks interface now exposes the following `onCreateAnimation(...)` method instead (and `onCreateAnimator(...)` is now removed) ``` ts export interface AndroidFragmentCallbacks { onCreateAnimation(fragment: any, transit: number, enter: boolean, nextAnim: number, superFunc: Function): any; // ... } ``` Before: Transition class exposed the following abstract `createAndroidAnimator(...)` method ``` ts export class Transition { public createAndroidAnimator(transitionType: string): any; // ... } ``` After: Transition class now exposes the following abstract `createAndroidAnimation(...)` method instead (and `createAndroidAnimation(...) is now removed) ``` ts export class Transition { public createAndroidAnimation(transitionType: string): any; // ... } ``` To migrate the code of your custom transitions follow the example below: Before: ``` ts import * as transition from "tns-core-modules/ui/transition"; export class CustomTransition extends transition.Transition { constructor(duration: number, curve: any) { super(duration, curve); } public createAndroidAnimator(transitionType: string): android.animation.Animator { var scaleValues = Array.create("float", 2); switch (transitionType) { case transition.AndroidTransitionType.enter: case transition.AndroidTransitionType.popEnter: scaleValues[0] = 0; scaleValues[1] = 1; break; case transition.AndroidTransitionType.exit: case transition.AndroidTransitionType.popExit: scaleValues[0] = 1; scaleValues[1] = 0; break; } var objectAnimators = Array.create(android.animation.Animator, 2); objectAnimators[0] = android.animation.ObjectAnimator.ofFloat(null, "scaleX", scaleValues); objectAnimators[1] = android.animation.ObjectAnimator.ofFloat(null, "scaleY", scaleValues); var animatorSet = new android.animation.AnimatorSet(); animatorSet.playTogether(objectAnimators); var duration = this.getDuration(); if (duration !== undefined) { animatorSet.setDuration(duration); } animatorSet.setInterpolator(this.getCurve()); return animatorSet; } } ``` After: ``` ts import * as transition from "tns-core-modules/ui/transition"; export class CustomTransition extends transition.Transition { constructor(duration: number, curve: any) { super(duration, curve); } public createAndroidAnimation(transitionType: string): android.view.animation.Animation { const scaleValues = []; switch (transitionType) { case transition.AndroidTransitionType.enter: case transition.AndroidTransitionType.popEnter: scaleValues[0] = 0; scaleValues[1] = 1; break; case transition.AndroidTransitionType.exit: case transition.AndroidTransitionType.popExit: scaleValues[0] = 1; scaleValues[1] = 0; break; } const animationSet = new android.view.animation.AnimationSet(false); const duration = this.getDuration(); if (duration !== undefined) { animationSet.setDuration(duration); } animationSet.setInterpolator(this.getCurve()); animationSet.addAnimation( new android.view.animation.ScaleAnimation( scaleValues[0], scaleValues[1], scaleValues[0], scaleValues[1] )); return animationSet; } } ```
This commit is contained in:
@ -5,8 +5,9 @@ export class CustomTransition extends transition.Transition {
|
|||||||
super(duration, curve);
|
super(duration, curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||||
var scaleValues = Array.create("float", 2);
|
const scaleValues = [];
|
||||||
|
|
||||||
switch (transitionType) {
|
switch (transitionType) {
|
||||||
case transition.AndroidTransitionType.enter:
|
case transition.AndroidTransitionType.enter:
|
||||||
case transition.AndroidTransitionType.popEnter:
|
case transition.AndroidTransitionType.popEnter:
|
||||||
@ -19,18 +20,22 @@ export class CustomTransition extends transition.Transition {
|
|||||||
scaleValues[1] = 0;
|
scaleValues[1] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var objectAnimators = Array.create(android.animation.Animator, 2);
|
|
||||||
objectAnimators[0] = android.animation.ObjectAnimator.ofFloat(null, "scaleX", scaleValues);
|
const animationSet = new android.view.animation.AnimationSet(false);
|
||||||
objectAnimators[1] = android.animation.ObjectAnimator.ofFloat(null, "scaleY", scaleValues);
|
const duration = this.getDuration();
|
||||||
var animatorSet = new android.animation.AnimatorSet();
|
|
||||||
animatorSet.playTogether(objectAnimators);
|
|
||||||
|
|
||||||
var duration = this.getDuration();
|
|
||||||
if (duration !== undefined) {
|
if (duration !== undefined) {
|
||||||
animatorSet.setDuration(duration);
|
animationSet.setDuration(duration);
|
||||||
}
|
}
|
||||||
animatorSet.setInterpolator(this.getCurve());
|
|
||||||
|
|
||||||
return animatorSet;
|
animationSet.setInterpolator(this.getCurve());
|
||||||
|
animationSet.addAnimation(
|
||||||
|
new android.view.animation.ScaleAnimation(
|
||||||
|
scaleValues[0],
|
||||||
|
scaleValues[1],
|
||||||
|
scaleValues[0],
|
||||||
|
scaleValues[1]
|
||||||
|
));
|
||||||
|
|
||||||
|
return animationSet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,8 @@ export class AndroidApplication extends Observable implements AndroidApplication
|
|||||||
public paused: boolean;
|
public paused: boolean;
|
||||||
public nativeApp: android.app.Application;
|
public nativeApp: android.app.Application;
|
||||||
public context: android.content.Context;
|
public context: android.content.Context;
|
||||||
public foregroundActivity: android.app.Activity;
|
public foregroundActivity: android.support.v7.app.AppCompatActivity;
|
||||||
public startActivity: android.app.Activity;
|
public startActivity: android.support.v7.app.AppCompatActivity;
|
||||||
public packageName: string;
|
public packageName: string;
|
||||||
// we are using these property to store the callbacks to avoid early GC collection which would trigger MarkReachableObjects
|
// we are using these property to store the callbacks to avoid early GC collection which would trigger MarkReachableObjects
|
||||||
private callbacks: any = {};
|
private callbacks: any = {};
|
||||||
@ -221,7 +221,7 @@ global.__onLiveSync = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function initLifecycleCallbacks() {
|
function initLifecycleCallbacks() {
|
||||||
const setThemeOnLaunch = profile("setThemeOnLaunch", (activity: android.app.Activity) => {
|
const setThemeOnLaunch = profile("setThemeOnLaunch", (activity: android.support.v7.app.AppCompatActivity) => {
|
||||||
// Set app theme after launch screen was used during startup
|
// Set app theme after launch screen was used during startup
|
||||||
const activityInfo = activity.getPackageManager().getActivityInfo(activity.getComponentName(), android.content.pm.PackageManager.GET_META_DATA);
|
const activityInfo = activity.getPackageManager().getActivityInfo(activity.getComponentName(), android.content.pm.PackageManager.GET_META_DATA);
|
||||||
if (activityInfo.metaData) {
|
if (activityInfo.metaData) {
|
||||||
@ -232,11 +232,11 @@ function initLifecycleCallbacks() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const notifyActivityCreated = profile("notifyActivityCreated", function (activity: android.app.Activity, savedInstanceState: android.os.Bundle) {
|
const notifyActivityCreated = profile("notifyActivityCreated", function (activity: android.support.v7.app.AppCompatActivity, savedInstanceState: android.os.Bundle) {
|
||||||
androidApp.notify(<AndroidActivityBundleEventData>{ eventName: ActivityCreated, object: androidApp, activity, bundle: savedInstanceState });
|
androidApp.notify(<AndroidActivityBundleEventData>{ eventName: ActivityCreated, object: androidApp, activity, bundle: savedInstanceState });
|
||||||
});
|
});
|
||||||
|
|
||||||
const subscribeForGlobalLayout = profile("subscribeForGlobalLayout", function (activity: android.app.Activity) {
|
const subscribeForGlobalLayout = profile("subscribeForGlobalLayout", function (activity: android.support.v7.app.AppCompatActivity) {
|
||||||
const rootView = activity.getWindow().getDecorView().getRootView();
|
const rootView = activity.getWindow().getDecorView().getRootView();
|
||||||
// store the listener not to trigger GC collection before collecting the method
|
// store the listener not to trigger GC collection before collecting the method
|
||||||
this.onGlobalLayoutListener = new android.view.ViewTreeObserver.OnGlobalLayoutListener({
|
this.onGlobalLayoutListener = new android.view.ViewTreeObserver.OnGlobalLayoutListener({
|
||||||
@ -250,7 +250,7 @@ function initLifecycleCallbacks() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const lifecycleCallbacks = new android.app.Application.ActivityLifecycleCallbacks({
|
const lifecycleCallbacks = new android.app.Application.ActivityLifecycleCallbacks({
|
||||||
onActivityCreated: profile("onActivityCreated", function (activity: android.app.Activity, savedInstanceState: android.os.Bundle) {
|
onActivityCreated: profile("onActivityCreated", function (activity: android.support.v7.app.AppCompatActivity, savedInstanceState: android.os.Bundle) {
|
||||||
setThemeOnLaunch(activity);
|
setThemeOnLaunch(activity);
|
||||||
|
|
||||||
if (!androidApp.startActivity) {
|
if (!androidApp.startActivity) {
|
||||||
@ -264,7 +264,7 @@ function initLifecycleCallbacks() {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
onActivityDestroyed: profile("onActivityDestroyed", function (activity: android.app.Activity) {
|
onActivityDestroyed: profile("onActivityDestroyed", function (activity: android.support.v7.app.AppCompatActivity) {
|
||||||
if (activity === androidApp.foregroundActivity) {
|
if (activity === androidApp.foregroundActivity) {
|
||||||
androidApp.foregroundActivity = undefined;
|
androidApp.foregroundActivity = undefined;
|
||||||
}
|
}
|
||||||
@ -278,7 +278,7 @@ function initLifecycleCallbacks() {
|
|||||||
gc();
|
gc();
|
||||||
}),
|
}),
|
||||||
|
|
||||||
onActivityPaused: profile("onActivityPaused", function (activity: android.app.Activity) {
|
onActivityPaused: profile("onActivityPaused", function (activity: android.support.v7.app.AppCompatActivity) {
|
||||||
if ((<any>activity).isNativeScriptActivity) {
|
if ((<any>activity).isNativeScriptActivity) {
|
||||||
androidApp.paused = true;
|
androidApp.paused = true;
|
||||||
notify(<ApplicationEventData>{ eventName: suspendEvent, object: androidApp, android: activity });
|
notify(<ApplicationEventData>{ eventName: suspendEvent, object: androidApp, android: activity });
|
||||||
@ -287,7 +287,7 @@ function initLifecycleCallbacks() {
|
|||||||
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityPaused, object: androidApp, activity: activity });
|
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityPaused, object: androidApp, activity: activity });
|
||||||
}),
|
}),
|
||||||
|
|
||||||
onActivityResumed: profile("onActivityResumed", function (activity: android.app.Activity) {
|
onActivityResumed: profile("onActivityResumed", function (activity: android.support.v7.app.AppCompatActivity) {
|
||||||
androidApp.foregroundActivity = activity;
|
androidApp.foregroundActivity = activity;
|
||||||
|
|
||||||
if ((<any>activity).isNativeScriptActivity) {
|
if ((<any>activity).isNativeScriptActivity) {
|
||||||
@ -298,15 +298,15 @@ function initLifecycleCallbacks() {
|
|||||||
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityResumed, object: androidApp, activity: activity });
|
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityResumed, object: androidApp, activity: activity });
|
||||||
}),
|
}),
|
||||||
|
|
||||||
onActivitySaveInstanceState: profile("onActivityResumed", function (activity: android.app.Activity, outState: android.os.Bundle) {
|
onActivitySaveInstanceState: profile("onActivityResumed", function (activity: android.support.v7.app.AppCompatActivity, outState: android.os.Bundle) {
|
||||||
androidApp.notify(<AndroidActivityBundleEventData>{ eventName: SaveActivityState, object: androidApp, activity: activity, bundle: outState });
|
androidApp.notify(<AndroidActivityBundleEventData>{ eventName: SaveActivityState, object: androidApp, activity: activity, bundle: outState });
|
||||||
}),
|
}),
|
||||||
|
|
||||||
onActivityStarted: profile("onActivityStarted", function (activity: android.app.Activity) {
|
onActivityStarted: profile("onActivityStarted", function (activity: android.support.v7.app.AppCompatActivity) {
|
||||||
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityStarted, object: androidApp, activity: activity });
|
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityStarted, object: androidApp, activity: activity });
|
||||||
}),
|
}),
|
||||||
|
|
||||||
onActivityStopped: profile("onActivityStopped", function (activity: android.app.Activity) {
|
onActivityStopped: profile("onActivityStopped", function (activity: android.support.v7.app.AppCompatActivity) {
|
||||||
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityStopped, object: androidApp, activity: activity });
|
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityStopped, object: androidApp, activity: activity });
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -288,7 +288,7 @@ export interface AndroidActivityEventData {
|
|||||||
/**
|
/**
|
||||||
* The activity.
|
* The activity.
|
||||||
*/
|
*/
|
||||||
activity: any /* android.app.Activity */;
|
activity: any /* android.support.v7.app.AppCompatActivity */;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the event.
|
* The name of the event.
|
||||||
@ -378,7 +378,7 @@ export class AndroidApplication extends Observable {
|
|||||||
/**
|
/**
|
||||||
* The currently active (loaded) [android Activity](http://developer.android.com/reference/android/app/Activity.html). This property is automatically updated upon Activity events.
|
* The currently active (loaded) [android Activity](http://developer.android.com/reference/android/app/Activity.html). This property is automatically updated upon Activity events.
|
||||||
*/
|
*/
|
||||||
foregroundActivity: any /* android.app.Activity */;
|
foregroundActivity: any /* android.support.v7.app.AppCompatActivity */;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated. Please use startActivity, foregroundActivity or context property.
|
* Deprecated. Please use startActivity, foregroundActivity or context property.
|
||||||
@ -388,7 +388,7 @@ export class AndroidApplication extends Observable {
|
|||||||
/**
|
/**
|
||||||
* The main (start) Activity for the application.
|
* The main (start) Activity for the application.
|
||||||
*/
|
*/
|
||||||
startActivity: any /* android.app.Activity */;
|
startActivity: any /* android.support.v7.app.AppCompatActivity */;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the application package.
|
* The name of the application package.
|
||||||
|
@ -47,7 +47,7 @@ interface TouchListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface DialogFragment {
|
interface DialogFragment {
|
||||||
new(): android.app.DialogFragment;
|
new(): android.support.v4.app.DialogFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
function initializeDisabledListener(): void {
|
function initializeDisabledListener(): void {
|
||||||
@ -120,7 +120,7 @@ function initializeDialogFragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DialogFragmentImpl extends android.app.DialogFragment {
|
class DialogFragmentImpl extends android.support.v4.app.DialogFragment {
|
||||||
public owner: View;
|
public owner: View;
|
||||||
private _fullscreen: boolean;
|
private _fullscreen: boolean;
|
||||||
private _stretched: boolean;
|
private _stretched: boolean;
|
||||||
@ -141,7 +141,7 @@ function initializeDialogFragment() {
|
|||||||
this._dismissCallback = options.dismissCallback;
|
this._dismissCallback = options.dismissCallback;
|
||||||
this._shownCallback = options.shownCallback;
|
this._shownCallback = options.shownCallback;
|
||||||
this.owner._dialogFragment = this;
|
this.owner._dialogFragment = this;
|
||||||
this.setStyle(android.app.DialogFragment.STYLE_NO_TITLE, 0);
|
this.setStyle(android.support.v4.app.DialogFragment.STYLE_NO_TITLE, 0);
|
||||||
|
|
||||||
const dialog = new DialogImpl(this, this.getActivity(), this.getTheme());
|
const dialog = new DialogImpl(this, this.getActivity(), this.getTheme());
|
||||||
|
|
||||||
@ -225,13 +225,13 @@ function getModalOptions(domId: number): DialogOptions {
|
|||||||
export class View extends ViewCommon {
|
export class View extends ViewCommon {
|
||||||
public static androidBackPressedEvent = androidBackPressedEvent;
|
public static androidBackPressedEvent = androidBackPressedEvent;
|
||||||
|
|
||||||
public _dialogFragment: android.app.DialogFragment;
|
public _dialogFragment: android.support.v4.app.DialogFragment;
|
||||||
private _isClickable: boolean;
|
private _isClickable: boolean;
|
||||||
private touchListenerIsSet: boolean;
|
private touchListenerIsSet: boolean;
|
||||||
private touchListener: android.view.View.OnTouchListener;
|
private touchListener: android.view.View.OnTouchListener;
|
||||||
private layoutChangeListenerIsSet: boolean;
|
private layoutChangeListenerIsSet: boolean;
|
||||||
private layoutChangeListener: android.view.View.OnLayoutChangeListener;
|
private layoutChangeListener: android.view.View.OnLayoutChangeListener;
|
||||||
private _manager: android.app.FragmentManager;
|
private _manager: android.support.v4.app.FragmentManager;
|
||||||
|
|
||||||
nativeViewProtected: android.view.View;
|
nativeViewProtected: android.view.View;
|
||||||
|
|
||||||
@ -263,7 +263,7 @@ export class View extends ViewCommon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public _getFragmentManager(): android.app.FragmentManager {
|
public _getFragmentManager(): android.support.v4.app.FragmentManager {
|
||||||
let manager = this._manager;
|
let manager = this._manager;
|
||||||
if (!manager) {
|
if (!manager) {
|
||||||
let view: View = this;
|
let view: View = this;
|
||||||
@ -280,7 +280,7 @@ export class View extends ViewCommon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!manager && this._context) {
|
if (!manager && this._context) {
|
||||||
manager = (<android.app.Activity>this._context).getFragmentManager();
|
manager = (<android.support.v7.app.AppCompatActivity>this._context).getSupportFragmentManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._manager = manager;
|
this._manager = manager;
|
||||||
|
2
tns-core-modules/ui/core/view/view.d.ts
vendored
2
tns-core-modules/ui/core/view/view.d.ts
vendored
@ -659,7 +659,7 @@ export abstract class View extends ViewBase {
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_getFragmentManager(): any; /* android.app.FragmentManager */
|
_getFragmentManager(): any; /* android.support.v4.app.FragmentManager */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates styleScope or create new styleScope.
|
* Updates styleScope or create new styleScope.
|
||||||
|
@ -36,7 +36,7 @@ function dismissSoftInput(owner: EditableTextBase): void {
|
|||||||
if (!dismissKeyboardTimeoutId) {
|
if (!dismissKeyboardTimeoutId) {
|
||||||
dismissKeyboardTimeoutId = setTimeout(() => {
|
dismissKeyboardTimeoutId = setTimeout(() => {
|
||||||
const owner = dismissKeyboardOwner && dismissKeyboardOwner.get();
|
const owner = dismissKeyboardOwner && dismissKeyboardOwner.get();
|
||||||
const activity = (owner && owner._context) as android.app.Activity;
|
const activity = (owner && owner._context) as android.support.v7.app.AppCompatActivity;
|
||||||
const nativeView = owner && owner.nativeViewProtected;
|
const nativeView = owner && owner.nativeViewProtected;
|
||||||
dismissKeyboardTimeoutId = null;
|
dismissKeyboardTimeoutId = null;
|
||||||
dismissKeyboardOwner = null;
|
dismissKeyboardOwner = null;
|
||||||
|
@ -8,7 +8,7 @@ if ((<any>global).__snapshot || (<any>global).__snapshotEnabled) {
|
|||||||
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
@JavaProxy("com.tns.NativeScriptActivity")
|
@JavaProxy("com.tns.NativeScriptActivity")
|
||||||
class NativeScriptActivity extends android.app.Activity {
|
class NativeScriptActivity extends android.support.v7.app.AppCompatActivity {
|
||||||
private _callbacks: AndroidActivityCallbacks;
|
private _callbacks: AndroidActivityCallbacks;
|
||||||
public isNativeScriptActivity;
|
public isNativeScriptActivity;
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -54,7 +54,7 @@ class NativeScriptActivity extends android.app.Activity {
|
|||||||
this._callbacks.onBackPressed(this, super.onBackPressed);
|
this._callbacks.onBackPressed(this, super.onBackPressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onRequestPermissionsResult(requestCode: number, permissions: Array<String>, grantResults: Array<number>): void {
|
public onRequestPermissionsResult(requestCode: number, permissions: Array<string>, grantResults: Array<number>): void {
|
||||||
this._callbacks.onRequestPermissionsResult(this, requestCode, permissions, grantResults, undefined /*TODO: Enable if needed*/);
|
this._callbacks.onRequestPermissionsResult(this, requestCode, permissions, grantResults, undefined /*TODO: Enable if needed*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { AndroidFragmentCallbacks, setFragmentCallbacks, setFragmentClass } from "./frame";
|
import { AndroidFragmentCallbacks, setFragmentCallbacks, setFragmentClass } from "./frame";
|
||||||
|
|
||||||
@JavaProxy("com.tns.FragmentClass")
|
@JavaProxy("com.tns.FragmentClass")
|
||||||
class FragmentClass extends android.app.Fragment {
|
class FragmentClass extends android.support.v4.app.Fragment {
|
||||||
// This field is updated in the frame module upon `new` (although hacky this eases the Fragment->callbacks association a lot)
|
// This field is updated in the frame module upon `new` (although hacky this eases the Fragment->callbacks association a lot)
|
||||||
private _callbacks: AndroidFragmentCallbacks;
|
private _callbacks: AndroidFragmentCallbacks;
|
||||||
|
|
||||||
@ -14,9 +14,8 @@ class FragmentClass extends android.app.Fragment {
|
|||||||
this._callbacks.onHiddenChanged(this, hidden, super.onHiddenChanged);
|
this._callbacks.onHiddenChanged(this, hidden, super.onHiddenChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onCreateAnimator(transit: number, enter: boolean, nextAnim: number): android.animation.Animator {
|
public onCreateAnimation(transit: number, enter: boolean, nextAnim: number): android.view.animation.Animation {
|
||||||
let result = this._callbacks.onCreateAnimator(this, transit, enter, nextAnim, super.onCreateAnimator);
|
return this._callbacks.onCreateAnimation(this, transit, enter, nextAnim, super.onCreateAnimation);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public onStop(): void {
|
public onStop(): void {
|
||||||
|
@ -19,7 +19,7 @@ interface TransitionListener {
|
|||||||
new(entry: ExpandedEntry, transition: android.transition.Transition): ExpandedTransitionListener;
|
new(entry: ExpandedEntry, transition: android.transition.Transition): ExpandedTransitionListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ExpandedAnimator extends android.animation.Animator {
|
interface ExpandedAnimation extends android.view.animation.Animation {
|
||||||
entry: ExpandedEntry;
|
entry: ExpandedEntry;
|
||||||
transitionType?: string;
|
transitionType?: string;
|
||||||
}
|
}
|
||||||
@ -35,13 +35,13 @@ interface ExpandedEntry extends BackstackEntry {
|
|||||||
reenterTransitionListener: ExpandedTransitionListener;
|
reenterTransitionListener: ExpandedTransitionListener;
|
||||||
returnTransitionListener: ExpandedTransitionListener;
|
returnTransitionListener: ExpandedTransitionListener;
|
||||||
|
|
||||||
enterAnimator: ExpandedAnimator;
|
enterAnimation: ExpandedAnimation;
|
||||||
exitAnimator: ExpandedAnimator;
|
exitAnimation: ExpandedAnimation;
|
||||||
popEnterAnimator: ExpandedAnimator;
|
popEnterAnimation: ExpandedAnimation;
|
||||||
popExitAnimator: ExpandedAnimator;
|
popExitAnimation: ExpandedAnimation;
|
||||||
|
|
||||||
defaultEnterAnimator: ExpandedAnimator;
|
defaultEnterAnimation: ExpandedAnimation;
|
||||||
defaultExitAnimator: ExpandedAnimator;
|
defaultExitAnimation: ExpandedAnimation;
|
||||||
|
|
||||||
transition: Transition;
|
transition: Transition;
|
||||||
transitionName: string;
|
transitionName: string;
|
||||||
@ -49,7 +49,6 @@ interface ExpandedEntry extends BackstackEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sdkVersion = lazy(() => parseInt(device.sdkVersion));
|
const sdkVersion = lazy(() => parseInt(device.sdkVersion));
|
||||||
const intEvaluator = lazy(() => new android.animation.IntEvaluator());
|
|
||||||
const defaultInterpolator = lazy(() => new android.view.animation.AccelerateDecelerateInterpolator());
|
const defaultInterpolator = lazy(() => new android.view.animation.AccelerateDecelerateInterpolator());
|
||||||
const isAndroidP = lazy(() => sdkVersion() > 27);
|
const isAndroidP = lazy(() => sdkVersion() > 27);
|
||||||
|
|
||||||
@ -57,23 +56,23 @@ export const waitingQueue = new Map<number, Set<ExpandedEntry>>();
|
|||||||
export const completedEntries = new Map<number, ExpandedEntry>();
|
export const completedEntries = new Map<number, ExpandedEntry>();
|
||||||
|
|
||||||
let TransitionListener: TransitionListener;
|
let TransitionListener: TransitionListener;
|
||||||
let AnimationListener: android.animation.Animator.AnimatorListener;
|
let AnimationListener: android.view.animation.Animation.AnimationListener;
|
||||||
let loadAnimatorMethod: java.lang.reflect.Method;
|
let loadAnimationMethod: java.lang.reflect.Method;
|
||||||
let reflectionDone: boolean;
|
let reflectionDone: boolean;
|
||||||
let defaultEnterAnimatorStatic: android.animation.Animator;
|
let defaultEnterAnimationStatic: android.view.animation.Animation;
|
||||||
let defaultExitAnimatorStatic: android.animation.Animator;
|
let defaultExitAnimationStatic: android.view.animation.Animation;
|
||||||
|
|
||||||
export function _setAndroidFragmentTransitions(
|
export function _setAndroidFragmentTransitions(
|
||||||
animated: boolean,
|
animated: boolean,
|
||||||
navigationTransition: NavigationTransition,
|
navigationTransition: NavigationTransition,
|
||||||
currentEntry: ExpandedEntry,
|
currentEntry: ExpandedEntry,
|
||||||
newEntry: ExpandedEntry,
|
newEntry: ExpandedEntry,
|
||||||
fragmentTransaction: android.app.FragmentTransaction,
|
fragmentTransaction: android.support.v4.app.FragmentTransaction,
|
||||||
manager: android.app.FragmentManager,
|
manager: android.support.v4.app.FragmentManager,
|
||||||
frameId: number): void {
|
frameId: number): void {
|
||||||
|
|
||||||
const currentFragment: android.app.Fragment = currentEntry ? currentEntry.fragment : null;
|
const currentFragment: android.support.v4.app.Fragment = currentEntry ? currentEntry.fragment : null;
|
||||||
const newFragment: android.app.Fragment = newEntry.fragment;
|
const newFragment: android.support.v4.app.Fragment = newEntry.fragment;
|
||||||
const entries = waitingQueue.get(frameId);
|
const entries = waitingQueue.get(frameId);
|
||||||
if (entries && entries.size > 0) {
|
if (entries && entries.size > 0) {
|
||||||
throw new Error("Calling navigation before previous navigation finish.");
|
throw new Error("Calling navigation before previous navigation finish.");
|
||||||
@ -189,39 +188,39 @@ export function _setAndroidFragmentTransitions(
|
|||||||
printTransitions(newEntry);
|
printTransitions(newEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _onFragmentCreateAnimator(entry: ExpandedEntry, fragment: android.app.Fragment, nextAnim: number, enter: boolean): android.animation.Animator {
|
export function _onFragmentCreateAnimation(entry: ExpandedEntry, fragment: android.support.v4.app.Fragment, nextAnim: number, enter: boolean): android.view.animation.Animation {
|
||||||
let animator: android.animation.Animator;
|
let animation: android.view.animation.Animation;
|
||||||
switch (nextAnim) {
|
switch (nextAnim) {
|
||||||
case AnimationType.enterFakeResourceId:
|
case AnimationType.enterFakeResourceId:
|
||||||
animator = entry.enterAnimator;
|
animation = entry.enterAnimation;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AnimationType.exitFakeResourceId:
|
case AnimationType.exitFakeResourceId:
|
||||||
animator = entry.exitAnimator;
|
animation = entry.exitAnimation;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AnimationType.popEnterFakeResourceId:
|
case AnimationType.popEnterFakeResourceId:
|
||||||
animator = entry.popEnterAnimator;
|
animation = entry.popEnterAnimation;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AnimationType.popExitFakeResourceId:
|
case AnimationType.popExitFakeResourceId:
|
||||||
animator = entry.popExitAnimator;
|
animation = entry.popExitAnimation;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!animator && sdkVersion() >= 21) {
|
if (!animation && sdkVersion() >= 21) {
|
||||||
const view = fragment.getView();
|
const view = fragment.getView();
|
||||||
const jsParent = entry.resolvedPage.parent;
|
const jsParent = entry.resolvedPage.parent;
|
||||||
const parent = view.getParent() || (jsParent && jsParent.nativeViewProtected);
|
const parent = view.getParent() || (jsParent && jsParent.nativeViewProtected);
|
||||||
const animatedEntries = _getAnimatedEntries(entry.frameId);
|
const animatedEntries = _getAnimatedEntries(entry.frameId);
|
||||||
if (!animatedEntries || !animatedEntries.has(entry)) {
|
if (!animatedEntries || !animatedEntries.has(entry)) {
|
||||||
if (parent && !(<any>parent).isLaidOut()) {
|
if (parent && !(<any>parent).isLaidOut()) {
|
||||||
animator = enter ? entry.defaultEnterAnimator : entry.defaultExitAnimator;
|
animation = enter ? entry.defaultEnterAnimation : entry.defaultExitAnimation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return animator;
|
return animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _getAnimatedEntries(frameId: number): Set<BackstackEntry> {
|
export function _getAnimatedEntries(frameId: number): Set<BackstackEntry> {
|
||||||
@ -331,45 +330,45 @@ function getTransitionListener(entry: ExpandedEntry, transition: android.transit
|
|||||||
return new TransitionListener(entry, transition);
|
return new TransitionListener(entry, transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAnimationListener(): android.animation.Animator.AnimatorListener {
|
function getAnimationListener(): android.view.animation.Animation.AnimationListener {
|
||||||
if (!AnimationListener) {
|
if (!AnimationListener) {
|
||||||
@Interfaces([android.animation.Animator.AnimatorListener])
|
@Interfaces([android.view.animation.Animation.AnimationListener])
|
||||||
class AnimationListnerImpl extends java.lang.Object implements android.animation.Animator.AnimatorListener {
|
class AnimationListenerImpl extends java.lang.Object implements android.view.animation.Animation.AnimationListener {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
return global.__native(this);
|
return global.__native(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAnimationStart(animator: ExpandedAnimator): void {
|
onAnimationStart(animation: ExpandedAnimation): void {
|
||||||
const entry = animator.entry;
|
const entry = animation.entry;
|
||||||
addToWaitingQueue(entry);
|
addToWaitingQueue(entry);
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`START ${animator.transitionType} for ${entry.fragmentTag}`, traceCategories.Transition);
|
traceWrite(`START ${animation.transitionType} for ${entry.fragmentTag}`, traceCategories.Transition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onAnimationRepeat(animator: ExpandedAnimator): void {
|
onAnimationRepeat(animation: ExpandedAnimation): void {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`REPEAT ${animator.transitionType} for ${animator.entry.fragmentTag}`, traceCategories.Transition);
|
traceWrite(`REPEAT ${animation.transitionType} for ${animation.entry.fragmentTag}`, traceCategories.Transition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onAnimationEnd(animator: ExpandedAnimator): void {
|
onAnimationEnd(animation: ExpandedAnimation): void {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`END ${animator.transitionType} for ${animator.entry.fragmentTag}`, traceCategories.Transition);
|
traceWrite(`END ${animation.transitionType} for ${animation.entry.fragmentTag}`, traceCategories.Transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
transitionOrAnimationCompleted(animator.entry);
|
transitionOrAnimationCompleted(animation.entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAnimationCancel(animator: ExpandedAnimator): void {
|
onAnimationCancel(animation: ExpandedAnimation): void {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`CANCEL ${animator.transitionType} for ${animator.entry.fragmentTag}`, traceCategories.Transition);
|
traceWrite(`CANCEL ${animation.transitionType} for ${animation.entry.fragmentTag}`, traceCategories.Transition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationListener = new AnimationListnerImpl();
|
AnimationListener = new AnimationListenerImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
return AnimationListener;
|
return AnimationListener;
|
||||||
@ -386,24 +385,23 @@ function addToWaitingQueue(entry: ExpandedEntry): void {
|
|||||||
entries.add(entry);
|
entries.add(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearAnimationListener(animator: ExpandedAnimator, listener: android.animation.Animator.AnimatorListener): void {
|
function clearAnimationListener(animation: ExpandedAnimation): void {
|
||||||
if (!animator) {
|
if (!animation) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
animator.removeListener(listener);
|
|
||||||
|
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
const entry = animator.entry;
|
const entry = animation.entry;
|
||||||
traceWrite(`Clear ${animator.transitionType} - ${entry.transition} for ${entry.fragmentTag}`, traceCategories.Transition);
|
traceWrite(`Clear ${animation.transitionType} - ${entry.transition} for ${entry.fragmentTag}`, traceCategories.Transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
animator.entry = null;
|
animation.setAnimationListener(null);
|
||||||
|
animation.entry = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearExitAndReenterTransitions(entry: ExpandedEntry, removeListener: boolean): void {
|
function clearExitAndReenterTransitions(entry: ExpandedEntry, removeListener: boolean): void {
|
||||||
if (sdkVersion() >= 21) {
|
if (sdkVersion() >= 21) {
|
||||||
const fragment: android.app.Fragment = entry.fragment;
|
const fragment: android.support.v4.app.Fragment = entry.fragment;
|
||||||
const exitListener = entry.exitTransitionListener;
|
const exitListener = entry.exitTransitionListener;
|
||||||
if (exitListener) {
|
if (exitListener) {
|
||||||
const exitTransition = fragment.getExitTransition();
|
const exitTransition = fragment.getExitTransition();
|
||||||
@ -456,7 +454,7 @@ function clearEntry(entry: ExpandedEntry, removeListener: boolean): void {
|
|||||||
clearExitAndReenterTransitions(entry, removeListener);
|
clearExitAndReenterTransitions(entry, removeListener);
|
||||||
|
|
||||||
if (sdkVersion() >= 21) {
|
if (sdkVersion() >= 21) {
|
||||||
const fragment: android.app.Fragment = entry.fragment;
|
const fragment: android.support.v4.app.Fragment = entry.fragment;
|
||||||
const enterListener = entry.enterTransitionListener;
|
const enterListener = entry.enterTransitionListener;
|
||||||
if (enterListener) {
|
if (enterListener) {
|
||||||
const enterTransition = fragment.getEnterTransition();
|
const enterTransition = fragment.getEnterTransition();
|
||||||
@ -497,15 +495,14 @@ function clearEntry(entry: ExpandedEntry, removeListener: boolean): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (removeListener) {
|
if (removeListener) {
|
||||||
const listener = getAnimationListener();
|
clearAnimationListener(entry.enterAnimation);
|
||||||
clearAnimationListener(entry.enterAnimator, listener);
|
clearAnimationListener(entry.exitAnimation);
|
||||||
clearAnimationListener(entry.exitAnimator, listener);
|
clearAnimationListener(entry.popEnterAnimation);
|
||||||
clearAnimationListener(entry.popEnterAnimator, listener);
|
clearAnimationListener(entry.popExitAnimation);
|
||||||
clearAnimationListener(entry.popExitAnimator, listener);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function allowTransitionOverlap(fragment: android.app.Fragment): void {
|
function allowTransitionOverlap(fragment: android.support.v4.app.Fragment): void {
|
||||||
if (fragment) {
|
if (fragment) {
|
||||||
fragment.setAllowEnterTransitionOverlap(true);
|
fragment.setAllowEnterTransitionOverlap(true);
|
||||||
fragment.setAllowReturnTransitionOverlap(true);
|
fragment.setAllowReturnTransitionOverlap(true);
|
||||||
@ -518,7 +515,7 @@ function setEnterTransition(navigationTransition: NavigationTransition, entry: E
|
|||||||
|
|
||||||
// attach listener to JS object so that it will be alive as long as entry.
|
// attach listener to JS object so that it will be alive as long as entry.
|
||||||
entry.enterTransitionListener = listener;
|
entry.enterTransitionListener = listener;
|
||||||
const fragment: android.app.Fragment = entry.fragment;
|
const fragment: android.support.v4.app.Fragment = entry.fragment;
|
||||||
fragment.setEnterTransition(transition);
|
fragment.setEnterTransition(transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,7 +525,7 @@ function setExitTransition(navigationTransition: NavigationTransition, entry: Ex
|
|||||||
|
|
||||||
// attach listener to JS object so that it will be alive as long as entry.
|
// attach listener to JS object so that it will be alive as long as entry.
|
||||||
entry.exitTransitionListener = listener;
|
entry.exitTransitionListener = listener;
|
||||||
const fragment: android.app.Fragment = entry.fragment;
|
const fragment: android.support.v4.app.Fragment = entry.fragment;
|
||||||
fragment.setExitTransition(transition);
|
fragment.setExitTransition(transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -538,7 +535,7 @@ function setReenterTransition(navigationTransition: NavigationTransition, entry:
|
|||||||
|
|
||||||
// attach listener to JS object so that it will be alive as long as entry.
|
// attach listener to JS object so that it will be alive as long as entry.
|
||||||
entry.reenterTransitionListener = listener;
|
entry.reenterTransitionListener = listener;
|
||||||
const fragment: android.app.Fragment = entry.fragment;
|
const fragment: android.support.v4.app.Fragment = entry.fragment;
|
||||||
fragment.setReenterTransition(transition);
|
fragment.setReenterTransition(transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,7 +545,7 @@ function setReturnTransition(navigationTransition: NavigationTransition, entry:
|
|||||||
|
|
||||||
// attach listener to JS object so that it will be alive as long as entry.
|
// attach listener to JS object so that it will be alive as long as entry.
|
||||||
entry.returnTransitionListener = listener;
|
entry.returnTransitionListener = listener;
|
||||||
const fragment: android.app.Fragment = entry.fragment;
|
const fragment: android.support.v4.app.Fragment = entry.fragment;
|
||||||
fragment.setReturnTransition(transition);
|
fragment.setReturnTransition(transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,21 +635,21 @@ function setupNewFragmentExplodeTransition(navTransition: NavigationTransition,
|
|||||||
function setupExitAndPopEnterAnimation(entry: ExpandedEntry, transition: Transition): void {
|
function setupExitAndPopEnterAnimation(entry: ExpandedEntry, transition: Transition): void {
|
||||||
const listener = getAnimationListener();
|
const listener = getAnimationListener();
|
||||||
|
|
||||||
// remove previous listener if we are changing the animator.
|
// remove previous listener if we are changing the animation.
|
||||||
clearAnimationListener(entry.exitAnimator, listener);
|
clearAnimationListener(entry.exitAnimation);
|
||||||
clearAnimationListener(entry.popEnterAnimator, listener);
|
clearAnimationListener(entry.popEnterAnimation);
|
||||||
|
|
||||||
const exitAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.exit);
|
const exitAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.exit);
|
||||||
exitAnimator.transitionType = AndroidTransitionType.exit;
|
exitAnimation.transitionType = AndroidTransitionType.exit;
|
||||||
exitAnimator.entry = entry;
|
exitAnimation.entry = entry;
|
||||||
exitAnimator.addListener(listener);
|
exitAnimation.setAnimationListener(listener);
|
||||||
entry.exitAnimator = exitAnimator;
|
entry.exitAnimation = exitAnimation;
|
||||||
|
|
||||||
const popEnterAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.popEnter);
|
const popEnterAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.popEnter);
|
||||||
popEnterAnimator.transitionType = AndroidTransitionType.popEnter;
|
popEnterAnimation.transitionType = AndroidTransitionType.popEnter;
|
||||||
popEnterAnimator.entry = entry;
|
popEnterAnimation.entry = entry;
|
||||||
popEnterAnimator.addListener(listener);
|
popEnterAnimation.setAnimationListener(listener);
|
||||||
entry.popEnterAnimator = popEnterAnimator;
|
entry.popEnterAnimation = popEnterAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupAllAnimation(entry: ExpandedEntry, transition: Transition): void {
|
function setupAllAnimation(entry: ExpandedEntry, transition: Transition): void {
|
||||||
@ -661,33 +658,33 @@ function setupAllAnimation(entry: ExpandedEntry, transition: Transition): void {
|
|||||||
|
|
||||||
// setupAllAnimation is called only for new fragments so we don't
|
// setupAllAnimation is called only for new fragments so we don't
|
||||||
// need to clearAnimationListener for enter & popExit animators.
|
// need to clearAnimationListener for enter & popExit animators.
|
||||||
const enterAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.enter);
|
const enterAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.enter);
|
||||||
enterAnimator.transitionType = AndroidTransitionType.enter;
|
enterAnimation.transitionType = AndroidTransitionType.enter;
|
||||||
enterAnimator.entry = entry;
|
enterAnimation.entry = entry;
|
||||||
enterAnimator.addListener(listener);
|
enterAnimation.setAnimationListener(listener);
|
||||||
entry.enterAnimator = enterAnimator;
|
entry.enterAnimation = enterAnimation;
|
||||||
|
|
||||||
const popExitAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.popExit);
|
const popExitAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.popExit);
|
||||||
popExitAnimator.transitionType = AndroidTransitionType.popExit;
|
popExitAnimation.transitionType = AndroidTransitionType.popExit;
|
||||||
popExitAnimator.entry = entry;
|
popExitAnimation.entry = entry;
|
||||||
popExitAnimator.addListener(listener);
|
popExitAnimation.setAnimationListener(listener);
|
||||||
entry.popExitAnimator = popExitAnimator;
|
entry.popExitAnimation = popExitAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupDefaultAnimations(entry: ExpandedEntry, transition: Transition): void {
|
function setupDefaultAnimations(entry: ExpandedEntry, transition: Transition): void {
|
||||||
const listener = getAnimationListener();
|
const listener = getAnimationListener();
|
||||||
|
|
||||||
const enterAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.enter);
|
const enterAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.enter);
|
||||||
enterAnimator.transitionType = AndroidTransitionType.enter;
|
enterAnimation.transitionType = AndroidTransitionType.enter;
|
||||||
enterAnimator.entry = entry;
|
enterAnimation.entry = entry;
|
||||||
enterAnimator.addListener(listener);
|
enterAnimation.setAnimationListener(listener);
|
||||||
entry.defaultEnterAnimator = enterAnimator;
|
entry.defaultEnterAnimation = enterAnimation;
|
||||||
|
|
||||||
const exitAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.exit);
|
const exitAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.exit);
|
||||||
exitAnimator.transitionType = AndroidTransitionType.exit;
|
exitAnimation.transitionType = AndroidTransitionType.exit;
|
||||||
exitAnimator.entry = entry;
|
exitAnimation.entry = entry;
|
||||||
exitAnimator.addListener(listener);
|
exitAnimation.setAnimationListener(listener);
|
||||||
entry.defaultExitAnimator = exitAnimator;
|
entry.defaultExitAnimation = exitAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setUpNativeTransition(navigationTransition: NavigationTransition, nativeTransition: android.transition.Transition) {
|
function setUpNativeTransition(navigationTransition: NavigationTransition, nativeTransition: android.transition.Transition) {
|
||||||
@ -754,38 +751,41 @@ function javaClassArray(...params: java.lang.Class<any>[]) {
|
|||||||
return nativeArray;
|
return nativeArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
function initDefaultAnimations(manager: android.app.FragmentManager): void {
|
function initDefaultAnimations(manager: android.support.v4.app.FragmentManager): void {
|
||||||
if (reflectionDone) {
|
if (reflectionDone) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reflectionDone = true;
|
reflectionDone = true;
|
||||||
|
|
||||||
loadAnimatorMethod = manager.getClass().getDeclaredMethod("loadAnimator", javaClassArray(android.app.Fragment.class, java.lang.Integer.TYPE, java.lang.Boolean.TYPE, java.lang.Integer.TYPE));
|
loadAnimationMethod = manager.getClass().getDeclaredMethod("loadAnimation", javaClassArray(android.support.v4.app.Fragment.class, java.lang.Integer.TYPE, java.lang.Boolean.TYPE, java.lang.Integer.TYPE));
|
||||||
if (loadAnimatorMethod != null) {
|
if (loadAnimationMethod != null) {
|
||||||
loadAnimatorMethod.setAccessible(true);
|
loadAnimationMethod.setAccessible(true);
|
||||||
|
|
||||||
const fragment_open = java.lang.Integer.valueOf(android.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
|
const fragment_open = java.lang.Integer.valueOf(android.support.v4.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
|
||||||
const zero = java.lang.Integer.valueOf(0);
|
const zero = java.lang.Integer.valueOf(0);
|
||||||
const fragment = new android.app.Fragment();
|
const fragment = new android.support.v4.app.Fragment();
|
||||||
|
|
||||||
// Get default enter transition.
|
// Get default enter transition.
|
||||||
defaultEnterAnimatorStatic = loadAnimatorMethod.invoke(manager, javaObjectArray(fragment, fragment_open, java.lang.Boolean.TRUE, zero));
|
defaultEnterAnimationStatic = loadAnimationMethod.invoke(manager, javaObjectArray(fragment, fragment_open, java.lang.Boolean.TRUE, zero));
|
||||||
|
|
||||||
// Get default exit transition.
|
// Get default exit transition.
|
||||||
defaultExitAnimatorStatic = loadAnimatorMethod.invoke(manager, javaObjectArray(fragment, fragment_open, java.lang.Boolean.FALSE, zero));
|
defaultExitAnimationStatic = loadAnimationMethod.invoke(manager, javaObjectArray(fragment, fragment_open, java.lang.Boolean.FALSE, zero));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultAnimation(enter: boolean): android.animation.Animator {
|
function getDefaultAnimation(enter: boolean): android.view.animation.Animation {
|
||||||
const defaultAnimator = enter ? defaultEnterAnimatorStatic : defaultExitAnimatorStatic;
|
const defaultAnimation = enter ? defaultEnterAnimationStatic : defaultExitAnimationStatic;
|
||||||
return defaultAnimator ? defaultAnimator.clone() : null;
|
return defaultAnimation ? defaultAnimation.clone() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDummyZeroDurationAnimator(): android.animation.Animator {
|
function createDummyZeroDurationAnimation(): android.view.animation.Animation {
|
||||||
const animator = android.animation.ValueAnimator.ofObject(intEvaluator(), javaObjectArray(java.lang.Integer.valueOf(0), java.lang.Integer.valueOf(1)));
|
// NOTE: returning the dummy AlphaAnimation directly does not work for some reason;
|
||||||
animator.setDuration(0);
|
// animationEnd is fired first, then some animationStart (but for a different animation?)
|
||||||
return animator;
|
const animationSet = new android.view.animation.AnimationSet(false);
|
||||||
|
animationSet.addAnimation(new android.view.animation.AlphaAnimation(1, 1));
|
||||||
|
|
||||||
|
return animationSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
function printTransitions(entry: ExpandedEntry) {
|
function printTransitions(entry: ExpandedEntry) {
|
||||||
@ -796,10 +796,10 @@ function printTransitions(entry: ExpandedEntry) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (entry.transition) {
|
if (entry.transition) {
|
||||||
result += `enterAnimator=${entry.enterAnimator}, `;
|
result += `enterAnimator=${entry.enterAnimation}, `;
|
||||||
result += `exitAnimator=${entry.exitAnimator}, `;
|
result += `exitAnimator=${entry.exitAnimation}, `;
|
||||||
result += `popEnterAnimator=${entry.popEnterAnimator}, `;
|
result += `popEnterAnimator=${entry.popEnterAnimation}, `;
|
||||||
result += `popExitAnimator=${entry.popExitAnimator}, `;
|
result += `popExitAnimator=${entry.popExitAnimation}, `;
|
||||||
}
|
}
|
||||||
if (sdkVersion() >= 21) {
|
if (sdkVersion() >= 21) {
|
||||||
const fragment = entry.fragment;
|
const fragment = entry.fragment;
|
||||||
@ -813,13 +813,13 @@ function printTransitions(entry: ExpandedEntry) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class NoTransition extends Transition {
|
class NoTransition extends Transition {
|
||||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||||
return createDummyZeroDurationAnimator();
|
return createDummyZeroDurationAnimation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultTransition extends Transition {
|
class DefaultTransition extends Transition {
|
||||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||||
switch (transitionType) {
|
switch (transitionType) {
|
||||||
case AndroidTransitionType.enter:
|
case AndroidTransitionType.enter:
|
||||||
case AndroidTransitionType.popEnter:
|
case AndroidTransitionType.popEnter:
|
||||||
|
@ -24,12 +24,12 @@ export function _setAndroidFragmentTransitions(
|
|||||||
currentEntry: BackstackEntry,
|
currentEntry: BackstackEntry,
|
||||||
newEntry: BackstackEntry,
|
newEntry: BackstackEntry,
|
||||||
fragmentTransaction: any,
|
fragmentTransaction: any,
|
||||||
manager: any /* android.app.FragmentManager */,
|
manager: any /* android.support.v4.app.FragmentManager */,
|
||||||
frameId: number): void;
|
frameId: number): void;
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
export function _onFragmentCreateAnimator(entry: BackstackEntry, fragment: any, nextAnim: number, enter: boolean): any;
|
export function _onFragmentCreateAnimation(entry: BackstackEntry, fragment: any, nextAnim: number, enter: boolean): any;
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
} from "./frame-common";
|
} from "./frame-common";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
_setAndroidFragmentTransitions, _onFragmentCreateAnimator, _getAnimatedEntries,
|
_setAndroidFragmentTransitions, _onFragmentCreateAnimation, _getAnimatedEntries,
|
||||||
_updateTransitions, _reverseTransitions, _clearEntry, _clearFragment, AnimationType
|
_updateTransitions, _reverseTransitions, _clearEntry, _clearFragment, AnimationType
|
||||||
} from "./fragment.transitions";
|
} from "./fragment.transitions";
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ export class Frame extends FrameBase {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const manager: android.app.FragmentManager = this._getFragmentManager();
|
const manager: android.support.v4.app.FragmentManager = this._getFragmentManager();
|
||||||
const transaction = manager.beginTransaction();
|
const transaction = manager.beginTransaction();
|
||||||
const androidSdkVersion = sdkVersion();
|
const androidSdkVersion = sdkVersion();
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ export class Frame extends FrameBase {
|
|||||||
transaction.commitAllowingStateLoss();
|
transaction.commitAllowingStateLoss();
|
||||||
}
|
}
|
||||||
|
|
||||||
private createFragment(backstackEntry: BackstackEntry, fragmentTag: string): android.app.Fragment {
|
private createFragment(backstackEntry: BackstackEntry, fragmentTag: string): android.support.v4.app.Fragment {
|
||||||
ensureFragmentClass();
|
ensureFragmentClass();
|
||||||
const newFragment = new fragmentClass();
|
const newFragment = new fragmentClass();
|
||||||
const args = new android.os.Bundle();
|
const args = new android.os.Bundle();
|
||||||
@ -316,7 +316,7 @@ export class Frame extends FrameBase {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const manager: android.app.FragmentManager = this._getFragmentManager();
|
const manager: android.support.v4.app.FragmentManager = this._getFragmentManager();
|
||||||
const clearHistory = newEntry.entry.clearHistory;
|
const clearHistory = newEntry.entry.clearHistory;
|
||||||
const currentEntry = this._currentEntry;
|
const currentEntry = this._currentEntry;
|
||||||
|
|
||||||
@ -343,7 +343,7 @@ export class Frame extends FrameBase {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
if (currentEntry && animated && !navigationTransition) {
|
if (currentEntry && animated && !navigationTransition) {
|
||||||
transaction.setTransition(android.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
|
transaction.setTransition(android.support.v4.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction.replace(this.containerViewId, newFragment, newFragmentTag);
|
transaction.replace(this.containerViewId, newFragment, newFragmentTag);
|
||||||
@ -355,7 +355,7 @@ export class Frame extends FrameBase {
|
|||||||
super._goBackCore(backstackEntry);
|
super._goBackCore(backstackEntry);
|
||||||
navDepth = backstackEntry.navDepth;
|
navDepth = backstackEntry.navDepth;
|
||||||
|
|
||||||
const manager: android.app.FragmentManager = this._getFragmentManager();
|
const manager: android.support.v4.app.FragmentManager = this._getFragmentManager();
|
||||||
const transaction = manager.beginTransaction();
|
const transaction = manager.beginTransaction();
|
||||||
|
|
||||||
if (!backstackEntry.fragment) {
|
if (!backstackEntry.fragment) {
|
||||||
@ -509,8 +509,8 @@ class AndroidFrame extends Observable implements AndroidFrameDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public get activity(): android.app.Activity {
|
public get activity(): android.support.v7.app.AppCompatActivity {
|
||||||
let activity: android.app.Activity = this.owner._context;
|
let activity: android.support.v7.app.AppCompatActivity = this.owner._context;
|
||||||
if (activity) {
|
if (activity) {
|
||||||
return activity;
|
return activity;
|
||||||
}
|
}
|
||||||
@ -542,7 +542,7 @@ class AndroidFrame extends Observable implements AndroidFrameDefinition {
|
|||||||
return bar;
|
return bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get currentActivity(): android.app.Activity {
|
public get currentActivity(): android.support.v7.app.AppCompatActivity {
|
||||||
let activity = this.activity;
|
let activity = this.activity;
|
||||||
if (activity) {
|
if (activity) {
|
||||||
return activity;
|
return activity;
|
||||||
@ -582,7 +582,7 @@ class AndroidFrame extends Observable implements AndroidFrameDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function findPageForFragment(fragment: android.app.Fragment, frame: Frame) {
|
function findPageForFragment(fragment: android.support.v4.app.Fragment, frame: Frame) {
|
||||||
const fragmentTag = fragment.getTag();
|
const fragmentTag = fragment.getTag();
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`Finding page for ${fragmentTag}.`, traceCategories.NativeLifecycle);
|
traceWrite(`Finding page for ${fragmentTag}.`, traceCategories.NativeLifecycle);
|
||||||
@ -615,7 +615,7 @@ function findPageForFragment(fragment: android.app.Fragment, frame: Frame) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function startActivity(activity: android.app.Activity, frameId: number) {
|
function startActivity(activity: android.support.v7.app.AppCompatActivity, frameId: number) {
|
||||||
// TODO: Implicitly, we will open the same activity type as the current one
|
// TODO: Implicitly, we will open the same activity type as the current one
|
||||||
const intent = new android.content.Intent(activity, activity.getClass());
|
const intent = new android.content.Intent(activity, activity.getClass());
|
||||||
intent.setAction(android.content.Intent.ACTION_DEFAULT);
|
intent.setAction(android.content.Intent.ACTION_DEFAULT);
|
||||||
@ -646,7 +646,7 @@ function ensureFragmentClass() {
|
|||||||
require("ui/frame/fragment");
|
require("ui/frame/fragment");
|
||||||
|
|
||||||
if (!fragmentClass) {
|
if (!fragmentClass) {
|
||||||
throw new Error("Failed to initialize the extended android.app.Fragment class");
|
throw new Error("Failed to initialize the extended android.support.v4.app.Fragment class");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -664,7 +664,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
|||||||
public entry: BackstackEntry;
|
public entry: BackstackEntry;
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public onHiddenChanged(fragment: android.app.Fragment, hidden: boolean, superFunc: Function): void {
|
public onHiddenChanged(fragment: android.support.v4.app.Fragment, hidden: boolean, superFunc: Function): void {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`${fragment}.onHiddenChanged(${hidden})`, traceCategories.NativeLifecycle);
|
traceWrite(`${fragment}.onHiddenChanged(${hidden})`, traceCategories.NativeLifecycle);
|
||||||
}
|
}
|
||||||
@ -672,28 +672,29 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public onCreateAnimator(fragment: android.app.Fragment, transit: number, enter: boolean, nextAnim: number, superFunc: Function): android.animation.Animator {
|
public onCreateAnimation(fragment: android.support.v4.app.Fragment, transit: number, enter: boolean, nextAnim: number, superFunc: Function): android.view.animation.Animation {
|
||||||
let nextAnimString: string;
|
let nextAnimString: string;
|
||||||
switch (nextAnim) {
|
switch (nextAnim) {
|
||||||
case -10: nextAnimString = "enter"; break;
|
case AnimationType.enterFakeResourceId: nextAnimString = "enter"; break;
|
||||||
case -20: nextAnimString = "exit"; break;
|
case AnimationType.exitFakeResourceId: nextAnimString = "exit"; break;
|
||||||
case -30: nextAnimString = "popEnter"; break;
|
case AnimationType.popEnterFakeResourceId: nextAnimString = "popEnter"; break;
|
||||||
case -40: nextAnimString = "popExit"; break;
|
case AnimationType.popExitFakeResourceId: nextAnimString = "popExit"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let animator = _onFragmentCreateAnimator(this.entry, fragment, nextAnim, enter);
|
let animation = _onFragmentCreateAnimation(this.entry, fragment, nextAnim, enter);
|
||||||
if (!animator) {
|
if (!animation) {
|
||||||
animator = superFunc.call(fragment, transit, enter, nextAnim);
|
animation = superFunc.call(fragment, transit, enter, nextAnim);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`${fragment}.onCreateAnimator(${transit}, ${enter ? "enter" : "exit"}, ${nextAnimString}): ${animator ? "animator" : "no animator"}`, traceCategories.NativeLifecycle);
|
traceWrite(`${fragment}.onCreateAnimation(${transit}, ${enter ? "enter" : "exit"}, ${nextAnimString}): ${animation ? "animation" : "no animation"}`, traceCategories.NativeLifecycle);
|
||||||
}
|
}
|
||||||
return animator;
|
|
||||||
|
return animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public onCreate(fragment: android.app.Fragment, savedInstanceState: android.os.Bundle, superFunc: Function): void {
|
public onCreate(fragment: android.support.v4.app.Fragment, savedInstanceState: android.os.Bundle, superFunc: Function): void {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`${fragment}.onCreate(${savedInstanceState})`, traceCategories.NativeLifecycle);
|
traceWrite(`${fragment}.onCreate(${savedInstanceState})`, traceCategories.NativeLifecycle);
|
||||||
}
|
}
|
||||||
@ -714,7 +715,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public onCreateView(fragment: android.app.Fragment, inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle, superFunc: Function): android.view.View {
|
public onCreateView(fragment: android.support.v4.app.Fragment, inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle, superFunc: Function): android.view.View {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`${fragment}.onCreateView(inflater, container, ${savedInstanceState})`, traceCategories.NativeLifecycle);
|
traceWrite(`${fragment}.onCreateView(inflater, container, ${savedInstanceState})`, traceCategories.NativeLifecycle);
|
||||||
}
|
}
|
||||||
@ -752,7 +753,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public onSaveInstanceState(fragment: android.app.Fragment, outState: android.os.Bundle, superFunc: Function): void {
|
public onSaveInstanceState(fragment: android.support.v4.app.Fragment, outState: android.os.Bundle, superFunc: Function): void {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`${fragment}.onSaveInstanceState(${outState})`, traceCategories.NativeLifecycle);
|
traceWrite(`${fragment}.onSaveInstanceState(${outState})`, traceCategories.NativeLifecycle);
|
||||||
}
|
}
|
||||||
@ -760,7 +761,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public onDestroyView(fragment: android.app.Fragment, superFunc: Function): void {
|
public onDestroyView(fragment: android.support.v4.app.Fragment, superFunc: Function): void {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`${fragment}.onDestroyView()`, traceCategories.NativeLifecycle);
|
traceWrite(`${fragment}.onDestroyView()`, traceCategories.NativeLifecycle);
|
||||||
}
|
}
|
||||||
@ -768,7 +769,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public onDestroy(fragment: android.app.Fragment, superFunc: Function): void {
|
public onDestroy(fragment: android.support.v4.app.Fragment, superFunc: Function): void {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`${fragment}.onDestroy()`, traceCategories.NativeLifecycle);
|
traceWrite(`${fragment}.onDestroy()`, traceCategories.NativeLifecycle);
|
||||||
}
|
}
|
||||||
@ -776,12 +777,12 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public onStop(fragment: android.app.Fragment, superFunc: Function): void {
|
public onStop(fragment: android.support.v4.app.Fragment, superFunc: Function): void {
|
||||||
superFunc.call(fragment);
|
superFunc.call(fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public toStringOverride(fragment: android.app.Fragment, superFunc: Function): string {
|
public toStringOverride(fragment: android.support.v4.app.Fragment, superFunc: Function): string {
|
||||||
const entry = this.entry;
|
const entry = this.entry;
|
||||||
if (entry) {
|
if (entry) {
|
||||||
return `${entry.fragmentTag}<${entry.resolvedPage}>`;
|
return `${entry.fragmentTag}<${entry.resolvedPage}>`;
|
||||||
@ -799,7 +800,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public onCreate(activity: android.app.Activity, savedInstanceState: android.os.Bundle, superFunc: Function): void {
|
public onCreate(activity: android.support.v7.app.AppCompatActivity, savedInstanceState: android.os.Bundle, superFunc: Function): void {
|
||||||
if (traceEnabled()) {
|
if (traceEnabled()) {
|
||||||
traceWrite(`Activity.onCreate(${savedInstanceState})`, traceCategories.NativeLifecycle);
|
traceWrite(`Activity.onCreate(${savedInstanceState})`, traceCategories.NativeLifecycle);
|
||||||
}
|
}
|
||||||
@ -826,7 +827,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public onSaveInstanceState(activity: android.app.Activity, outState: android.os.Bundle, superFunc: Function): void {
|
public onSaveInstanceState(activity: android.support.v7.app.AppCompatActivity, outState: android.os.Bundle, superFunc: Function): void {
|
||||||
superFunc.call(activity, outState);
|
superFunc.call(activity, outState);
|
||||||
const rootView = this._rootView;
|
const rootView = this._rootView;
|
||||||
if (rootView instanceof Frame) {
|
if (rootView instanceof Frame) {
|
||||||
@ -967,7 +968,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public resetActivityContent(activity: android.app.Activity): void {
|
public resetActivityContent(activity: android.support.v7.app.AppCompatActivity): void {
|
||||||
if (this._rootView) {
|
if (this._rootView) {
|
||||||
const manager = this._rootView._getFragmentManager();
|
const manager = this._rootView._getFragmentManager();
|
||||||
manager.executePendingTransactions();
|
manager.executePendingTransactions();
|
||||||
@ -986,7 +987,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
|||||||
// 3. Livesync if rootView has no custom _onLivesync. this._rootView should have been cleared upfront. Launch event should not fired
|
// 3. Livesync if rootView has no custom _onLivesync. this._rootView should have been cleared upfront. Launch event should not fired
|
||||||
// 4. _resetRootView method. this._rootView should have been cleared upfront. Launch event should not fired
|
// 4. _resetRootView method. this._rootView should have been cleared upfront. Launch event should not fired
|
||||||
private setActivityContent(
|
private setActivityContent(
|
||||||
activity: android.app.Activity,
|
activity: android.support.v7.app.AppCompatActivity,
|
||||||
savedInstanceState: android.os.Bundle,
|
savedInstanceState: android.os.Bundle,
|
||||||
fireLaunchEvent: boolean
|
fireLaunchEvent: boolean
|
||||||
): void {
|
): void {
|
||||||
@ -1069,10 +1070,10 @@ const notifyLaunch = profile("notifyLaunch", function notifyLaunch(intent: andro
|
|||||||
return launchArgs.root;
|
return launchArgs.root;
|
||||||
});
|
});
|
||||||
|
|
||||||
export function setActivityCallbacks(activity: android.app.Activity): void {
|
export function setActivityCallbacks(activity: android.support.v7.app.AppCompatActivity): void {
|
||||||
activity[CALLBACKS] = new ActivityCallbacksImplementation();
|
activity[CALLBACKS] = new ActivityCallbacksImplementation();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setFragmentCallbacks(fragment: android.app.Fragment): void {
|
export function setFragmentCallbacks(fragment: android.support.v4.app.Fragment): void {
|
||||||
fragment[CALLBACKS] = new FragmentCallbacksImplementation();
|
fragment[CALLBACKS] = new FragmentCallbacksImplementation();
|
||||||
}
|
}
|
||||||
|
14
tns-core-modules/ui/frame/frame.d.ts
vendored
14
tns-core-modules/ui/frame/frame.d.ts
vendored
@ -174,7 +174,7 @@ export class Frame extends View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the extended android.app.Fragment class to the Frame and navigation routine. An instance of this class will be created to represent the Page currently visible on the srceen. This method is available only for the Android platform.
|
* Sets the extended android.support.v4.app.Fragment class to the Frame and navigation routine. An instance of this class will be created to represent the Page currently visible on the srceen. This method is available only for the Android platform.
|
||||||
*/
|
*/
|
||||||
export function setFragmentClass(clazz: any): void;
|
export function setFragmentClass(clazz: any): void;
|
||||||
|
|
||||||
@ -364,12 +364,12 @@ export interface AndroidFrame extends Observable {
|
|||||||
/**
|
/**
|
||||||
* Gets the native [android Activity](http://developer.android.com/reference/android/app/Activity.html) instance associated with this Frame. In case of nested Frame objects, this property points to the activity of the root Frame.
|
* Gets the native [android Activity](http://developer.android.com/reference/android/app/Activity.html) instance associated with this Frame. In case of nested Frame objects, this property points to the activity of the root Frame.
|
||||||
*/
|
*/
|
||||||
activity: any /* android.app.Activity */;
|
activity: any /* android.support.v7.app.AppCompatActivity */;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current (foreground) activity for the application. This property will recursively traverse all existing Frame objects and check for own Activity property.
|
* Gets the current (foreground) activity for the application. This property will recursively traverse all existing Frame objects and check for own Activity property.
|
||||||
*/
|
*/
|
||||||
currentActivity: any /* android.app.Activity */;
|
currentActivity: any /* android.support.v7.app.AppCompatActivity */;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the actionBar property of the currentActivity.
|
* Gets the actionBar property of the currentActivity.
|
||||||
@ -388,7 +388,7 @@ export interface AndroidFrame extends Observable {
|
|||||||
cachePagesOnNavigate: boolean;
|
cachePagesOnNavigate: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the native android.app.Fragment instance created for the specified Page.
|
* Finds the native android.support.v4.app.Fragment instance created for the specified Page.
|
||||||
* @param page The Page instance to search for.
|
* @param page The Page instance to search for.
|
||||||
*/
|
*/
|
||||||
fragmentForPage(entry: BackstackEntry): any;
|
fragmentForPage(entry: BackstackEntry): any;
|
||||||
@ -410,7 +410,7 @@ export interface AndroidActivityCallbacks {
|
|||||||
|
|
||||||
export interface AndroidFragmentCallbacks {
|
export interface AndroidFragmentCallbacks {
|
||||||
onHiddenChanged(fragment: any, hidden: boolean, superFunc: Function): void;
|
onHiddenChanged(fragment: any, hidden: boolean, superFunc: Function): void;
|
||||||
onCreateAnimator(fragment: any, transit: number, enter: boolean, nextAnim: number, superFunc: Function): any;
|
onCreateAnimation(fragment: any, transit: number, enter: boolean, nextAnim: number, superFunc: Function): any;
|
||||||
onCreate(fragment: any, savedInstanceState: any, superFunc: Function): void;
|
onCreate(fragment: any, savedInstanceState: any, superFunc: Function): void;
|
||||||
onCreateView(fragment: any, inflater: any, container: any, savedInstanceState: any, superFunc: Function): any;
|
onCreateView(fragment: any, inflater: any, container: any, savedInstanceState: any, superFunc: Function): any;
|
||||||
onSaveInstanceState(fragment: any, outState: any, superFunc: Function): void;
|
onSaveInstanceState(fragment: any, outState: any, superFunc: Function): void;
|
||||||
@ -446,7 +446,7 @@ export interface iOSFrame {
|
|||||||
//@endprivate
|
//@endprivate
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setActivityCallbacks(activity: any /*android.app.Activity*/): void;
|
export function setActivityCallbacks(activity: any /*android.support.v7.app.AppCompatActivity*/): void;
|
||||||
//@private
|
//@private
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@ -455,5 +455,5 @@ export function reloadPage(): void;
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
export function setFragmentCallbacks(fragment: any /*android.app.Fragment*/): void;
|
export function setFragmentCallbacks(fragment: any /*android.support.v4.app.Fragment*/): void;
|
||||||
//@endprivate
|
//@endprivate
|
||||||
|
@ -59,7 +59,7 @@ export class Page extends PageBase {
|
|||||||
|
|
||||||
[statusBarStyleProperty.getDefault](): { color: number, systemUiVisibility: number } {
|
[statusBarStyleProperty.getDefault](): { color: number, systemUiVisibility: number } {
|
||||||
if (device.sdkVersion >= "21") {
|
if (device.sdkVersion >= "21") {
|
||||||
const window = (<android.app.Activity>this._context).getWindow();
|
const window = (<android.support.v7.app.AppCompatActivity>this._context).getWindow();
|
||||||
const decorView = window.getDecorView();
|
const decorView = window.getDecorView();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -72,7 +72,7 @@ export class Page extends PageBase {
|
|||||||
}
|
}
|
||||||
[statusBarStyleProperty.setNative](value: "dark" | "light" | { color: number, systemUiVisibility: number }) {
|
[statusBarStyleProperty.setNative](value: "dark" | "light" | { color: number, systemUiVisibility: number }) {
|
||||||
if (device.sdkVersion >= "21") {
|
if (device.sdkVersion >= "21") {
|
||||||
const window = (<android.app.Activity>this._context).getWindow();
|
const window = (<android.support.v7.app.AppCompatActivity>this._context).getWindow();
|
||||||
const decorView = window.getDecorView();
|
const decorView = window.getDecorView();
|
||||||
|
|
||||||
if (value === "light") {
|
if (value === "light") {
|
||||||
@ -91,7 +91,7 @@ export class Page extends PageBase {
|
|||||||
|
|
||||||
[androidStatusBarBackgroundProperty.getDefault](): number {
|
[androidStatusBarBackgroundProperty.getDefault](): number {
|
||||||
if (device.sdkVersion >= "21") {
|
if (device.sdkVersion >= "21") {
|
||||||
const window = (<android.app.Activity>this._context).getWindow();
|
const window = (<android.support.v7.app.AppCompatActivity>this._context).getWindow();
|
||||||
return (<any>window).getStatusBarColor();
|
return (<any>window).getStatusBarColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ export class Page extends PageBase {
|
|||||||
}
|
}
|
||||||
[androidStatusBarBackgroundProperty.setNative](value: number | Color) {
|
[androidStatusBarBackgroundProperty.setNative](value: number | Color) {
|
||||||
if (device.sdkVersion >= "21") {
|
if (device.sdkVersion >= "21") {
|
||||||
const window = (<android.app.Activity>this._context).getWindow();
|
const window = (<android.support.v7.app.AppCompatActivity>this._context).getWindow();
|
||||||
const color = value instanceof Color ? value.android : value;
|
const color = value instanceof Color ? value.android : value;
|
||||||
(<any>window).setStatusBarColor(color);
|
(<any>window).setStatusBarColor(color);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ function initializeNativeClasses() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TabFragmentImplementation extends android.app.Fragment {
|
class TabFragmentImplementation extends android.support.v4.app.Fragment {
|
||||||
private tab: TabView;
|
private tab: TabView;
|
||||||
private index: number;
|
private index: number;
|
||||||
|
|
||||||
@ -90,8 +90,8 @@ function initializeNativeClasses() {
|
|||||||
|
|
||||||
class FragmentPagerAdapter extends android.support.v4.view.PagerAdapter {
|
class FragmentPagerAdapter extends android.support.v4.view.PagerAdapter {
|
||||||
public items: Array<TabViewItemDefinition>;
|
public items: Array<TabViewItemDefinition>;
|
||||||
private mCurTransaction: android.app.FragmentTransaction;
|
private mCurTransaction: android.support.v4.app.FragmentTransaction;
|
||||||
private mCurrentPrimaryItem: android.app.Fragment;
|
private mCurrentPrimaryItem: android.support.v4.app.Fragment;
|
||||||
|
|
||||||
constructor(public owner: TabView) {
|
constructor(public owner: TabView) {
|
||||||
super();
|
super();
|
||||||
@ -127,7 +127,7 @@ function initializeNativeClasses() {
|
|||||||
const itemId = this.getItemId(position);
|
const itemId = this.getItemId(position);
|
||||||
const name = makeFragmentName(container.getId(), itemId);
|
const name = makeFragmentName(container.getId(), itemId);
|
||||||
|
|
||||||
let fragment: android.app.Fragment = fragmentManager.findFragmentByTag(name);
|
let fragment: android.support.v4.app.Fragment = fragmentManager.findFragmentByTag(name);
|
||||||
if (fragment != null) {
|
if (fragment != null) {
|
||||||
this.mCurTransaction.attach(fragment);
|
this.mCurTransaction.attach(fragment);
|
||||||
} else {
|
} else {
|
||||||
@ -159,7 +159,7 @@ function initializeNativeClasses() {
|
|||||||
this.mCurTransaction = fragmentManager.beginTransaction();
|
this.mCurTransaction = fragmentManager.beginTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
const fragment: android.app.Fragment = <android.app.Fragment>object;
|
const fragment: android.support.v4.app.Fragment = <android.support.v4.app.Fragment>object;
|
||||||
this.mCurTransaction.detach(fragment);
|
this.mCurTransaction.detach(fragment);
|
||||||
|
|
||||||
if (this.mCurrentPrimaryItem === fragment) {
|
if (this.mCurrentPrimaryItem === fragment) {
|
||||||
@ -174,7 +174,7 @@ function initializeNativeClasses() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setPrimaryItem(container: android.view.ViewGroup, position: number, object: java.lang.Object): void {
|
setPrimaryItem(container: android.view.ViewGroup, position: number, object: java.lang.Object): void {
|
||||||
const fragment = <android.app.Fragment>object;
|
const fragment = <android.support.v4.app.Fragment>object;
|
||||||
if (fragment !== this.mCurrentPrimaryItem) {
|
if (fragment !== this.mCurrentPrimaryItem) {
|
||||||
if (this.mCurrentPrimaryItem != null) {
|
if (this.mCurrentPrimaryItem != null) {
|
||||||
this.mCurrentPrimaryItem.setMenuVisibility(false);
|
this.mCurrentPrimaryItem.setMenuVisibility(false);
|
||||||
@ -213,7 +213,7 @@ function initializeNativeClasses() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isViewFromObject(view: android.view.View, object: java.lang.Object): boolean {
|
isViewFromObject(view: android.view.View, object: java.lang.Object): boolean {
|
||||||
return (<android.app.Fragment>object).getView() === view;
|
return (<android.support.v4.app.Fragment>object).getView() === view;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveState(): android.os.Parcelable {
|
saveState(): android.os.Parcelable {
|
||||||
|
@ -1,28 +1,29 @@
|
|||||||
import { Transition, AndroidTransitionType } from "./transition";
|
import { Transition, AndroidTransitionType } from "./transition";
|
||||||
|
|
||||||
export class FadeTransition extends Transition {
|
export class FadeTransition extends Transition {
|
||||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||||
const alphaValues = Array.create("float", 2);
|
const alphaValues = [];
|
||||||
switch (transitionType) {
|
switch (transitionType) {
|
||||||
case AndroidTransitionType.enter:
|
case AndroidTransitionType.enter:
|
||||||
case AndroidTransitionType.popEnter:
|
case AndroidTransitionType.popEnter:
|
||||||
alphaValues[0] = 0;
|
alphaValues[0] = 0.0;
|
||||||
alphaValues[1] = 1;
|
alphaValues[1] = 1.0;
|
||||||
break;
|
break;
|
||||||
case AndroidTransitionType.exit:
|
case AndroidTransitionType.exit:
|
||||||
case AndroidTransitionType.popExit:
|
case AndroidTransitionType.popExit:
|
||||||
alphaValues[0] = 1;
|
alphaValues[0] = 1.0;
|
||||||
alphaValues[1] = 0;
|
alphaValues[1] = 0.0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", alphaValues);
|
const animation = new android.view.animation.AlphaAnimation(alphaValues[0], alphaValues[1]);
|
||||||
const duration = this.getDuration();
|
const duration = this.getDuration();
|
||||||
if (duration !== undefined) {
|
if (duration !== undefined) {
|
||||||
animator.setDuration(duration);
|
animation.setDuration(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
animator.setInterpolator(this.getCurve());
|
animation.setInterpolator(this.getCurve());
|
||||||
return animator;
|
|
||||||
|
return animation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Transition, AndroidTransitionType } from "./transition";
|
import { Transition, AndroidTransitionType } from "./transition";
|
||||||
|
|
||||||
//http://developer.android.com/training/animation/cardflip.html
|
// http://developer.android.com/training/animation/cardflip.html
|
||||||
export class FlipTransition extends Transition {
|
export class FlipTransition extends Transition {
|
||||||
private _direction: string;
|
private _direction: string;
|
||||||
|
|
||||||
@ -9,109 +9,117 @@ export class FlipTransition extends Transition {
|
|||||||
this._direction = direction;
|
this._direction = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||||
let objectAnimators;
|
ensureRotate3dAnimationClass();
|
||||||
let values;
|
|
||||||
let animator: android.animation.ObjectAnimator;
|
let animation: android.view.animation.Animation;
|
||||||
const animatorSet = new android.animation.AnimatorSet();
|
let animationSet: android.view.animation.AnimationSet
|
||||||
|
let rotateAnimation: android.view.animation.Animation;
|
||||||
|
let alphaAnimation: android.view.animation.Animation;
|
||||||
const fullDuration = this.getDuration() || 300;
|
const fullDuration = this.getDuration() || 300;
|
||||||
const interpolator = this.getCurve();
|
const interpolator = this.getCurve();
|
||||||
const rotationY = this._direction === "right" ? 180 : -180;
|
const rotationY = this._direction === "right" ? 180 : -180;
|
||||||
|
|
||||||
switch (transitionType) {
|
switch (transitionType) {
|
||||||
case AndroidTransitionType.enter: // card_flip_right_in
|
case AndroidTransitionType.enter: // card_flip_right_in
|
||||||
objectAnimators = Array.create(android.animation.Animator, 3);
|
animation = new Rotate3dAnimationClass(rotationY, 0.0, 0.5, 0.5);
|
||||||
|
animation.setInterpolator(interpolator);
|
||||||
values = Array.create("float", 2);
|
animation.setDuration(fullDuration);
|
||||||
values[0] = 1.0;
|
|
||||||
values[1] = 0.0;
|
|
||||||
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
|
||||||
animator.setDuration(0);
|
|
||||||
objectAnimators[0] = animator;
|
|
||||||
|
|
||||||
values = Array.create("float", 2);
|
|
||||||
values[0] = rotationY;
|
|
||||||
values[1] = 0.0;
|
|
||||||
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
|
||||||
animator.setInterpolator(interpolator);
|
|
||||||
animator.setDuration(fullDuration);
|
|
||||||
objectAnimators[1] = animator;
|
|
||||||
|
|
||||||
values = Array.create("float", 2);
|
|
||||||
values[0] = 0.0;
|
|
||||||
values[1] = 1.0;
|
|
||||||
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
|
||||||
animator.setStartDelay(fullDuration / 2);
|
|
||||||
animator.setDuration(1);
|
|
||||||
objectAnimators[2] = animator;
|
|
||||||
break;
|
break;
|
||||||
case AndroidTransitionType.exit: // card_flip_right_out
|
case AndroidTransitionType.exit: // card_flip_right_out
|
||||||
objectAnimators = Array.create(android.animation.Animator, 2);
|
animation = animationSet = new android.view.animation.AnimationSet(false /* shareInterpolator */);
|
||||||
|
|
||||||
|
rotateAnimation = new Rotate3dAnimationClass(0.0, -rotationY, 0.5, 0.5);
|
||||||
|
rotateAnimation.setInterpolator(interpolator);
|
||||||
|
rotateAnimation.setDuration(fullDuration);
|
||||||
|
animationSet.addAnimation(rotateAnimation);
|
||||||
|
|
||||||
values = Array.create("float", 2);
|
alphaAnimation = new android.view.animation.AlphaAnimation(1.0, 0.0);
|
||||||
values[0] = 0.0;
|
alphaAnimation.setStartOffset(fullDuration / 2);
|
||||||
values[1] = -rotationY;
|
alphaAnimation.setDuration(1);
|
||||||
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
animationSet.addAnimation(alphaAnimation);
|
||||||
animator.setInterpolator(interpolator);
|
|
||||||
animator.setDuration(fullDuration);
|
|
||||||
objectAnimators[0] = animator;
|
|
||||||
|
|
||||||
values = Array.create("float", 2);
|
|
||||||
values[0] = 1.0;
|
|
||||||
values[1] = 0.0;
|
|
||||||
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
|
||||||
animator.setStartDelay(fullDuration / 2);
|
|
||||||
animator.setDuration(1);
|
|
||||||
objectAnimators[1] = animator;
|
|
||||||
break;
|
break;
|
||||||
case AndroidTransitionType.popEnter: // card_flip_left_in
|
case AndroidTransitionType.popEnter: // card_flip_left_in
|
||||||
objectAnimators = Array.create(android.animation.Animator, 3);
|
animation = new Rotate3dAnimationClass(-rotationY, 0.0, 0.5, 0.5);
|
||||||
|
animation.setInterpolator(interpolator);
|
||||||
values = Array.create("float", 2);
|
animation.setDuration(fullDuration);
|
||||||
values[0] = 1.0;
|
|
||||||
values[1] = 0.0;
|
|
||||||
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
|
||||||
animator.setDuration(0);
|
|
||||||
objectAnimators[0] = animator;
|
|
||||||
|
|
||||||
values = Array.create("float", 2);
|
|
||||||
values[0] = -rotationY;
|
|
||||||
values[1] = 0.0;
|
|
||||||
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
|
||||||
animator.setInterpolator(interpolator);
|
|
||||||
animator.setDuration(fullDuration);
|
|
||||||
objectAnimators[1] = animator;
|
|
||||||
|
|
||||||
values = Array.create("float", 2);
|
|
||||||
values[0] = 0.0;
|
|
||||||
values[1] = 1.0;
|
|
||||||
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
|
||||||
animator.setStartDelay(fullDuration / 2);
|
|
||||||
animator.setDuration(1);
|
|
||||||
objectAnimators[2] = animator;
|
|
||||||
break;
|
break;
|
||||||
case AndroidTransitionType.popExit: // card_flip_left_out
|
case AndroidTransitionType.popExit: // card_flip_left_out
|
||||||
objectAnimators = Array.create(android.animation.Animator, 2);
|
animation = animationSet = new android.view.animation.AnimationSet(false /* shareInterpolator */);
|
||||||
|
|
||||||
|
rotateAnimation = new Rotate3dAnimationClass(0.0, rotationY, 0.5, 0.5);
|
||||||
|
rotateAnimation.setInterpolator(interpolator);
|
||||||
|
rotateAnimation.setDuration(fullDuration);
|
||||||
|
animationSet.addAnimation(rotateAnimation);
|
||||||
|
|
||||||
values = Array.create("float", 2);
|
alphaAnimation = new android.view.animation.AlphaAnimation(1.0, 0.0);
|
||||||
values[0] = 0.0;
|
alphaAnimation.setStartOffset(fullDuration / 2);
|
||||||
values[1] = rotationY;
|
alphaAnimation.setDuration(1);
|
||||||
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
animationSet.addAnimation(alphaAnimation);
|
||||||
animator.setInterpolator(interpolator);
|
|
||||||
animator.setDuration(fullDuration);
|
|
||||||
objectAnimators[0] = animator;
|
|
||||||
|
|
||||||
values = Array.create("float", 2);
|
|
||||||
values[0] = 1.0;
|
|
||||||
values[1] = 0.0;
|
|
||||||
animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", values);
|
|
||||||
animator.setStartDelay(fullDuration / 2);
|
|
||||||
animator.setDuration(1);
|
|
||||||
objectAnimators[1] = animator;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
animatorSet.playTogether(objectAnimators);
|
return animation;
|
||||||
return animatorSet;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let Rotate3dAnimationClass;
|
||||||
|
function ensureRotate3dAnimationClass() {
|
||||||
|
if (Rotate3dAnimationClass) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new 3D rotation on the Y axis. The rotation is defined by its
|
||||||
|
* start angle and its end angle. Both angles are in degrees. The rotation
|
||||||
|
* is performed around a center point on the 2D space, definied by a pair
|
||||||
|
* of X and Y coordinates, called centerX and centerY.
|
||||||
|
*
|
||||||
|
* @param fromDegrees the start angle of the 3D rotation
|
||||||
|
* @param toDegrees the end angle of the 3D rotation
|
||||||
|
* @param centerX the X center of the 3D rotation (relative to self)
|
||||||
|
* @param centerY the Y center of the 3D rotation (relative to self)
|
||||||
|
*/
|
||||||
|
class Rotate3dAnimation extends android.view.animation.Animation {
|
||||||
|
private _camera: android.graphics.Camera;
|
||||||
|
private _pivotX: number;
|
||||||
|
private _pivotY: number;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private _fromDegrees: number,
|
||||||
|
private _toDegrees: number,
|
||||||
|
private _centerX: number,
|
||||||
|
private _centerY: number) {
|
||||||
|
super();
|
||||||
|
return global.__native(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public initialize(width: number, height: number, parentWidth: number, parentHeight: number) {
|
||||||
|
super.initialize(width, height, parentWidth, parentHeight);
|
||||||
|
this._pivotX = this.resolveSize(android.view.animation.Animation.RELATIVE_TO_SELF, this._centerX, width, parentWidth);
|
||||||
|
this._pivotY = this.resolveSize(android.view.animation.Animation.RELATIVE_TO_SELF, this._centerY, height, parentHeight);
|
||||||
|
this._camera = new android.graphics.Camera();
|
||||||
|
}
|
||||||
|
|
||||||
|
public applyTransformation(interpolatedTime: number, t: android.view.animation.Transformation) {
|
||||||
|
const fromDegrees = this._fromDegrees;
|
||||||
|
const degrees = fromDegrees + ((this._toDegrees - fromDegrees) * interpolatedTime);
|
||||||
|
|
||||||
|
const pivotX = this._pivotX;
|
||||||
|
const pivotY = this._pivotY;
|
||||||
|
const camera = this._camera;
|
||||||
|
|
||||||
|
const matrix: android.graphics.Matrix = t.getMatrix();
|
||||||
|
|
||||||
|
camera.save();
|
||||||
|
camera.rotateY(degrees);
|
||||||
|
camera.getMatrix(matrix);
|
||||||
|
camera.restore();
|
||||||
|
|
||||||
|
matrix.preTranslate(-pivotX, -pivotY);
|
||||||
|
matrix.postTranslate(pivotX, pivotY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rotate3dAnimationClass = Rotate3dAnimation;
|
||||||
|
}
|
@ -13,8 +13,8 @@ export class SlideTransition extends transition.Transition {
|
|||||||
this._direction = direction;
|
this._direction = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||||
const translationValues = Array.create("float", 2);
|
const translationValues = [];
|
||||||
switch (this._direction) {
|
switch (this._direction) {
|
||||||
case "left":
|
case "left":
|
||||||
switch (transitionType) {
|
switch (transitionType) {
|
||||||
@ -97,23 +97,25 @@ export class SlideTransition extends transition.Transition {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let prop;
|
|
||||||
|
let animation;
|
||||||
if (this._direction === "left" || this._direction === "right") {
|
if (this._direction === "left" || this._direction === "right") {
|
||||||
prop = "translationX";
|
animation = new android.view.animation.TranslateAnimation(translationValues[0], translationValues[1], 0, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
prop = "translationY";
|
animation = new android.view.animation.TranslateAnimation(0, 0, translationValues[0], translationValues[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const animator = android.animation.ObjectAnimator.ofFloat(null, prop, translationValues);
|
|
||||||
const duration = this.getDuration();
|
const duration = this.getDuration();
|
||||||
if (duration !== undefined) {
|
if (duration !== undefined) {
|
||||||
animator.setDuration(duration);
|
animation.setDuration(duration);
|
||||||
}
|
}
|
||||||
animator.setInterpolator(this.getCurve());
|
|
||||||
return animator;
|
animation.setInterpolator(this.getCurve());
|
||||||
|
|
||||||
|
return animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public toString(): string {
|
public toString(): string {
|
||||||
return `${super.toString()} ${this._direction}`;
|
return `${super.toString()} ${this._direction}`;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ export class Transition implements TransitionDefinition {
|
|||||||
throw new Error("Abstract method call");
|
throw new Error("Abstract method call");
|
||||||
}
|
}
|
||||||
|
|
||||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||||
throw new Error("Abstract method call");
|
throw new Error("Abstract method call");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,6 @@ export class Transition {
|
|||||||
public getDuration(): number;
|
public getDuration(): number;
|
||||||
public getCurve(): any;
|
public getCurve(): any;
|
||||||
public animateIOSTransition(containerView: any, fromView: any, toView: any, operation: any, completion: (finished: boolean) => void): void;
|
public animateIOSTransition(containerView: any, fromView: any, toView: any, operation: any, completion: (finished: boolean) => void): void;
|
||||||
public createAndroidAnimator(transitionType: string): any;
|
public createAndroidAnimation(transitionType: string): any;
|
||||||
public toString(): string;
|
public toString(): string;
|
||||||
}
|
}
|
@ -24,7 +24,7 @@ export class Transition implements TransitionDefinition {
|
|||||||
throw new Error("Abstract method call");
|
throw new Error("Abstract method call");
|
||||||
}
|
}
|
||||||
|
|
||||||
public createAndroidAnimator(transitionType: string): any {
|
public createAndroidAnimation(transitionType: string): any {
|
||||||
throw new Error("Abstract method call");
|
throw new Error("Abstract method call");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ export module ad {
|
|||||||
|
|
||||||
if (nativeView instanceof android.view.View) {
|
if (nativeView instanceof android.view.View) {
|
||||||
windowToken = nativeView.getWindowToken()
|
windowToken = nativeView.getWindowToken()
|
||||||
} else if (androidApp.foregroundActivity instanceof android.app.Activity) {
|
} else if (androidApp.foregroundActivity instanceof android.support.v7.app.AppCompatActivity) {
|
||||||
const decorView = androidApp.foregroundActivity.getWindow().getDecorView();
|
const decorView = androidApp.foregroundActivity.getWindow().getDecorView();
|
||||||
windowToken = decorView ? decorView.getWindowToken() : null;
|
windowToken = decorView ? decorView.getWindowToken() : null;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user