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);
|
||||
}
|
||||
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
var scaleValues = Array.create("float", 2);
|
||||
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||
const scaleValues = [];
|
||||
|
||||
switch (transitionType) {
|
||||
case transition.AndroidTransitionType.enter:
|
||||
case transition.AndroidTransitionType.popEnter:
|
||||
@ -19,18 +20,22 @@ export class CustomTransition extends transition.Transition {
|
||||
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();
|
||||
|
||||
const animationSet = new android.view.animation.AnimationSet(false);
|
||||
const duration = this.getDuration();
|
||||
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 nativeApp: android.app.Application;
|
||||
public context: android.content.Context;
|
||||
public foregroundActivity: android.app.Activity;
|
||||
public startActivity: android.app.Activity;
|
||||
public foregroundActivity: android.support.v7.app.AppCompatActivity;
|
||||
public startActivity: android.support.v7.app.AppCompatActivity;
|
||||
public packageName: string;
|
||||
// we are using these property to store the callbacks to avoid early GC collection which would trigger MarkReachableObjects
|
||||
private callbacks: any = {};
|
||||
@ -221,7 +221,7 @@ global.__onLiveSync = function () {
|
||||
};
|
||||
|
||||
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
|
||||
const activityInfo = activity.getPackageManager().getActivityInfo(activity.getComponentName(), android.content.pm.PackageManager.GET_META_DATA);
|
||||
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 });
|
||||
});
|
||||
|
||||
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();
|
||||
// store the listener not to trigger GC collection before collecting the method
|
||||
this.onGlobalLayoutListener = new android.view.ViewTreeObserver.OnGlobalLayoutListener({
|
||||
@ -250,7 +250,7 @@ function initLifecycleCallbacks() {
|
||||
});
|
||||
|
||||
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);
|
||||
|
||||
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) {
|
||||
androidApp.foregroundActivity = undefined;
|
||||
}
|
||||
@ -278,7 +278,7 @@ function initLifecycleCallbacks() {
|
||||
gc();
|
||||
}),
|
||||
|
||||
onActivityPaused: profile("onActivityPaused", function (activity: android.app.Activity) {
|
||||
onActivityPaused: profile("onActivityPaused", function (activity: android.support.v7.app.AppCompatActivity) {
|
||||
if ((<any>activity).isNativeScriptActivity) {
|
||||
androidApp.paused = true;
|
||||
notify(<ApplicationEventData>{ eventName: suspendEvent, object: androidApp, android: activity });
|
||||
@ -287,7 +287,7 @@ function initLifecycleCallbacks() {
|
||||
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;
|
||||
|
||||
if ((<any>activity).isNativeScriptActivity) {
|
||||
@ -298,15 +298,15 @@ function initLifecycleCallbacks() {
|
||||
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 });
|
||||
}),
|
||||
|
||||
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 });
|
||||
}),
|
||||
|
||||
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 });
|
||||
})
|
||||
});
|
||||
|
@ -288,7 +288,7 @@ export interface AndroidActivityEventData {
|
||||
/**
|
||||
* The activity.
|
||||
*/
|
||||
activity: any /* android.app.Activity */;
|
||||
activity: any /* android.support.v7.app.AppCompatActivity */;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
foregroundActivity: any /* android.app.Activity */;
|
||||
foregroundActivity: any /* android.support.v7.app.AppCompatActivity */;
|
||||
|
||||
/**
|
||||
* Deprecated. Please use startActivity, foregroundActivity or context property.
|
||||
@ -388,7 +388,7 @@ export class AndroidApplication extends Observable {
|
||||
/**
|
||||
* 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.
|
||||
|
@ -47,7 +47,7 @@ interface TouchListener {
|
||||
}
|
||||
|
||||
interface DialogFragment {
|
||||
new(): android.app.DialogFragment;
|
||||
new(): android.support.v4.app.DialogFragment;
|
||||
}
|
||||
|
||||
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;
|
||||
private _fullscreen: boolean;
|
||||
private _stretched: boolean;
|
||||
@ -141,7 +141,7 @@ function initializeDialogFragment() {
|
||||
this._dismissCallback = options.dismissCallback;
|
||||
this._shownCallback = options.shownCallback;
|
||||
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());
|
||||
|
||||
@ -225,13 +225,13 @@ function getModalOptions(domId: number): DialogOptions {
|
||||
export class View extends ViewCommon {
|
||||
public static androidBackPressedEvent = androidBackPressedEvent;
|
||||
|
||||
public _dialogFragment: android.app.DialogFragment;
|
||||
public _dialogFragment: android.support.v4.app.DialogFragment;
|
||||
private _isClickable: boolean;
|
||||
private touchListenerIsSet: boolean;
|
||||
private touchListener: android.view.View.OnTouchListener;
|
||||
private layoutChangeListenerIsSet: boolean;
|
||||
private layoutChangeListener: android.view.View.OnLayoutChangeListener;
|
||||
private _manager: android.app.FragmentManager;
|
||||
private _manager: android.support.v4.app.FragmentManager;
|
||||
|
||||
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;
|
||||
if (!manager) {
|
||||
let view: View = this;
|
||||
@ -280,7 +280,7 @@ export class View extends ViewCommon {
|
||||
}
|
||||
|
||||
if (!manager && this._context) {
|
||||
manager = (<android.app.Activity>this._context).getFragmentManager();
|
||||
manager = (<android.support.v7.app.AppCompatActivity>this._context).getSupportFragmentManager();
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
_getFragmentManager(): any; /* android.app.FragmentManager */
|
||||
_getFragmentManager(): any; /* android.support.v4.app.FragmentManager */
|
||||
|
||||
/**
|
||||
* Updates styleScope or create new styleScope.
|
||||
|
@ -36,7 +36,7 @@ function dismissSoftInput(owner: EditableTextBase): void {
|
||||
if (!dismissKeyboardTimeoutId) {
|
||||
dismissKeyboardTimeoutId = setTimeout(() => {
|
||||
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;
|
||||
dismissKeyboardTimeoutId = null;
|
||||
dismissKeyboardOwner = null;
|
||||
|
@ -8,7 +8,7 @@ if ((<any>global).__snapshot || (<any>global).__snapshotEnabled) {
|
||||
|
||||
//@ts-ignore
|
||||
@JavaProxy("com.tns.NativeScriptActivity")
|
||||
class NativeScriptActivity extends android.app.Activity {
|
||||
class NativeScriptActivity extends android.support.v7.app.AppCompatActivity {
|
||||
private _callbacks: AndroidActivityCallbacks;
|
||||
public isNativeScriptActivity;
|
||||
constructor() {
|
||||
@ -54,7 +54,7 @@ class NativeScriptActivity extends android.app.Activity {
|
||||
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*/);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { AndroidFragmentCallbacks, setFragmentCallbacks, setFragmentClass } from "./frame";
|
||||
|
||||
@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)
|
||||
private _callbacks: AndroidFragmentCallbacks;
|
||||
|
||||
@ -14,9 +14,8 @@ class FragmentClass extends android.app.Fragment {
|
||||
this._callbacks.onHiddenChanged(this, hidden, super.onHiddenChanged);
|
||||
}
|
||||
|
||||
public onCreateAnimator(transit: number, enter: boolean, nextAnim: number): android.animation.Animator {
|
||||
let result = this._callbacks.onCreateAnimator(this, transit, enter, nextAnim, super.onCreateAnimator);
|
||||
return result;
|
||||
public onCreateAnimation(transit: number, enter: boolean, nextAnim: number): android.view.animation.Animation {
|
||||
return this._callbacks.onCreateAnimation(this, transit, enter, nextAnim, super.onCreateAnimation);
|
||||
}
|
||||
|
||||
public onStop(): void {
|
||||
|
@ -19,7 +19,7 @@ interface TransitionListener {
|
||||
new(entry: ExpandedEntry, transition: android.transition.Transition): ExpandedTransitionListener;
|
||||
}
|
||||
|
||||
interface ExpandedAnimator extends android.animation.Animator {
|
||||
interface ExpandedAnimation extends android.view.animation.Animation {
|
||||
entry: ExpandedEntry;
|
||||
transitionType?: string;
|
||||
}
|
||||
@ -35,13 +35,13 @@ interface ExpandedEntry extends BackstackEntry {
|
||||
reenterTransitionListener: ExpandedTransitionListener;
|
||||
returnTransitionListener: ExpandedTransitionListener;
|
||||
|
||||
enterAnimator: ExpandedAnimator;
|
||||
exitAnimator: ExpandedAnimator;
|
||||
popEnterAnimator: ExpandedAnimator;
|
||||
popExitAnimator: ExpandedAnimator;
|
||||
enterAnimation: ExpandedAnimation;
|
||||
exitAnimation: ExpandedAnimation;
|
||||
popEnterAnimation: ExpandedAnimation;
|
||||
popExitAnimation: ExpandedAnimation;
|
||||
|
||||
defaultEnterAnimator: ExpandedAnimator;
|
||||
defaultExitAnimator: ExpandedAnimator;
|
||||
defaultEnterAnimation: ExpandedAnimation;
|
||||
defaultExitAnimation: ExpandedAnimation;
|
||||
|
||||
transition: Transition;
|
||||
transitionName: string;
|
||||
@ -49,7 +49,6 @@ interface ExpandedEntry extends BackstackEntry {
|
||||
}
|
||||
|
||||
const sdkVersion = lazy(() => parseInt(device.sdkVersion));
|
||||
const intEvaluator = lazy(() => new android.animation.IntEvaluator());
|
||||
const defaultInterpolator = lazy(() => new android.view.animation.AccelerateDecelerateInterpolator());
|
||||
const isAndroidP = lazy(() => sdkVersion() > 27);
|
||||
|
||||
@ -57,23 +56,23 @@ export const waitingQueue = new Map<number, Set<ExpandedEntry>>();
|
||||
export const completedEntries = new Map<number, ExpandedEntry>();
|
||||
|
||||
let TransitionListener: TransitionListener;
|
||||
let AnimationListener: android.animation.Animator.AnimatorListener;
|
||||
let loadAnimatorMethod: java.lang.reflect.Method;
|
||||
let AnimationListener: android.view.animation.Animation.AnimationListener;
|
||||
let loadAnimationMethod: java.lang.reflect.Method;
|
||||
let reflectionDone: boolean;
|
||||
let defaultEnterAnimatorStatic: android.animation.Animator;
|
||||
let defaultExitAnimatorStatic: android.animation.Animator;
|
||||
let defaultEnterAnimationStatic: android.view.animation.Animation;
|
||||
let defaultExitAnimationStatic: android.view.animation.Animation;
|
||||
|
||||
export function _setAndroidFragmentTransitions(
|
||||
animated: boolean,
|
||||
navigationTransition: NavigationTransition,
|
||||
currentEntry: ExpandedEntry,
|
||||
newEntry: ExpandedEntry,
|
||||
fragmentTransaction: android.app.FragmentTransaction,
|
||||
manager: android.app.FragmentManager,
|
||||
fragmentTransaction: android.support.v4.app.FragmentTransaction,
|
||||
manager: android.support.v4.app.FragmentManager,
|
||||
frameId: number): void {
|
||||
|
||||
const currentFragment: android.app.Fragment = currentEntry ? currentEntry.fragment : null;
|
||||
const newFragment: android.app.Fragment = newEntry.fragment;
|
||||
const currentFragment: android.support.v4.app.Fragment = currentEntry ? currentEntry.fragment : null;
|
||||
const newFragment: android.support.v4.app.Fragment = newEntry.fragment;
|
||||
const entries = waitingQueue.get(frameId);
|
||||
if (entries && entries.size > 0) {
|
||||
throw new Error("Calling navigation before previous navigation finish.");
|
||||
@ -189,39 +188,39 @@ export function _setAndroidFragmentTransitions(
|
||||
printTransitions(newEntry);
|
||||
}
|
||||
|
||||
export function _onFragmentCreateAnimator(entry: ExpandedEntry, fragment: android.app.Fragment, nextAnim: number, enter: boolean): android.animation.Animator {
|
||||
let animator: android.animation.Animator;
|
||||
export function _onFragmentCreateAnimation(entry: ExpandedEntry, fragment: android.support.v4.app.Fragment, nextAnim: number, enter: boolean): android.view.animation.Animation {
|
||||
let animation: android.view.animation.Animation;
|
||||
switch (nextAnim) {
|
||||
case AnimationType.enterFakeResourceId:
|
||||
animator = entry.enterAnimator;
|
||||
animation = entry.enterAnimation;
|
||||
break;
|
||||
|
||||
case AnimationType.exitFakeResourceId:
|
||||
animator = entry.exitAnimator;
|
||||
animation = entry.exitAnimation;
|
||||
break;
|
||||
|
||||
case AnimationType.popEnterFakeResourceId:
|
||||
animator = entry.popEnterAnimator;
|
||||
animation = entry.popEnterAnimation;
|
||||
break;
|
||||
|
||||
case AnimationType.popExitFakeResourceId:
|
||||
animator = entry.popExitAnimator;
|
||||
animation = entry.popExitAnimation;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!animator && sdkVersion() >= 21) {
|
||||
if (!animation && sdkVersion() >= 21) {
|
||||
const view = fragment.getView();
|
||||
const jsParent = entry.resolvedPage.parent;
|
||||
const parent = view.getParent() || (jsParent && jsParent.nativeViewProtected);
|
||||
const animatedEntries = _getAnimatedEntries(entry.frameId);
|
||||
if (!animatedEntries || !animatedEntries.has(entry)) {
|
||||
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> {
|
||||
@ -331,45 +330,45 @@ function getTransitionListener(entry: ExpandedEntry, transition: android.transit
|
||||
return new TransitionListener(entry, transition);
|
||||
}
|
||||
|
||||
function getAnimationListener(): android.animation.Animator.AnimatorListener {
|
||||
function getAnimationListener(): android.view.animation.Animation.AnimationListener {
|
||||
if (!AnimationListener) {
|
||||
@Interfaces([android.animation.Animator.AnimatorListener])
|
||||
class AnimationListnerImpl extends java.lang.Object implements android.animation.Animator.AnimatorListener {
|
||||
@Interfaces([android.view.animation.Animation.AnimationListener])
|
||||
class AnimationListenerImpl extends java.lang.Object implements android.view.animation.Animation.AnimationListener {
|
||||
constructor() {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onAnimationStart(animator: ExpandedAnimator): void {
|
||||
const entry = animator.entry;
|
||||
onAnimationStart(animation: ExpandedAnimation): void {
|
||||
const entry = animation.entry;
|
||||
addToWaitingQueue(entry);
|
||||
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()) {
|
||||
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()) {
|
||||
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()) {
|
||||
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;
|
||||
@ -386,24 +385,23 @@ function addToWaitingQueue(entry: ExpandedEntry): void {
|
||||
entries.add(entry);
|
||||
}
|
||||
|
||||
function clearAnimationListener(animator: ExpandedAnimator, listener: android.animation.Animator.AnimatorListener): void {
|
||||
if (!animator) {
|
||||
function clearAnimationListener(animation: ExpandedAnimation): void {
|
||||
if (!animation) {
|
||||
return;
|
||||
}
|
||||
|
||||
animator.removeListener(listener);
|
||||
|
||||
if (traceEnabled()) {
|
||||
const entry = animator.entry;
|
||||
traceWrite(`Clear ${animator.transitionType} - ${entry.transition} for ${entry.fragmentTag}`, traceCategories.Transition);
|
||||
const entry = animation.entry;
|
||||
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 {
|
||||
if (sdkVersion() >= 21) {
|
||||
const fragment: android.app.Fragment = entry.fragment;
|
||||
const fragment: android.support.v4.app.Fragment = entry.fragment;
|
||||
const exitListener = entry.exitTransitionListener;
|
||||
if (exitListener) {
|
||||
const exitTransition = fragment.getExitTransition();
|
||||
@ -456,7 +454,7 @@ function clearEntry(entry: ExpandedEntry, removeListener: boolean): void {
|
||||
clearExitAndReenterTransitions(entry, removeListener);
|
||||
|
||||
if (sdkVersion() >= 21) {
|
||||
const fragment: android.app.Fragment = entry.fragment;
|
||||
const fragment: android.support.v4.app.Fragment = entry.fragment;
|
||||
const enterListener = entry.enterTransitionListener;
|
||||
if (enterListener) {
|
||||
const enterTransition = fragment.getEnterTransition();
|
||||
@ -497,15 +495,14 @@ function clearEntry(entry: ExpandedEntry, removeListener: boolean): void {
|
||||
}
|
||||
|
||||
if (removeListener) {
|
||||
const listener = getAnimationListener();
|
||||
clearAnimationListener(entry.enterAnimator, listener);
|
||||
clearAnimationListener(entry.exitAnimator, listener);
|
||||
clearAnimationListener(entry.popEnterAnimator, listener);
|
||||
clearAnimationListener(entry.popExitAnimator, listener);
|
||||
clearAnimationListener(entry.enterAnimation);
|
||||
clearAnimationListener(entry.exitAnimation);
|
||||
clearAnimationListener(entry.popEnterAnimation);
|
||||
clearAnimationListener(entry.popExitAnimation);
|
||||
}
|
||||
}
|
||||
|
||||
function allowTransitionOverlap(fragment: android.app.Fragment): void {
|
||||
function allowTransitionOverlap(fragment: android.support.v4.app.Fragment): void {
|
||||
if (fragment) {
|
||||
fragment.setAllowEnterTransitionOverlap(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.
|
||||
entry.enterTransitionListener = listener;
|
||||
const fragment: android.app.Fragment = entry.fragment;
|
||||
const fragment: android.support.v4.app.Fragment = entry.fragment;
|
||||
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.
|
||||
entry.exitTransitionListener = listener;
|
||||
const fragment: android.app.Fragment = entry.fragment;
|
||||
const fragment: android.support.v4.app.Fragment = entry.fragment;
|
||||
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.
|
||||
entry.reenterTransitionListener = listener;
|
||||
const fragment: android.app.Fragment = entry.fragment;
|
||||
const fragment: android.support.v4.app.Fragment = entry.fragment;
|
||||
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.
|
||||
entry.returnTransitionListener = listener;
|
||||
const fragment: android.app.Fragment = entry.fragment;
|
||||
const fragment: android.support.v4.app.Fragment = entry.fragment;
|
||||
fragment.setReturnTransition(transition);
|
||||
}
|
||||
|
||||
@ -638,21 +635,21 @@ function setupNewFragmentExplodeTransition(navTransition: NavigationTransition,
|
||||
function setupExitAndPopEnterAnimation(entry: ExpandedEntry, transition: Transition): void {
|
||||
const listener = getAnimationListener();
|
||||
|
||||
// remove previous listener if we are changing the animator.
|
||||
clearAnimationListener(entry.exitAnimator, listener);
|
||||
clearAnimationListener(entry.popEnterAnimator, listener);
|
||||
// remove previous listener if we are changing the animation.
|
||||
clearAnimationListener(entry.exitAnimation);
|
||||
clearAnimationListener(entry.popEnterAnimation);
|
||||
|
||||
const exitAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.exit);
|
||||
exitAnimator.transitionType = AndroidTransitionType.exit;
|
||||
exitAnimator.entry = entry;
|
||||
exitAnimator.addListener(listener);
|
||||
entry.exitAnimator = exitAnimator;
|
||||
const exitAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.exit);
|
||||
exitAnimation.transitionType = AndroidTransitionType.exit;
|
||||
exitAnimation.entry = entry;
|
||||
exitAnimation.setAnimationListener(listener);
|
||||
entry.exitAnimation = exitAnimation;
|
||||
|
||||
const popEnterAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.popEnter);
|
||||
popEnterAnimator.transitionType = AndroidTransitionType.popEnter;
|
||||
popEnterAnimator.entry = entry;
|
||||
popEnterAnimator.addListener(listener);
|
||||
entry.popEnterAnimator = popEnterAnimator;
|
||||
const popEnterAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.popEnter);
|
||||
popEnterAnimation.transitionType = AndroidTransitionType.popEnter;
|
||||
popEnterAnimation.entry = entry;
|
||||
popEnterAnimation.setAnimationListener(listener);
|
||||
entry.popEnterAnimation = popEnterAnimation;
|
||||
}
|
||||
|
||||
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
|
||||
// need to clearAnimationListener for enter & popExit animators.
|
||||
const enterAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.enter);
|
||||
enterAnimator.transitionType = AndroidTransitionType.enter;
|
||||
enterAnimator.entry = entry;
|
||||
enterAnimator.addListener(listener);
|
||||
entry.enterAnimator = enterAnimator;
|
||||
const enterAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.enter);
|
||||
enterAnimation.transitionType = AndroidTransitionType.enter;
|
||||
enterAnimation.entry = entry;
|
||||
enterAnimation.setAnimationListener(listener);
|
||||
entry.enterAnimation = enterAnimation;
|
||||
|
||||
const popExitAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.popExit);
|
||||
popExitAnimator.transitionType = AndroidTransitionType.popExit;
|
||||
popExitAnimator.entry = entry;
|
||||
popExitAnimator.addListener(listener);
|
||||
entry.popExitAnimator = popExitAnimator;
|
||||
const popExitAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.popExit);
|
||||
popExitAnimation.transitionType = AndroidTransitionType.popExit;
|
||||
popExitAnimation.entry = entry;
|
||||
popExitAnimation.setAnimationListener(listener);
|
||||
entry.popExitAnimation = popExitAnimation;
|
||||
}
|
||||
|
||||
function setupDefaultAnimations(entry: ExpandedEntry, transition: Transition): void {
|
||||
const listener = getAnimationListener();
|
||||
|
||||
const enterAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.enter);
|
||||
enterAnimator.transitionType = AndroidTransitionType.enter;
|
||||
enterAnimator.entry = entry;
|
||||
enterAnimator.addListener(listener);
|
||||
entry.defaultEnterAnimator = enterAnimator;
|
||||
const enterAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.enter);
|
||||
enterAnimation.transitionType = AndroidTransitionType.enter;
|
||||
enterAnimation.entry = entry;
|
||||
enterAnimation.setAnimationListener(listener);
|
||||
entry.defaultEnterAnimation = enterAnimation;
|
||||
|
||||
const exitAnimator = <ExpandedAnimator>transition.createAndroidAnimator(AndroidTransitionType.exit);
|
||||
exitAnimator.transitionType = AndroidTransitionType.exit;
|
||||
exitAnimator.entry = entry;
|
||||
exitAnimator.addListener(listener);
|
||||
entry.defaultExitAnimator = exitAnimator;
|
||||
const exitAnimation = <ExpandedAnimation>transition.createAndroidAnimation(AndroidTransitionType.exit);
|
||||
exitAnimation.transitionType = AndroidTransitionType.exit;
|
||||
exitAnimation.entry = entry;
|
||||
exitAnimation.setAnimationListener(listener);
|
||||
entry.defaultExitAnimation = exitAnimation;
|
||||
}
|
||||
|
||||
function setUpNativeTransition(navigationTransition: NavigationTransition, nativeTransition: android.transition.Transition) {
|
||||
@ -754,38 +751,41 @@ function javaClassArray(...params: java.lang.Class<any>[]) {
|
||||
return nativeArray;
|
||||
}
|
||||
|
||||
function initDefaultAnimations(manager: android.app.FragmentManager): void {
|
||||
function initDefaultAnimations(manager: android.support.v4.app.FragmentManager): void {
|
||||
if (reflectionDone) {
|
||||
return;
|
||||
}
|
||||
|
||||
reflectionDone = true;
|
||||
|
||||
loadAnimatorMethod = manager.getClass().getDeclaredMethod("loadAnimator", javaClassArray(android.app.Fragment.class, java.lang.Integer.TYPE, java.lang.Boolean.TYPE, java.lang.Integer.TYPE));
|
||||
if (loadAnimatorMethod != null) {
|
||||
loadAnimatorMethod.setAccessible(true);
|
||||
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 (loadAnimationMethod != null) {
|
||||
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 fragment = new android.app.Fragment();
|
||||
const fragment = new android.support.v4.app.Fragment();
|
||||
|
||||
// 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.
|
||||
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 {
|
||||
const defaultAnimator = enter ? defaultEnterAnimatorStatic : defaultExitAnimatorStatic;
|
||||
return defaultAnimator ? defaultAnimator.clone() : null;
|
||||
function getDefaultAnimation(enter: boolean): android.view.animation.Animation {
|
||||
const defaultAnimation = enter ? defaultEnterAnimationStatic : defaultExitAnimationStatic;
|
||||
return defaultAnimation ? defaultAnimation.clone() : null;
|
||||
}
|
||||
|
||||
function createDummyZeroDurationAnimator(): android.animation.Animator {
|
||||
const animator = android.animation.ValueAnimator.ofObject(intEvaluator(), javaObjectArray(java.lang.Integer.valueOf(0), java.lang.Integer.valueOf(1)));
|
||||
animator.setDuration(0);
|
||||
return animator;
|
||||
function createDummyZeroDurationAnimation(): android.view.animation.Animation {
|
||||
// NOTE: returning the dummy AlphaAnimation directly does not work for some reason;
|
||||
// animationEnd is fired first, then some animationStart (but for a different animation?)
|
||||
const animationSet = new android.view.animation.AnimationSet(false);
|
||||
animationSet.addAnimation(new android.view.animation.AlphaAnimation(1, 1));
|
||||
|
||||
return animationSet;
|
||||
}
|
||||
|
||||
function printTransitions(entry: ExpandedEntry) {
|
||||
@ -796,10 +796,10 @@ function printTransitions(entry: ExpandedEntry) {
|
||||
}
|
||||
|
||||
if (entry.transition) {
|
||||
result += `enterAnimator=${entry.enterAnimator}, `;
|
||||
result += `exitAnimator=${entry.exitAnimator}, `;
|
||||
result += `popEnterAnimator=${entry.popEnterAnimator}, `;
|
||||
result += `popExitAnimator=${entry.popExitAnimator}, `;
|
||||
result += `enterAnimator=${entry.enterAnimation}, `;
|
||||
result += `exitAnimator=${entry.exitAnimation}, `;
|
||||
result += `popEnterAnimator=${entry.popEnterAnimation}, `;
|
||||
result += `popExitAnimator=${entry.popExitAnimation}, `;
|
||||
}
|
||||
if (sdkVersion() >= 21) {
|
||||
const fragment = entry.fragment;
|
||||
@ -813,13 +813,13 @@ function printTransitions(entry: ExpandedEntry) {
|
||||
}
|
||||
|
||||
class NoTransition extends Transition {
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
return createDummyZeroDurationAnimator();
|
||||
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||
return createDummyZeroDurationAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
class DefaultTransition extends Transition {
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||
switch (transitionType) {
|
||||
case AndroidTransitionType.enter:
|
||||
case AndroidTransitionType.popEnter:
|
||||
|
@ -24,12 +24,12 @@ export function _setAndroidFragmentTransitions(
|
||||
currentEntry: BackstackEntry,
|
||||
newEntry: BackstackEntry,
|
||||
fragmentTransaction: any,
|
||||
manager: any /* android.app.FragmentManager */,
|
||||
manager: any /* android.support.v4.app.FragmentManager */,
|
||||
frameId: number): void;
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
} from "./frame-common";
|
||||
|
||||
import {
|
||||
_setAndroidFragmentTransitions, _onFragmentCreateAnimator, _getAnimatedEntries,
|
||||
_setAndroidFragmentTransitions, _onFragmentCreateAnimation, _getAnimatedEntries,
|
||||
_updateTransitions, _reverseTransitions, _clearEntry, _clearFragment, AnimationType
|
||||
} from "./fragment.transitions";
|
||||
|
||||
@ -195,7 +195,7 @@ export class Frame extends FrameBase {
|
||||
return;
|
||||
}
|
||||
|
||||
const manager: android.app.FragmentManager = this._getFragmentManager();
|
||||
const manager: android.support.v4.app.FragmentManager = this._getFragmentManager();
|
||||
const transaction = manager.beginTransaction();
|
||||
const androidSdkVersion = sdkVersion();
|
||||
|
||||
@ -214,7 +214,7 @@ export class Frame extends FrameBase {
|
||||
transaction.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
private createFragment(backstackEntry: BackstackEntry, fragmentTag: string): android.app.Fragment {
|
||||
private createFragment(backstackEntry: BackstackEntry, fragmentTag: string): android.support.v4.app.Fragment {
|
||||
ensureFragmentClass();
|
||||
const newFragment = new fragmentClass();
|
||||
const args = new android.os.Bundle();
|
||||
@ -316,7 +316,7 @@ export class Frame extends FrameBase {
|
||||
return;
|
||||
}
|
||||
|
||||
const manager: android.app.FragmentManager = this._getFragmentManager();
|
||||
const manager: android.support.v4.app.FragmentManager = this._getFragmentManager();
|
||||
const clearHistory = newEntry.entry.clearHistory;
|
||||
const currentEntry = this._currentEntry;
|
||||
|
||||
@ -343,7 +343,7 @@ export class Frame extends FrameBase {
|
||||
// }
|
||||
|
||||
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);
|
||||
@ -355,7 +355,7 @@ export class Frame extends FrameBase {
|
||||
super._goBackCore(backstackEntry);
|
||||
navDepth = backstackEntry.navDepth;
|
||||
|
||||
const manager: android.app.FragmentManager = this._getFragmentManager();
|
||||
const manager: android.support.v4.app.FragmentManager = this._getFragmentManager();
|
||||
const transaction = manager.beginTransaction();
|
||||
|
||||
if (!backstackEntry.fragment) {
|
||||
@ -509,8 +509,8 @@ class AndroidFrame extends Observable implements AndroidFrameDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
public get activity(): android.app.Activity {
|
||||
let activity: android.app.Activity = this.owner._context;
|
||||
public get activity(): android.support.v7.app.AppCompatActivity {
|
||||
let activity: android.support.v7.app.AppCompatActivity = this.owner._context;
|
||||
if (activity) {
|
||||
return activity;
|
||||
}
|
||||
@ -542,7 +542,7 @@ class AndroidFrame extends Observable implements AndroidFrameDefinition {
|
||||
return bar;
|
||||
}
|
||||
|
||||
public get currentActivity(): android.app.Activity {
|
||||
public get currentActivity(): android.support.v7.app.AppCompatActivity {
|
||||
let activity = this.activity;
|
||||
if (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();
|
||||
if (traceEnabled()) {
|
||||
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
|
||||
const intent = new android.content.Intent(activity, activity.getClass());
|
||||
intent.setAction(android.content.Intent.ACTION_DEFAULT);
|
||||
@ -646,7 +646,7 @@ function ensureFragmentClass() {
|
||||
require("ui/frame/fragment");
|
||||
|
||||
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;
|
||||
|
||||
@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()) {
|
||||
traceWrite(`${fragment}.onHiddenChanged(${hidden})`, traceCategories.NativeLifecycle);
|
||||
}
|
||||
@ -672,28 +672,29 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
}
|
||||
|
||||
@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;
|
||||
switch (nextAnim) {
|
||||
case -10: nextAnimString = "enter"; break;
|
||||
case -20: nextAnimString = "exit"; break;
|
||||
case -30: nextAnimString = "popEnter"; break;
|
||||
case -40: nextAnimString = "popExit"; break;
|
||||
case AnimationType.enterFakeResourceId: nextAnimString = "enter"; break;
|
||||
case AnimationType.exitFakeResourceId: nextAnimString = "exit"; break;
|
||||
case AnimationType.popEnterFakeResourceId: nextAnimString = "popEnter"; break;
|
||||
case AnimationType.popExitFakeResourceId: nextAnimString = "popExit"; break;
|
||||
}
|
||||
|
||||
let animator = _onFragmentCreateAnimator(this.entry, fragment, nextAnim, enter);
|
||||
if (!animator) {
|
||||
animator = superFunc.call(fragment, transit, enter, nextAnim);
|
||||
let animation = _onFragmentCreateAnimation(this.entry, fragment, nextAnim, enter);
|
||||
if (!animation) {
|
||||
animation = superFunc.call(fragment, transit, enter, nextAnim);
|
||||
}
|
||||
|
||||
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
|
||||
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()) {
|
||||
traceWrite(`${fragment}.onCreate(${savedInstanceState})`, traceCategories.NativeLifecycle);
|
||||
}
|
||||
@ -714,7 +715,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
}
|
||||
|
||||
@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()) {
|
||||
traceWrite(`${fragment}.onCreateView(inflater, container, ${savedInstanceState})`, traceCategories.NativeLifecycle);
|
||||
}
|
||||
@ -752,7 +753,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
}
|
||||
|
||||
@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()) {
|
||||
traceWrite(`${fragment}.onSaveInstanceState(${outState})`, traceCategories.NativeLifecycle);
|
||||
}
|
||||
@ -760,7 +761,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
}
|
||||
|
||||
@profile
|
||||
public onDestroyView(fragment: android.app.Fragment, superFunc: Function): void {
|
||||
public onDestroyView(fragment: android.support.v4.app.Fragment, superFunc: Function): void {
|
||||
if (traceEnabled()) {
|
||||
traceWrite(`${fragment}.onDestroyView()`, traceCategories.NativeLifecycle);
|
||||
}
|
||||
@ -768,7 +769,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
}
|
||||
|
||||
@profile
|
||||
public onDestroy(fragment: android.app.Fragment, superFunc: Function): void {
|
||||
public onDestroy(fragment: android.support.v4.app.Fragment, superFunc: Function): void {
|
||||
if (traceEnabled()) {
|
||||
traceWrite(`${fragment}.onDestroy()`, traceCategories.NativeLifecycle);
|
||||
}
|
||||
@ -776,12 +777,12 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
}
|
||||
|
||||
@profile
|
||||
public onStop(fragment: android.app.Fragment, superFunc: Function): void {
|
||||
public onStop(fragment: android.support.v4.app.Fragment, superFunc: Function): void {
|
||||
superFunc.call(fragment);
|
||||
}
|
||||
|
||||
@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;
|
||||
if (entry) {
|
||||
return `${entry.fragmentTag}<${entry.resolvedPage}>`;
|
||||
@ -799,7 +800,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
||||
}
|
||||
|
||||
@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()) {
|
||||
traceWrite(`Activity.onCreate(${savedInstanceState})`, traceCategories.NativeLifecycle);
|
||||
}
|
||||
@ -826,7 +827,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
||||
}
|
||||
|
||||
@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);
|
||||
const rootView = this._rootView;
|
||||
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) {
|
||||
const manager = this._rootView._getFragmentManager();
|
||||
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
|
||||
// 4. _resetRootView method. this._rootView should have been cleared upfront. Launch event should not fired
|
||||
private setActivityContent(
|
||||
activity: android.app.Activity,
|
||||
activity: android.support.v7.app.AppCompatActivity,
|
||||
savedInstanceState: android.os.Bundle,
|
||||
fireLaunchEvent: boolean
|
||||
): void {
|
||||
@ -1069,10 +1070,10 @@ const notifyLaunch = profile("notifyLaunch", function notifyLaunch(intent: andro
|
||||
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();
|
||||
}
|
||||
|
||||
export function setFragmentCallbacks(fragment: android.app.Fragment): void {
|
||||
export function setFragmentCallbacks(fragment: android.support.v4.app.Fragment): void {
|
||||
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;
|
||||
|
||||
@ -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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
currentActivity: any /* android.app.Activity */;
|
||||
currentActivity: any /* android.support.v7.app.AppCompatActivity */;
|
||||
|
||||
/**
|
||||
* Gets the actionBar property of the currentActivity.
|
||||
@ -388,7 +388,7 @@ export interface AndroidFrame extends Observable {
|
||||
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.
|
||||
*/
|
||||
fragmentForPage(entry: BackstackEntry): any;
|
||||
@ -410,7 +410,7 @@ export interface AndroidActivityCallbacks {
|
||||
|
||||
export interface AndroidFragmentCallbacks {
|
||||
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;
|
||||
onCreateView(fragment: any, inflater: any, container: any, savedInstanceState: any, superFunc: Function): any;
|
||||
onSaveInstanceState(fragment: any, outState: any, superFunc: Function): void;
|
||||
@ -446,7 +446,7 @@ export interface iOSFrame {
|
||||
//@endprivate
|
||||
}
|
||||
|
||||
export function setActivityCallbacks(activity: any /*android.app.Activity*/): void;
|
||||
export function setActivityCallbacks(activity: any /*android.support.v7.app.AppCompatActivity*/): void;
|
||||
//@private
|
||||
/**
|
||||
* @private
|
||||
@ -455,5 +455,5 @@ export function reloadPage(): void;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export function setFragmentCallbacks(fragment: any /*android.app.Fragment*/): void;
|
||||
export function setFragmentCallbacks(fragment: any /*android.support.v4.app.Fragment*/): void;
|
||||
//@endprivate
|
||||
|
@ -59,7 +59,7 @@ export class Page extends PageBase {
|
||||
|
||||
[statusBarStyleProperty.getDefault](): { color: number, systemUiVisibility: number } {
|
||||
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();
|
||||
|
||||
return {
|
||||
@ -72,7 +72,7 @@ export class Page extends PageBase {
|
||||
}
|
||||
[statusBarStyleProperty.setNative](value: "dark" | "light" | { color: number, systemUiVisibility: number }) {
|
||||
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();
|
||||
|
||||
if (value === "light") {
|
||||
@ -91,7 +91,7 @@ export class Page extends PageBase {
|
||||
|
||||
[androidStatusBarBackgroundProperty.getDefault](): number {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ export class Page extends PageBase {
|
||||
}
|
||||
[androidStatusBarBackgroundProperty.setNative](value: number | Color) {
|
||||
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;
|
||||
(<any>window).setStatusBarColor(color);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ function initializeNativeClasses() {
|
||||
return;
|
||||
}
|
||||
|
||||
class TabFragmentImplementation extends android.app.Fragment {
|
||||
class TabFragmentImplementation extends android.support.v4.app.Fragment {
|
||||
private tab: TabView;
|
||||
private index: number;
|
||||
|
||||
@ -90,8 +90,8 @@ function initializeNativeClasses() {
|
||||
|
||||
class FragmentPagerAdapter extends android.support.v4.view.PagerAdapter {
|
||||
public items: Array<TabViewItemDefinition>;
|
||||
private mCurTransaction: android.app.FragmentTransaction;
|
||||
private mCurrentPrimaryItem: android.app.Fragment;
|
||||
private mCurTransaction: android.support.v4.app.FragmentTransaction;
|
||||
private mCurrentPrimaryItem: android.support.v4.app.Fragment;
|
||||
|
||||
constructor(public owner: TabView) {
|
||||
super();
|
||||
@ -127,7 +127,7 @@ function initializeNativeClasses() {
|
||||
const itemId = this.getItemId(position);
|
||||
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) {
|
||||
this.mCurTransaction.attach(fragment);
|
||||
} else {
|
||||
@ -159,7 +159,7 @@ function initializeNativeClasses() {
|
||||
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);
|
||||
|
||||
if (this.mCurrentPrimaryItem === fragment) {
|
||||
@ -174,7 +174,7 @@ function initializeNativeClasses() {
|
||||
}
|
||||
|
||||
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 (this.mCurrentPrimaryItem != null) {
|
||||
this.mCurrentPrimaryItem.setMenuVisibility(false);
|
||||
@ -213,7 +213,7 @@ function initializeNativeClasses() {
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -1,28 +1,29 @@
|
||||
import { Transition, AndroidTransitionType } from "./transition";
|
||||
|
||||
export class FadeTransition extends Transition {
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
const alphaValues = Array.create("float", 2);
|
||||
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||
const alphaValues = [];
|
||||
switch (transitionType) {
|
||||
case AndroidTransitionType.enter:
|
||||
case AndroidTransitionType.popEnter:
|
||||
alphaValues[0] = 0;
|
||||
alphaValues[1] = 1;
|
||||
alphaValues[0] = 0.0;
|
||||
alphaValues[1] = 1.0;
|
||||
break;
|
||||
case AndroidTransitionType.exit:
|
||||
case AndroidTransitionType.popExit:
|
||||
alphaValues[0] = 1;
|
||||
alphaValues[1] = 0;
|
||||
alphaValues[0] = 1.0;
|
||||
alphaValues[1] = 0.0;
|
||||
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();
|
||||
if (duration !== undefined) {
|
||||
animator.setDuration(duration);
|
||||
animation.setDuration(duration);
|
||||
}
|
||||
|
||||
animator.setInterpolator(this.getCurve());
|
||||
return animator;
|
||||
animation.setInterpolator(this.getCurve());
|
||||
|
||||
return animation;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
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 {
|
||||
private _direction: string;
|
||||
|
||||
@ -9,109 +9,117 @@ export class FlipTransition extends Transition {
|
||||
this._direction = direction;
|
||||
}
|
||||
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
let objectAnimators;
|
||||
let values;
|
||||
let animator: android.animation.ObjectAnimator;
|
||||
const animatorSet = new android.animation.AnimatorSet();
|
||||
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||
ensureRotate3dAnimationClass();
|
||||
|
||||
let animation: android.view.animation.Animation;
|
||||
let animationSet: android.view.animation.AnimationSet
|
||||
let rotateAnimation: android.view.animation.Animation;
|
||||
let alphaAnimation: android.view.animation.Animation;
|
||||
const fullDuration = this.getDuration() || 300;
|
||||
const interpolator = this.getCurve();
|
||||
const rotationY = this._direction === "right" ? 180 : -180;
|
||||
|
||||
switch (transitionType) {
|
||||
case AndroidTransitionType.enter: // card_flip_right_in
|
||||
objectAnimators = Array.create(android.animation.Animator, 3);
|
||||
|
||||
values = Array.create("float", 2);
|
||||
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;
|
||||
animation = new Rotate3dAnimationClass(rotationY, 0.0, 0.5, 0.5);
|
||||
animation.setInterpolator(interpolator);
|
||||
animation.setDuration(fullDuration);
|
||||
break;
|
||||
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);
|
||||
values[0] = 0.0;
|
||||
values[1] = -rotationY;
|
||||
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
||||
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;
|
||||
alphaAnimation = new android.view.animation.AlphaAnimation(1.0, 0.0);
|
||||
alphaAnimation.setStartOffset(fullDuration / 2);
|
||||
alphaAnimation.setDuration(1);
|
||||
animationSet.addAnimation(alphaAnimation);
|
||||
break;
|
||||
case AndroidTransitionType.popEnter: // card_flip_left_in
|
||||
objectAnimators = Array.create(android.animation.Animator, 3);
|
||||
|
||||
values = Array.create("float", 2);
|
||||
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;
|
||||
animation = new Rotate3dAnimationClass(-rotationY, 0.0, 0.5, 0.5);
|
||||
animation.setInterpolator(interpolator);
|
||||
animation.setDuration(fullDuration);
|
||||
break;
|
||||
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);
|
||||
values[0] = 0.0;
|
||||
values[1] = rotationY;
|
||||
animator = android.animation.ObjectAnimator.ofFloat(null, "rotationY", values);
|
||||
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;
|
||||
alphaAnimation = new android.view.animation.AlphaAnimation(1.0, 0.0);
|
||||
alphaAnimation.setStartOffset(fullDuration / 2);
|
||||
alphaAnimation.setDuration(1);
|
||||
animationSet.addAnimation(alphaAnimation);
|
||||
break;
|
||||
}
|
||||
|
||||
animatorSet.playTogether(objectAnimators);
|
||||
return animatorSet;
|
||||
return animation;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
const translationValues = Array.create("float", 2);
|
||||
public createAndroidAnimation(transitionType: string): android.view.animation.Animation {
|
||||
const translationValues = [];
|
||||
switch (this._direction) {
|
||||
case "left":
|
||||
switch (transitionType) {
|
||||
@ -97,23 +97,25 @@ export class SlideTransition extends transition.Transition {
|
||||
}
|
||||
break;
|
||||
}
|
||||
let prop;
|
||||
|
||||
let animation;
|
||||
if (this._direction === "left" || this._direction === "right") {
|
||||
prop = "translationX";
|
||||
animation = new android.view.animation.TranslateAnimation(translationValues[0], translationValues[1], 0, 0);
|
||||
}
|
||||
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();
|
||||
if (duration !== undefined) {
|
||||
animator.setDuration(duration);
|
||||
animation.setDuration(duration);
|
||||
}
|
||||
animator.setInterpolator(this.getCurve());
|
||||
return animator;
|
||||
|
||||
animation.setInterpolator(this.getCurve());
|
||||
|
||||
return animation;
|
||||
}
|
||||
|
||||
|
||||
public toString(): string {
|
||||
return `${super.toString()} ${this._direction}`;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ export class Transition implements TransitionDefinition {
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,6 @@ export class Transition {
|
||||
public getDuration(): number;
|
||||
public getCurve(): any;
|
||||
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;
|
||||
}
|
@ -24,7 +24,7 @@ export class Transition implements TransitionDefinition {
|
||||
throw new Error("Abstract method call");
|
||||
}
|
||||
|
||||
public createAndroidAnimator(transitionType: string): any {
|
||||
public createAndroidAnimation(transitionType: string): any {
|
||||
throw new Error("Abstract method call");
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ export module ad {
|
||||
|
||||
if (nativeView instanceof android.view.View) {
|
||||
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();
|
||||
windowToken = decorView ? decorView.getWindowToken() : null;
|
||||
}
|
||||
|
Reference in New Issue
Block a user