mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Fixed: Navigating with clearHistory / transition
This commit is contained in:
@@ -39,25 +39,26 @@ export class NavPage extends Page implements definition.ControlsPage {
|
||||
|
||||
var that = this;
|
||||
that.on(View.loadedEvent, (args) => {
|
||||
console.log(`Loaded ${args.object}`);
|
||||
console.log(`NavPage: Loaded ${args.object}`);
|
||||
if (topmostFrame().android) {
|
||||
console.log(`NavPage: topmostFrame().android.cachePagesOnNavigate = true;`);
|
||||
topmostFrame().android.cachePagesOnNavigate = true;
|
||||
}
|
||||
});
|
||||
that.on(View.unloadedEvent, (args) => {
|
||||
console.log(`Unloaded ${args.object}`);
|
||||
console.log(`NavPage: Unloaded ${args.object}`);
|
||||
});
|
||||
that.on(Page.navigatingFromEvent, (args: NavigatedData) => {
|
||||
console.log(`NavigatING FROM ${args.object}, isBackNavigation: ${args.isBackNavigation}`);
|
||||
console.log(`NavPage: NavigatING FROM ${args.object}, isBackNavigation: ${args.isBackNavigation}`);
|
||||
});
|
||||
that.on(Page.navigatedFromEvent, (args: NavigatedData) => {
|
||||
console.log(`NaviagatED FROM ${args.object}, isBackNavigation: ${args.isBackNavigation}`);
|
||||
console.log(`NavPage: NaviagatED FROM ${args.object}, isBackNavigation: ${args.isBackNavigation}`);
|
||||
});
|
||||
that.on(Page.navigatingToEvent, (args: NavigatedData) => {
|
||||
console.log(`NavigatING TO ${args.object}, isBackNavigation: ${args.isBackNavigation}`);
|
||||
console.log(`NavPage: NavigatING TO ${args.object}, isBackNavigation: ${args.isBackNavigation}`);
|
||||
});
|
||||
that.on(Page.navigatedToEvent, (args: NavigatedData) => {
|
||||
console.log(`NavigatED TO ${args.object}, isBackNavigation: ${args.isBackNavigation}`);
|
||||
console.log(`NavPage: NavigatED TO ${args.object}, isBackNavigation: ${args.isBackNavigation}`);
|
||||
(<any>topmostFrame())._printFrameBackStack();
|
||||
if (topmostFrame().android) {
|
||||
(<any>topmostFrame())._printNativeBackStack();
|
||||
|
||||
@@ -60,7 +60,7 @@ var runTest = function (testInfo: TestInfoEntry) {
|
||||
if (testInfo.isTest) {
|
||||
duration = time() - start;
|
||||
testInfo.duration = duration;
|
||||
write("--- [" + testInfo.testName + "] OK, duration: " + duration, trace.messageType.info);
|
||||
write(`--- [${testInfo.testName}] OK, duration: ${duration}`, trace.messageType.info);
|
||||
testInfo.isPassed = true;
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ var runTest = function (testInfo: TestInfoEntry) {
|
||||
if (testInfo.isTest) {
|
||||
duration = time() - start;
|
||||
testInfo.duration = duration;
|
||||
write("--- [" + testInfo.testName + "] FAILED: " + e.message + ", duration: " + duration, trace.messageType.error);
|
||||
write(`--- [${testInfo.testName}] FAILED: ${e.message}, duration: ${duration}`, trace.messageType.error);
|
||||
testInfo.isPassed = false;
|
||||
testInfo.errorMessage = e.message;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,16 @@ import {Label} from "ui/label";
|
||||
trace.enable();
|
||||
trace.addCategories(trace.categories.Test + "," + trace.categories.Error);
|
||||
|
||||
// When debugging
|
||||
//trace.setCategories(trace.categories.concat(
|
||||
// trace.categories.Test,
|
||||
// trace.categories.Navigation,
|
||||
// trace.categories.Transition,
|
||||
// trace.categories.NativeLifecycle,
|
||||
// trace.categories.ViewHierarchy,
|
||||
// trace.categories.VisualTreeEvents
|
||||
//));
|
||||
|
||||
let page = new Page();
|
||||
page.id = "mainPage";
|
||||
|
||||
|
||||
@@ -4,36 +4,51 @@ import {topmost as topmostFrame, NavigationTransition} from "ui/frame";
|
||||
import {Color} from "color";
|
||||
|
||||
// Creates a random colorful page full of meaningless stuff.
|
||||
var pageFactory = function(): Page {
|
||||
var id = 0;
|
||||
var pageFactory = function (): Page {
|
||||
var page = new Page();
|
||||
page.actionBarHidden = true;
|
||||
page.id = `NavTestPage${id++}`;
|
||||
page.style.backgroundColor = new Color(255, Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255));
|
||||
return page;
|
||||
};
|
||||
|
||||
function waitUntilNavigatedFrom(oldPage: Page) {
|
||||
let topmost = topmostFrame();
|
||||
TKUnit.waitUntilReady(() => {
|
||||
return topmost.currentPage
|
||||
&& topmost.currentPage !== oldPage
|
||||
&& topmost.currentPage.isLoaded
|
||||
&& !oldPage.isLoaded
|
||||
;
|
||||
});
|
||||
}
|
||||
|
||||
function _test_backstackVisible(transition?: NavigationTransition) {
|
||||
let topmost = topmostFrame();
|
||||
let mainTestPage = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, transition: transition });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage !== mainTestPage; });
|
||||
topmost.navigate({ create: pageFactory, transition: transition, animated: true });
|
||||
waitUntilNavigatedFrom(mainTestPage);
|
||||
|
||||
// page1 should not be added to the backstack
|
||||
let page0 = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, backstackVisible: false, transition: transition });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage !== page0; });
|
||||
topmost.navigate({ create: pageFactory, backstackVisible: false, transition: transition, animated: true });
|
||||
waitUntilNavigatedFrom(page0);
|
||||
|
||||
let page1 = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, transition: transition });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage !== page1; });
|
||||
topmost.navigate({ create: pageFactory, transition: transition, animated: true });
|
||||
waitUntilNavigatedFrom(page1);
|
||||
|
||||
let page2 = topmost.currentPage;
|
||||
topmost.goBack();
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage !== page2; });
|
||||
waitUntilNavigatedFrom(page2);
|
||||
|
||||
// From page2 we have to go directly to page0, skipping page1.
|
||||
TKUnit.assert(topmost.currentPage === page0, "Page 1 should be skipped when going back.");
|
||||
|
||||
topmost.goBack();
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage === mainTestPage; });
|
||||
waitUntilNavigatedFrom(page0);
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, "We should be on the main test page at the end of the test.");
|
||||
}
|
||||
|
||||
export var test_backstackVisible = function () {
|
||||
@@ -45,22 +60,26 @@ export var test_backstackVisible_WithTransition = function () {
|
||||
}
|
||||
|
||||
function _test_backToEntry(transition?: NavigationTransition) {
|
||||
let topmost = topmostFrame();
|
||||
let page = (tag) => () => {
|
||||
var p = new Page();
|
||||
p.actionBarHidden = true;
|
||||
p.id = `NavTestPage${id++}`;
|
||||
p["tag"] = tag;
|
||||
return p;
|
||||
}
|
||||
let topmost = topmostFrame();
|
||||
let wait = tag => TKUnit.waitUntilReady(() => topmost.currentPage["tag"] === tag, 1);
|
||||
let mainTestPage = topmost.currentPage;
|
||||
let waitFunc = tag => TKUnit.waitUntilReady(() => topmost.currentPage["tag"] === tag, 1);
|
||||
let navigate = tag => {
|
||||
topmost.navigate({ create: page(tag), transition: transition });
|
||||
wait(tag)
|
||||
topmost.navigate({ create: page(tag), transition: transition, animated: true });
|
||||
waitFunc(tag);
|
||||
|
||||
}
|
||||
let back = pages => {
|
||||
topmost.goBack(topmost.backStack[topmost.backStack.length - pages]);
|
||||
}
|
||||
let currentPageMustBe = tag => {
|
||||
wait(tag); // TODO: Add a timeout...
|
||||
waitFunc(tag); // TODO: Add a timeout...
|
||||
TKUnit.assert(topmost.currentPage["tag"] === tag, "Expected current page to be " + tag + " it was " + topmost.currentPage["tag"] + " instead.");
|
||||
}
|
||||
|
||||
@@ -81,7 +100,10 @@ function _test_backToEntry(transition?: NavigationTransition) {
|
||||
currentPageMustBe("page1.1");
|
||||
back(1);
|
||||
currentPageMustBe("page1");
|
||||
let page1 = topmost.currentPage;
|
||||
back(1);
|
||||
waitUntilNavigatedFrom(page1);
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, "We should be on the main test page at the end of the test.");
|
||||
}
|
||||
|
||||
export var test_backToEntry = function () {
|
||||
@@ -102,34 +124,37 @@ function _test_ClearHistory(transition?: NavigationTransition) {
|
||||
var currentPage: Page;
|
||||
|
||||
currentPage = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, clearHistory: true, transition: transition});
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage !== currentPage; });
|
||||
topmost.navigate({ create: pageFactory, clearHistory: true, transition: transition, animated: true });
|
||||
waitUntilNavigatedFrom(currentPage);
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, "1.topmost.backStack.length");
|
||||
TKUnit.assertEqual(topmost.canGoBack(), false, "1.topmost.canGoBack().");
|
||||
|
||||
currentPage = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, transition: transition });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage !== currentPage; });
|
||||
topmost.navigate({ create: pageFactory, transition: transition, animated: true });
|
||||
waitUntilNavigatedFrom(currentPage);
|
||||
TKUnit.assertEqual(topmost.backStack.length, 1, "2.topmost.backStack.length");
|
||||
TKUnit.assertEqual(topmost.canGoBack(), true, "2.topmost.canGoBack().");
|
||||
|
||||
currentPage = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, transition: transition });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage !== currentPage; });
|
||||
topmost.navigate({ create: pageFactory, transition: transition, animated: true });
|
||||
waitUntilNavigatedFrom(currentPage);
|
||||
TKUnit.assertEqual(topmost.backStack.length, 2, "3.topmost.backStack.length");
|
||||
TKUnit.assertEqual(topmost.canGoBack(), true, "3.topmost.canGoBack().");
|
||||
|
||||
currentPage = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, transition: transition });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage !== currentPage; });
|
||||
topmost.navigate({ create: pageFactory, clearHistory: true, transition: transition, animated: true });
|
||||
waitUntilNavigatedFrom(currentPage);
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, "4.topmost.backStack.length");
|
||||
TKUnit.assertEqual(topmost.canGoBack(), false, "4.topmost.canGoBack().");
|
||||
|
||||
TKUnit.assert(topmost.canGoBack(), "Frame should be able to go back.");
|
||||
TKUnit.assert(topmost.backStack.length === 3, "Back stack should have 3 entries.");
|
||||
|
||||
// Navigate with clear history.
|
||||
currentPage = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, clearHistory: true, transition: transition });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage !== currentPage; });
|
||||
topmost.navigate({ create: mainPageFactory, clearHistory: true, animated: false });
|
||||
waitUntilNavigatedFrom(currentPage);
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, "5.topmost.backStack.length");
|
||||
TKUnit.assertEqual(topmost.canGoBack(), false, "5.topmost.canGoBack().");
|
||||
|
||||
TKUnit.assert(!topmost.canGoBack(), "Frame should NOT be able to go back.");
|
||||
TKUnit.assert(topmost.backStack.length === 0, "Back stack should have 0 entries.");
|
||||
|
||||
topmost.navigate({ create: mainPageFactory, transition: transition });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage === mainTestPage; });
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, "We should be on the main test page at the end of the test.");
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, "Back stack should be empty at the end of the test.");
|
||||
}
|
||||
|
||||
// Clearing the history messes up the tests app.
|
||||
@@ -138,49 +163,104 @@ export var test_ClearHistory = function () {
|
||||
}
|
||||
|
||||
export var test_ClearHistory_WithTransition = function () {
|
||||
_test_ClearHistory({ name: "slide" });
|
||||
_test_ClearHistory({ name: "fade" });
|
||||
}
|
||||
|
||||
export var test_ClearHistory_WithTransition_WithCachePagesOnNavigate = function () {
|
||||
let topmost = topmostFrame();
|
||||
if (!topmost.android) {
|
||||
return;
|
||||
}
|
||||
|
||||
let originalCachePagesOnNavigate = topmost.android.cachePagesOnNavigate;
|
||||
topmostFrame().android.cachePagesOnNavigate = true;
|
||||
_test_ClearHistory({ name: "fade" });
|
||||
topmostFrame().android.cachePagesOnNavigate = originalCachePagesOnNavigate;
|
||||
}
|
||||
|
||||
// Test case for https://github.com/NativeScript/NativeScript/issues/1948
|
||||
export var test_ClearHistoryWithTransitionDoesNotBreakNavigation = function () {
|
||||
let topmost = topmostFrame();
|
||||
|
||||
let mainTestPage = topmost.currentPage;
|
||||
let mainPageFactory = function (): Page {
|
||||
return mainTestPage;
|
||||
};
|
||||
|
||||
// Go to details-page
|
||||
topmost.navigate({ create: pageFactory, clearHistory: false });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage !== mainTestPage; });
|
||||
topmost.navigate({ create: pageFactory, clearHistory: false, animated: true });
|
||||
waitUntilNavigatedFrom(mainTestPage);
|
||||
|
||||
// Go back to main-page with clearHistory
|
||||
var detailsPage: Page;
|
||||
detailsPage = topmost.currentPage;
|
||||
topmost.transition = { name: "fade" };
|
||||
topmost.navigate({ create: mainPageFactory, clearHistory: true });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage === mainTestPage; });
|
||||
topmost.navigate({ create: mainPageFactory, clearHistory: true, animated: true });
|
||||
waitUntilNavigatedFrom(detailsPage);
|
||||
|
||||
// Go to details-page AGAIN
|
||||
topmost.navigate({ create: pageFactory, clearHistory: false });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage !== mainTestPage; });
|
||||
topmost.navigate({ create: pageFactory, clearHistory: false, animated: true });
|
||||
waitUntilNavigatedFrom(mainTestPage);
|
||||
|
||||
// Go back to main-page with clearHistory
|
||||
detailsPage = topmost.currentPage;
|
||||
topmost.transition = { name: "fade" };
|
||||
topmost.navigate({ create: mainPageFactory, clearHistory: true });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage === mainTestPage; });
|
||||
topmost.navigate({ create: mainPageFactory, clearHistory: true, animated: true });
|
||||
waitUntilNavigatedFrom(detailsPage);
|
||||
|
||||
// Clean up
|
||||
topmost.transition = undefined;
|
||||
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, "We should be on the main test page at the end of the test.");
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, "Back stack should be empty at the end of the test.");
|
||||
}
|
||||
|
||||
export var test_ClearHistoryWithTransitionDoesNotBreakNavigation_WithLocalTransition = function () {
|
||||
let topmost = topmostFrame();
|
||||
let originalCachePagesOnNavigate: boolean;
|
||||
if (topmost.android) {
|
||||
originalCachePagesOnNavigate = topmost.android.cachePagesOnNavigate;
|
||||
topmostFrame().android.cachePagesOnNavigate = true;
|
||||
}
|
||||
|
||||
let mainTestPage = topmost.currentPage;
|
||||
let mainPageFactory = function (): Page {
|
||||
return mainTestPage;
|
||||
};
|
||||
|
||||
// Go to 1st page
|
||||
var currentPage = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, clearHistory: false, transition: { name: "fade" }, animated: true });
|
||||
waitUntilNavigatedFrom(currentPage);
|
||||
|
||||
// Go to 2nd page
|
||||
currentPage = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, clearHistory: false, transition: { name: "fade" }, animated: true });
|
||||
waitUntilNavigatedFrom(currentPage);
|
||||
|
||||
// Go to 3rd page with clearHistory
|
||||
currentPage = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, clearHistory: true, transition: { name: "fade" }, animated: true });
|
||||
waitUntilNavigatedFrom(currentPage);
|
||||
|
||||
// Go back to main
|
||||
currentPage = topmost.currentPage;
|
||||
topmost.navigate({ create: mainPageFactory, clearHistory: true, transition: { name: "fade" }, animated: true });
|
||||
waitUntilNavigatedFrom(currentPage);
|
||||
|
||||
if (topmost.android) {
|
||||
topmostFrame().android.cachePagesOnNavigate = originalCachePagesOnNavigate;
|
||||
}
|
||||
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, "We should be on the main test page at the end of the test.");
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, "Back stack should be empty at the end of the test.");
|
||||
}
|
||||
|
||||
function _test_NavigationEvents(transition?: NavigationTransition) {
|
||||
let topmost = topmostFrame();
|
||||
let argsToString = (args: NavigatedData) => {
|
||||
return `${(<Page>args.object).id} ${args.eventName} ${(args.isBackNavigation ? "back" : "forward") }`
|
||||
};
|
||||
|
||||
let topmost = topmostFrame();
|
||||
let mainTestPage = topmost.currentPage;
|
||||
let originalMainPageId = mainTestPage.id;
|
||||
mainTestPage.id = "main-page";
|
||||
@@ -193,6 +273,7 @@ function _test_NavigationEvents(transition?: NavigationTransition) {
|
||||
let actualSecondPageEvents = new Array<string>();
|
||||
let secondPageFactory = function (): Page {
|
||||
var secondPage = new Page();
|
||||
secondPage.actionBarHidden = true;
|
||||
secondPage.id = "second-page"
|
||||
secondPage.on(Page.navigatingFromEvent, (args: NavigatedData) => { actualSecondPageEvents.push(argsToString(args)); });
|
||||
secondPage.on(Page.navigatedFromEvent, (args: NavigatedData) => { actualSecondPageEvents.push(argsToString(args)); });
|
||||
@@ -203,12 +284,14 @@ function _test_NavigationEvents(transition?: NavigationTransition) {
|
||||
};
|
||||
|
||||
// Go to other page
|
||||
topmost.navigate({ create: secondPageFactory, transition: transition });
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage !== mainTestPage; });
|
||||
topmost.navigate({ create: secondPageFactory, transition: transition, animated: true });
|
||||
waitUntilNavigatedFrom(mainTestPage);
|
||||
|
||||
// Go back to main
|
||||
let currentPage = topmost.currentPage;
|
||||
topmost.goBack();
|
||||
TKUnit.waitUntilReady(() => { return topmost.currentPage === mainTestPage; });
|
||||
waitUntilNavigatedFrom(currentPage);
|
||||
|
||||
mainTestPage.id = originalMainPageId;
|
||||
|
||||
let expectedMainPageEvents = [
|
||||
@@ -227,6 +310,7 @@ function _test_NavigationEvents(transition?: NavigationTransition) {
|
||||
];
|
||||
TKUnit.arrayAssert(actualSecondPageEvents, expectedSecondPageEvents, "Actual second-page events are different from expected.");
|
||||
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, "We should be on the main test page at the end of the test.");
|
||||
}
|
||||
|
||||
export var test_NavigationEvents = function () {
|
||||
@@ -234,5 +318,5 @@ export var test_NavigationEvents = function () {
|
||||
}
|
||||
|
||||
export var test_NavigationEvents_WithTransition = function () {
|
||||
_test_NavigationEvents({ name: "slide" });
|
||||
_test_NavigationEvents({ name: "fade" });
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import * as helper from "../ui/helper";
|
||||
import * as platform from "platform";
|
||||
import * as trace from "trace";
|
||||
import {Color} from "color";
|
||||
import {NavigationEntry, NavigationTransition} from "ui/frame";
|
||||
import {NavigationEntry, NavigationTransition, topmost as topmostFrame} from "ui/frame";
|
||||
import {Page} from "ui/page";
|
||||
import {AnimationCurve} from "ui/enums"
|
||||
|
||||
@@ -29,6 +29,12 @@ function _testTransition(navigationTransition: NavigationTransition) {
|
||||
|
||||
// Extremely slow. Run only if needed.
|
||||
export var test_Transitions = function () {
|
||||
let topmost = topmostFrame();
|
||||
let mainTestPage = topmost.currentPage;
|
||||
let mainPageFactory = function (): Page {
|
||||
return mainTestPage;
|
||||
};
|
||||
|
||||
helper.navigate(() => {
|
||||
var page = new Page();
|
||||
page.id = "TransitionsTestPage_MAIN"
|
||||
@@ -77,4 +83,14 @@ export var test_Transitions = function () {
|
||||
var customTransition = new customTransitionModule.CustomTransition();
|
||||
_testTransition({ instance: customTransition });
|
||||
}
|
||||
|
||||
var oldPage = topmost.currentPage;
|
||||
topmost.navigate({ create: mainPageFactory, clearHistory: true, animated: false });
|
||||
TKUnit.waitUntilReady(() => {
|
||||
return topmost.currentPage
|
||||
&& topmost.currentPage !== oldPage
|
||||
&& topmost.currentPage.isLoaded
|
||||
&& !oldPage.isLoaded
|
||||
;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -968,6 +968,10 @@ export class View extends ProxyObject implements definition.View {
|
||||
* // TODO: Think whether we need the base Layout routine.
|
||||
*/
|
||||
public _addView(view: View, atIndex?: number) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this}._addView(${view}, ${atIndex})`, trace.categories.ViewHierarchy);
|
||||
}
|
||||
|
||||
if (!view) {
|
||||
throw new Error("Expecting a valid View instance.");
|
||||
}
|
||||
@@ -979,10 +983,6 @@ export class View extends ProxyObject implements definition.View {
|
||||
view._parent = this;
|
||||
this._addViewCore(view, atIndex);
|
||||
view._parentChanged(null);
|
||||
|
||||
if (trace.enabled) {
|
||||
trace.write("called _addView on view " + this._domId + " for a child " + view._domId, trace.categories.ViewHierarchy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1028,6 +1028,9 @@ export class View extends ProxyObject implements definition.View {
|
||||
* Core logic for removing a child view from this instance. Used by the framework to handle lifecycle events more centralized. Do not outside the UI Stack implementation.
|
||||
*/
|
||||
public _removeView(view: View) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this}._removeView(${view})`, trace.categories.ViewHierarchy);
|
||||
}
|
||||
if (view._parent !== this) {
|
||||
throw new Error("View not added to this instance. View: " + view + " CurrentParent: " + view._parent + " ExpectedParent: " + this);
|
||||
}
|
||||
@@ -1035,10 +1038,6 @@ export class View extends ProxyObject implements definition.View {
|
||||
this._removeViewCore(view);
|
||||
view._parent = undefined;
|
||||
view._parentChanged(this);
|
||||
|
||||
if (trace.enabled) {
|
||||
trace.write("called _removeView on view " + this._domId + " for a child " + view._domId, trace.categories.ViewHierarchy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -189,9 +189,8 @@ export class View extends viewCommon.View {
|
||||
}
|
||||
|
||||
if (trace.enabled) {
|
||||
trace.write("calling _onAttached on view " + this._domId, trace.categories.VisualTreeEvents);
|
||||
trace.write(`${this}._onAttached(context)`, trace.categories.VisualTreeEvents);
|
||||
}
|
||||
|
||||
if (this._context === context) {
|
||||
return;
|
||||
}
|
||||
@@ -221,6 +220,9 @@ export class View extends viewCommon.View {
|
||||
}
|
||||
|
||||
public _onDetached(force?: boolean) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this}._onDetached(force)`, trace.categories.VisualTreeEvents);
|
||||
}
|
||||
if (this._childrenCount > 0) {
|
||||
// Detach children first
|
||||
var that = this;
|
||||
@@ -236,10 +238,6 @@ export class View extends viewCommon.View {
|
||||
this._eachChildView(eachChild);
|
||||
}
|
||||
|
||||
if (trace.enabled) {
|
||||
trace.write("calling _onDetached on view " + this._domId, trace.categories.VisualTreeEvents);
|
||||
}
|
||||
|
||||
this._clearAndroidReference();
|
||||
|
||||
this._context = undefined;
|
||||
@@ -265,9 +263,8 @@ export class View extends viewCommon.View {
|
||||
|
||||
public _onContextChanged() {
|
||||
if (trace.enabled) {
|
||||
trace.write("calling _onContextChanged on view " + this._domId, trace.categories.VisualTreeEvents);
|
||||
trace.write(`${this}._onContextChanged`, trace.categories.VisualTreeEvents);
|
||||
}
|
||||
|
||||
this._createUI();
|
||||
// Ensure layout params
|
||||
if (this._nativeView && !(this._nativeView.getLayoutParams() instanceof org.nativescript.widgets.CommonLayoutParams)) {
|
||||
@@ -451,9 +448,15 @@ export class CustomLayoutView extends View implements viewDefinition.CustomLayou
|
||||
|
||||
if (this._nativeView && child._nativeView) {
|
||||
if (types.isNullOrUndefined(atIndex) || atIndex >= this._nativeView.getChildCount()) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this}._nativeView.addView(${child}._nativeView)`, trace.categories.VisualTreeEvents);
|
||||
}
|
||||
this._nativeView.addView(child._nativeView);
|
||||
}
|
||||
else {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this}._nativeView.addView(${child}._nativeView, ${atIndex})`, trace.categories.VisualTreeEvents);
|
||||
}
|
||||
this._nativeView.addView(child._nativeView, atIndex);
|
||||
}
|
||||
return true;
|
||||
@@ -466,6 +469,9 @@ export class CustomLayoutView extends View implements viewDefinition.CustomLayou
|
||||
super._removeViewFromNativeVisualTree(child);
|
||||
|
||||
if (this._nativeView && child._nativeView) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this}._nativeView.removeView(${child}._nativeView)`, trace.categories.VisualTreeEvents);
|
||||
}
|
||||
this._nativeView.removeView(child._nativeView);
|
||||
trace.notifyEvent(child, "childInLayoutRemovedFromNativeVisualTree");
|
||||
}
|
||||
|
||||
@@ -219,6 +219,9 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
var backstackEntry: definition.BackstackEntry = {
|
||||
entry: entry,
|
||||
resolvedPage: page,
|
||||
navDepth: undefined,
|
||||
fragmentTag: undefined,
|
||||
isBack: undefined,
|
||||
isNavigation: true
|
||||
};
|
||||
|
||||
@@ -266,7 +269,7 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
return this._navigationQueue.length === 0;
|
||||
}
|
||||
|
||||
public _isEntryBackstackVisible(entry: definition.BackstackEntry): boolean {
|
||||
public static _isEntryBackstackVisible(entry: definition.BackstackEntry): boolean {
|
||||
if (!entry) {
|
||||
return false;
|
||||
}
|
||||
@@ -297,7 +300,7 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
if (navigationContext.entry.entry.clearHistory) {
|
||||
this._backStack.length = 0;
|
||||
}
|
||||
else if (this._isEntryBackstackVisible(this._currentEntry)) {
|
||||
else if (Frame._isEntryBackstackVisible(this._currentEntry)) {
|
||||
this._backStack.push(this._currentEntry);
|
||||
}
|
||||
|
||||
@@ -313,11 +316,15 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
}
|
||||
|
||||
public _goBackCore(backstackEntry: definition.BackstackEntry) {
|
||||
//
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this}._goBackCore(${this._backstackEntryTrace(backstackEntry) }); ${this}.currentPage: ${this.currentPage}`, trace.categories.Navigation);
|
||||
}
|
||||
}
|
||||
|
||||
public _navigateCore(backstackEntry: definition.BackstackEntry) {
|
||||
//
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this}._navigateCore(${this._backstackEntryTrace(backstackEntry) }); ${this}.currentPage: ${this.currentPage}`, trace.categories.Navigation);
|
||||
}
|
||||
}
|
||||
|
||||
public _onNavigatingTo(backstackEntry: definition.BackstackEntry, isBack: boolean) {
|
||||
@@ -452,13 +459,37 @@ export class Frame extends CustomLayoutView implements definition.Frame {
|
||||
public _printFrameBackStack() {
|
||||
var length = this.backStack.length;
|
||||
var i = length - 1;
|
||||
console.log("---------------------------");
|
||||
console.log("Frame Back Stack (" + length + ")");
|
||||
console.log(`Frame Back Stack: `);
|
||||
while (i >= 0) {
|
||||
var backstackEntry = <definition.BackstackEntry>this.backStack[i--];
|
||||
console.log("[ " + backstackEntry.resolvedPage.id + " ]");
|
||||
console.log(`\t${backstackEntry.resolvedPage}`);
|
||||
}
|
||||
}
|
||||
|
||||
public _backstackEntryTrace(b: definition.BackstackEntry): string {
|
||||
let result = `${b.resolvedPage}`;
|
||||
|
||||
let backstackVisible = Frame._isEntryBackstackVisible(b);
|
||||
if (!backstackVisible) {
|
||||
result += ` | INVISIBLE`;
|
||||
}
|
||||
|
||||
if (b.entry.clearHistory) {
|
||||
result += ` | CLEAR HISTORY`;
|
||||
}
|
||||
|
||||
let animated = this._getIsAnimatedNavigation(b.entry);
|
||||
if (!animated) {
|
||||
result += ` | NOT ANIMATED`;
|
||||
}
|
||||
|
||||
let t = this._getNavigationTransition(b.entry);
|
||||
if (t) {
|
||||
result += ` | Transition[${JSON.stringify(t)}]`;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
var _topmost = function (): Frame {
|
||||
@@ -488,3 +519,4 @@ export function goBack(): boolean {
|
||||
export function stack(): Array<definition.Frame> {
|
||||
return frameStack;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,27 +10,22 @@ import * as types from "utils/types";
|
||||
|
||||
global.moduleMerge(frameCommon, exports);
|
||||
|
||||
var TAG = "_fragmentTag";
|
||||
var HIDDEN = "_hidden";
|
||||
var INTENT_EXTRA = "com.tns.activity";
|
||||
var BACKSTACK_TAG = "_backstackTag";
|
||||
var IS_BACK = "_isBack";
|
||||
var NAV_DEPTH = "_navDepth";
|
||||
var CLEARING_HISTORY = "_clearingHistory";
|
||||
var FRAMEID = "_frameId";
|
||||
var FRAGMENT = "_FRAGMENT";
|
||||
|
||||
var navDepth = -1;
|
||||
|
||||
var activityInitialized = false;
|
||||
let HIDDEN = "_hidden";
|
||||
let INTENT_EXTRA = "com.tns.activity";
|
||||
let FRAMEID = "_frameId";
|
||||
let navDepth = -1;
|
||||
let fragmentId = -1;
|
||||
let activityInitialized = false;
|
||||
|
||||
function onFragmentShown(fragment: FragmentClass) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`SHOWN ${fragment.getTag()}`, trace.categories.NativeLifecycle);
|
||||
trace.write(`SHOWN ${fragment}`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
if (fragment[CLEARING_HISTORY]) {
|
||||
if (fragment.clearHistory) {
|
||||
// This is the fragment which was at the bottom of the stack (fragment0) when we cleared history and called
|
||||
// manager.popBackStack(firstEntryName, android.app.FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
if (trace.enabled) {
|
||||
trace.write(`${fragment.getTag()} has been shown, but we are currently clearing history. Returning.`, trace.categories.NativeLifecycle);
|
||||
trace.write(`${fragment} has been shown, but it is being cleared from history. Returning.`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -51,6 +46,9 @@ function onFragmentShown(fragment: FragmentClass) {
|
||||
}
|
||||
|
||||
var isBack = currentNavigationContext ? currentNavigationContext.isBackNavigation : false;
|
||||
|
||||
transitionModule._removePageNativeViewFromAndroidParent(page);
|
||||
|
||||
frame._addView(page);
|
||||
|
||||
// onFragmentShown is called before NativeActivity.start where we call frame.onLoaded
|
||||
@@ -67,19 +65,11 @@ function onFragmentShown(fragment: FragmentClass) {
|
||||
|
||||
function onFragmentHidden(fragment: FragmentClass, destroyed: boolean) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`HIDDEN ${fragment.getTag()}`, trace.categories.NativeLifecycle);
|
||||
trace.write(`HIDDEN ${fragment}; destroyed: ${destroyed}`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
|
||||
if (fragment[CLEARING_HISTORY]) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${fragment.getTag()} has been hidden, but we are currently clearing history. Clearing any existing transitions.`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
transitionModule._clearBackwardTransitions(fragment);
|
||||
transitionModule._clearForwardTransitions(fragment);
|
||||
}
|
||||
|
||||
var isBack = fragment.entry[IS_BACK];
|
||||
fragment.entry[IS_BACK] = undefined;
|
||||
var isBack = fragment.entry.isBack;
|
||||
fragment.entry.isBack = undefined;
|
||||
|
||||
// Handle page transitions.
|
||||
transitionModule._onFragmentHidden(fragment, isBack, destroyed);
|
||||
@@ -126,9 +116,7 @@ export class Frame extends frameCommon.Frame {
|
||||
}
|
||||
|
||||
public _navigateCore(backstackEntry: definition.BackstackEntry) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this}._navigateCore(page: ${backstackEntry.resolvedPage}, backstackVisible: ${this._isEntryBackstackVisible(backstackEntry)}, clearHistory: ${backstackEntry.entry.clearHistory}), navDepth: ${navDepth}`, trace.categories.Navigation);
|
||||
}
|
||||
super._navigateCore(backstackEntry);
|
||||
|
||||
let activity = this._android.activity;
|
||||
if (!activity) {
|
||||
@@ -145,68 +133,61 @@ export class Frame extends frameCommon.Frame {
|
||||
}
|
||||
|
||||
let manager = activity.getFragmentManager();
|
||||
let isFirstNavigation = types.isNullOrUndefined(this._currentEntry);
|
||||
|
||||
backstackEntry.isNavigation = true;
|
||||
// Current Fragment
|
||||
var currentFragment: FragmentClass;
|
||||
if (this._currentEntry) {
|
||||
this._currentEntry.isNavigation = true;
|
||||
currentFragment = <FragmentClass>manager.findFragmentByTag(this._currentEntry.fragmentTag);
|
||||
}
|
||||
|
||||
// Clear history
|
||||
if (backstackEntry.entry.clearHistory) {
|
||||
let backStackEntryCount = manager.getBackStackEntryCount();
|
||||
let i = backStackEntryCount - 1;
|
||||
let fragment: android.app.Fragment;
|
||||
while (i >= 0) {
|
||||
fragment = manager.findFragmentByTag(manager.getBackStackEntryAt(i--).getName());
|
||||
if (trace.enabled) {
|
||||
trace.write(`${fragment.getTag()}[CLEARING_HISTORY] = true;`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
fragment[CLEARING_HISTORY] = true;
|
||||
}
|
||||
let clearHistory = backstackEntry.entry.clearHistory;
|
||||
|
||||
// Remember that the current fragment has never been added to the backStack, so mark it as well.
|
||||
if (this.currentPage) {
|
||||
fragment = manager.findFragmentByTag(this.currentPage[TAG]);
|
||||
if (fragment) {
|
||||
fragment[CLEARING_HISTORY] = true;
|
||||
if (trace.enabled) {
|
||||
trace.write(`${fragment.getTag()}[CLEARING_HISTORY] = true;`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (backStackEntryCount) {
|
||||
let firstEntryName = manager.getBackStackEntryAt(0).getName();
|
||||
if (trace.enabled) {
|
||||
trace.write(`manager.popBackStack(${firstEntryName}, android.app.FragmentManager.POP_BACK_STACK_INCLUSIVE);`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
manager.popBackStack(firstEntryName, android.app.FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
this._currentEntry = null;
|
||||
// New Fragment
|
||||
if (clearHistory) {
|
||||
navDepth = -1;
|
||||
}
|
||||
|
||||
navDepth++;
|
||||
|
||||
let fragmentTransaction = manager.beginTransaction();
|
||||
|
||||
var currentFragmentTag: string;
|
||||
var currentFragment: android.app.Fragment;
|
||||
if (this.currentPage) {
|
||||
currentFragmentTag = this.currentPage[TAG];
|
||||
currentFragment = manager.findFragmentByTag(currentFragmentTag);
|
||||
}
|
||||
|
||||
var newFragmentTag = "fragment" + navDepth;
|
||||
fragmentId++;
|
||||
var newFragmentTag = `fragment${fragmentId}[${navDepth}]`;
|
||||
let newFragment = new FragmentClass();
|
||||
|
||||
let args = new android.os.Bundle();
|
||||
args.putInt(FRAMEID, this._android.frameId);
|
||||
newFragment.setArguments(args);
|
||||
newFragment.frame = this;
|
||||
newFragment.entry = backstackEntry;
|
||||
|
||||
var animated = this._getIsAnimatedNavigation(backstackEntry.entry);
|
||||
var navigationTransition = this._getNavigationTransition(backstackEntry.entry);
|
||||
// backstackEntry
|
||||
backstackEntry.isNavigation = true;
|
||||
backstackEntry.fragmentTag = newFragmentTag;
|
||||
backstackEntry.navDepth = navDepth;
|
||||
|
||||
// Clear History
|
||||
let length = manager.getBackStackEntryCount();
|
||||
let emptyNativeBackStack = clearHistory && length > 0;
|
||||
if (emptyNativeBackStack) {
|
||||
for (let i = 0; i < length; i++) {
|
||||
let fragmentToRemove = <FragmentClass>manager.findFragmentByTag(manager.getBackStackEntryAt(i).getName());
|
||||
Frame._clearHistory(fragmentToRemove);
|
||||
}
|
||||
if (currentFragment) {
|
||||
Frame._clearHistory(currentFragment);
|
||||
}
|
||||
let firstEntryName = manager.getBackStackEntryAt(0).getName();
|
||||
if (trace.enabled) {
|
||||
trace.write(`POP BACK STACK ${firstEntryName}`, trace.categories.Navigation);
|
||||
}
|
||||
manager.popBackStackImmediate(firstEntryName, android.app.FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
|
||||
let fragmentTransaction = manager.beginTransaction();
|
||||
if (trace.enabled) {
|
||||
trace.write(`BEGIN TRANSACTION ${fragmentTransaction}`, trace.categories.Navigation);
|
||||
}
|
||||
|
||||
// Transitions
|
||||
let animated = this._getIsAnimatedNavigation(backstackEntry.entry);
|
||||
let navigationTransition = this._getNavigationTransition(backstackEntry.entry);
|
||||
if (currentFragment) {
|
||||
// There might be transitions left over from previous forward navigations from the current page.
|
||||
transitionModule._clearForwardTransitions(currentFragment);
|
||||
@@ -216,101 +197,89 @@ export class Frame extends frameCommon.Frame {
|
||||
}
|
||||
}
|
||||
|
||||
newFragment.frame = this;
|
||||
newFragment.entry = backstackEntry;
|
||||
|
||||
// Cahce newFragment at backstackEntry instance so that it cannot die while backstackEntry is alive.
|
||||
backstackEntry[FRAGMENT] = newFragment;
|
||||
|
||||
backstackEntry[BACKSTACK_TAG] = newFragmentTag;
|
||||
backstackEntry[NAV_DEPTH] = navDepth;
|
||||
|
||||
// remember the fragment tag at page level so that we can retrieve the fragment associated with a Page instance
|
||||
backstackEntry.resolvedPage[TAG] = newFragmentTag;
|
||||
|
||||
if (isFirstNavigation) {
|
||||
fragmentTransaction.add(this.containerViewId, newFragment, newFragmentTag);
|
||||
// Hide/remove current fragment if it exists and was not popped
|
||||
if (currentFragment && !emptyNativeBackStack) {
|
||||
if (this.android.cachePagesOnNavigate && !clearHistory) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`fragmentTransaction.add(${newFragmentTag});`, trace.categories.NativeLifecycle);
|
||||
trace.write(`\tHIDE ${currentFragment}`, trace.categories.Navigation);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.android.cachePagesOnNavigate && !backstackEntry.entry.clearHistory) {
|
||||
if (currentFragment) {
|
||||
fragmentTransaction.hide(currentFragment);
|
||||
if (trace.enabled) {
|
||||
trace.write(`fragmentTransaction.hide(${currentFragmentTag});`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (trace.enabled) {
|
||||
trace.write(`Could not find ${currentFragmentTag} to hide.`, trace.categories.NativeLifecycle);
|
||||
trace.write(`\tREMOVE ${currentFragment}`, trace.categories.Navigation);
|
||||
}
|
||||
fragmentTransaction.remove(currentFragment);
|
||||
}
|
||||
}
|
||||
|
||||
// Add newFragment
|
||||
if (trace.enabled) {
|
||||
trace.write(`\tADD ${newFragmentTag}<${newFragment.entry.resolvedPage}>`, trace.categories.Navigation);
|
||||
}
|
||||
fragmentTransaction.add(this.containerViewId, newFragment, newFragmentTag);
|
||||
if (trace.enabled) {
|
||||
trace.write(`fragmentTransaction.add(${newFragmentTag});`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fragmentTransaction.replace(this.containerViewId, newFragment, newFragmentTag);
|
||||
if (trace.enabled) {
|
||||
trace.write(`fragmentTransaction.replace(${newFragmentTag});`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
}
|
||||
|
||||
// Add to backStack if needed.
|
||||
if (this.backStack.length > 0 && this._currentEntry) {
|
||||
// addToBackStack
|
||||
if (this.backStack.length > 0 && currentFragment && !clearHistory) {
|
||||
// We add each entry in the backstack to avoid the "Stack corrupted" mismatch
|
||||
let backstackTag = this._currentEntry[BACKSTACK_TAG];
|
||||
fragmentTransaction.addToBackStack(backstackTag);
|
||||
if (trace.enabled) {
|
||||
trace.write(`fragmentTransaction.addToBackStack(${backstackTag});`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
trace.write(`\tADD TO BACK STACK ${currentFragment}`, trace.categories.Navigation);
|
||||
}
|
||||
fragmentTransaction.addToBackStack(this._currentEntry.fragmentTag);
|
||||
}
|
||||
|
||||
if (!isFirstNavigation) {
|
||||
if (currentFragment) {
|
||||
// This bug is fixed on API19+
|
||||
ensureAnimationFixed();
|
||||
let trans: number;
|
||||
if (this.android.cachePagesOnNavigate && animationFixed < 0) {
|
||||
// Apparently, there is an Android bug with when hiding fragments with animation.
|
||||
// https://code.google.com/p/android/issues/detail?id=32405
|
||||
// When bug is fixed use animated variable.
|
||||
fragmentTransaction.setTransition(android.app.FragmentTransaction.TRANSIT_NONE);
|
||||
trans = android.app.FragmentTransaction.TRANSIT_NONE;
|
||||
}
|
||||
else {
|
||||
var transit = animated ? android.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN : android.app.FragmentTransaction.TRANSIT_NONE;
|
||||
fragmentTransaction.setTransition(transit);
|
||||
trans = animated ? android.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN : android.app.FragmentTransaction.TRANSIT_NONE;
|
||||
}
|
||||
if (trace.enabled) {
|
||||
trace.write(`\tSET TRANSITION ${trans === 0 ? "NONE" : "OPEN"}`, trace.categories.Navigation);
|
||||
}
|
||||
fragmentTransaction.setTransition(trans);
|
||||
}
|
||||
|
||||
fragmentTransaction.commit();
|
||||
if (trace.enabled) {
|
||||
trace.write(`fragmentTransaction.commit();`, trace.categories.NativeLifecycle);
|
||||
trace.write(`END TRANSACTION ${fragmentTransaction}`, trace.categories.Navigation);
|
||||
}
|
||||
}
|
||||
|
||||
private static _clearHistory(fragment: FragmentClass) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`CLEAR HISTORY FOR ${fragment}`, trace.categories.Navigation);
|
||||
}
|
||||
fragment.clearHistory = true;
|
||||
transitionModule._clearBackwardTransitions(fragment);
|
||||
transitionModule._clearForwardTransitions(fragment);
|
||||
transitionModule._removePageNativeViewFromAndroidParent(fragment.entry.resolvedPage);
|
||||
}
|
||||
|
||||
public _goBackCore(backstackEntry: definition.BackstackEntry) {
|
||||
navDepth = backstackEntry[NAV_DEPTH];
|
||||
super._goBackCore(backstackEntry);
|
||||
|
||||
navDepth = backstackEntry.navDepth;
|
||||
|
||||
backstackEntry.isNavigation = true;
|
||||
if (this._currentEntry) {
|
||||
// We need this information inside onFragmentHidden
|
||||
this._currentEntry[IS_BACK] = true;
|
||||
this._currentEntry.isBack = true;
|
||||
this._currentEntry.isNavigation = true;
|
||||
}
|
||||
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this}._goBackCore(pageId: ${backstackEntry.resolvedPage.id}, backstackVisible: ${this._isEntryBackstackVisible(backstackEntry)}, clearHistory: ${backstackEntry.entry.clearHistory}), navDepth: ${navDepth}`, trace.categories.Navigation);
|
||||
}
|
||||
|
||||
var manager = this._android.activity.getFragmentManager();
|
||||
if (manager.getBackStackEntryCount() > 0) {
|
||||
// pop all other fragments up until the named one
|
||||
// this handles cases where user may navigate to an inner page without adding it on the backstack
|
||||
manager.popBackStack(backstackEntry[BACKSTACK_TAG], android.app.FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
manager.popBackStack(backstackEntry.fragmentTag, android.app.FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,11 +329,10 @@ export class Frame extends frameCommon.Frame {
|
||||
var manager = this._android.activity.getFragmentManager();
|
||||
var length = manager.getBackStackEntryCount();
|
||||
var i = length - 1;
|
||||
console.log("---------------------------");
|
||||
console.log("Fragment Manager Back Stack (" + length + ")");
|
||||
console.log(`Fragment Manager Back Stack: `);
|
||||
while (i >= 0) {
|
||||
var fragment = <any>manager.findFragmentByTag(manager.getBackStackEntryAt(i--).getName());
|
||||
console.log("[ " + fragment.getTag() + " ]");
|
||||
var fragment = manager.findFragmentByTag(manager.getBackStackEntryAt(i--).getName());
|
||||
console.log(`\t${fragment}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,7 +526,7 @@ function findPageForFragment(fragment: android.app.Fragment, frame: Frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame.currentPage && frame.currentPage[TAG] === fragmentTag) {
|
||||
if (frame._currentEntry && frame._currentEntry.fragmentTag === fragmentTag) {
|
||||
page = frame.currentPage;
|
||||
entry = frame._currentEntry;
|
||||
if (trace.enabled) {
|
||||
@@ -568,7 +536,7 @@ function findPageForFragment(fragment: android.app.Fragment, frame: Frame) {
|
||||
else {
|
||||
var backStack = frame.backStack;
|
||||
for (var i = 0; i < backStack.length; i++) {
|
||||
if (backStack[i].resolvedPage[TAG] === fragmentTag) {
|
||||
if (backStack[i].fragmentTag === fragmentTag) {
|
||||
entry = backStack[i];
|
||||
break;
|
||||
}
|
||||
@@ -584,8 +552,6 @@ function findPageForFragment(fragment: android.app.Fragment, frame: Frame) {
|
||||
if (page) {
|
||||
(<any>fragment).frame = frame;
|
||||
(<any>fragment).entry = entry;
|
||||
|
||||
page[TAG] = fragmentTag;
|
||||
}
|
||||
else {
|
||||
//throw new Error(`Could not find a page for ${fragmentTag}.`);
|
||||
@@ -625,6 +591,7 @@ function ensureAnimationFixed() {
|
||||
class FragmentClass extends android.app.Fragment {
|
||||
public frame: Frame;
|
||||
public entry: definition.BackstackEntry;
|
||||
public clearHistory: boolean;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -633,7 +600,7 @@ class FragmentClass extends android.app.Fragment {
|
||||
|
||||
public onHiddenChanged(hidden: boolean): void {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this.getTag()}.onHiddenChanged(${hidden})`, trace.categories.NativeLifecycle);
|
||||
trace.write(`${this}.onHiddenChanged(${hidden})`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
super.onHiddenChanged(hidden);
|
||||
if (hidden) {
|
||||
@@ -645,20 +612,29 @@ class FragmentClass extends android.app.Fragment {
|
||||
}
|
||||
|
||||
public onCreateAnimator(transit: number, enter: boolean, nextAnim: number): android.animation.Animator {
|
||||
var nextAnimString: string;
|
||||
switch (nextAnim) {
|
||||
case -10: nextAnimString = "enter"; break;
|
||||
case -20: nextAnimString = "exit"; break;
|
||||
case -30: nextAnimString = "popEnter"; break;
|
||||
case -40: nextAnimString = "popExit"; break;
|
||||
}
|
||||
|
||||
var animator = transitionModule._onFragmentCreateAnimator(this, nextAnim);
|
||||
|
||||
if (!animator) {
|
||||
animator = super.onCreateAnimator(transit, enter, nextAnim);
|
||||
}
|
||||
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this.getTag()}.onCreateAnimator(${transit}, ${enter}, ${nextAnim}): ${animator}`, trace.categories.NativeLifecycle);
|
||||
trace.write(`${this}.onCreateAnimator(${transit}, ${enter ? "enter" : "exit"}, ${nextAnimString}): ${animator}`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
return animator;
|
||||
}
|
||||
|
||||
public onCreate(savedInstanceState: android.os.Bundle): void {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this.getTag()}.onCreate(${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
trace.write(`${this}.onCreate(${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
super.setHasOptionsMenu(true);
|
||||
@@ -681,7 +657,7 @@ class FragmentClass extends android.app.Fragment {
|
||||
|
||||
public onCreateView(inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle): android.view.View {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this.getTag()}.onCreateView(inflater, container, ${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
trace.write(`${this}.onCreateView(inflater, container, ${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
var entry = this.entry;
|
||||
var page = entry.resolvedPage;
|
||||
@@ -698,7 +674,7 @@ class FragmentClass extends android.app.Fragment {
|
||||
|
||||
public onSaveInstanceState(outState: android.os.Bundle): void {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this.getTag()}.onSaveInstanceState(${outState})`, trace.categories.NativeLifecycle);
|
||||
trace.write(`${this}.onSaveInstanceState(${outState})`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
super.onSaveInstanceState(outState);
|
||||
if (this.isHidden()) {
|
||||
@@ -708,7 +684,7 @@ class FragmentClass extends android.app.Fragment {
|
||||
|
||||
public onDestroyView(): void {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this.getTag()}.onDestroyView()`, trace.categories.NativeLifecycle);
|
||||
trace.write(`${this}.onDestroyView()`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
super.onDestroyView();
|
||||
// Detaching the page has been move in onFragmentHidden due to transitions.
|
||||
@@ -717,10 +693,14 @@ class FragmentClass extends android.app.Fragment {
|
||||
|
||||
public onDestroy(): void {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this.getTag()}.onDestroy()`, trace.categories.NativeLifecycle);
|
||||
trace.write(`${this}.onDestroy()`, trace.categories.NativeLifecycle);
|
||||
}
|
||||
super.onDestroy();
|
||||
this.entry[FRAGMENT] = undefined;
|
||||
this.entry.fragmentTag = undefined;
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
return `${this.getTag()}<${this.entry ? this.entry.resolvedPage : ""}>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
3
ui/frame/frame.d.ts
vendored
3
ui/frame/frame.d.ts
vendored
@@ -236,6 +236,9 @@ declare module "ui/frame" {
|
||||
resolvedPage: pages.Page;
|
||||
|
||||
//@private
|
||||
navDepth: number;
|
||||
fragmentTag: string;
|
||||
isBack: boolean;
|
||||
isNavigation: boolean;
|
||||
//@endprivate
|
||||
}
|
||||
|
||||
@@ -70,9 +70,8 @@ export class Frame extends frameCommon.Frame {
|
||||
}
|
||||
|
||||
public _navigateCore(backstackEntry: definition.BackstackEntry) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this}._navigateCore(page: ${backstackEntry.resolvedPage}, backstackVisible: ${this._isEntryBackstackVisible(backstackEntry)}, clearHistory: ${backstackEntry.entry.clearHistory}), navDepth: ${navDepth}`, trace.categories.Navigation);
|
||||
}
|
||||
super._navigateCore(backstackEntry);
|
||||
|
||||
let viewController: UIViewController = backstackEntry.resolvedPage.ios;
|
||||
if (!viewController) {
|
||||
throw new Error("Required page does not have a viewController created.");
|
||||
@@ -131,7 +130,7 @@ export class Frame extends frameCommon.Frame {
|
||||
}
|
||||
|
||||
// We should hide the current entry from the back stack.
|
||||
if (!this._isEntryBackstackVisible(this._currentEntry)) {
|
||||
if (!Frame._isEntryBackstackVisible(this._currentEntry)) {
|
||||
var newControllers = NSMutableArray.alloc().initWithArray(this._ios.controller.viewControllers);
|
||||
if (newControllers.count === 0) {
|
||||
throw new Error("Wrong controllers count.");
|
||||
@@ -161,10 +160,9 @@ export class Frame extends frameCommon.Frame {
|
||||
}
|
||||
|
||||
public _goBackCore(backstackEntry: definition.BackstackEntry) {
|
||||
super._goBackCore(backstackEntry);
|
||||
|
||||
navDepth = backstackEntry[NAV_DEPTH];
|
||||
if (trace.enabled) {
|
||||
trace.write(`${this}._goBackCore(page: ${backstackEntry.resolvedPage}, backstackVisible: ${this._isEntryBackstackVisible(backstackEntry)}, clearHistory: ${backstackEntry.entry.clearHistory}), navDepth: ${navDepth}`, trace.categories.Navigation);
|
||||
}
|
||||
|
||||
if (!this._shouldSkipNativePop) {
|
||||
var controller = backstackEntry.resolvedPage.ios;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import definition = require("ui/transition");
|
||||
import platform = require("platform");
|
||||
import frameModule = require("ui/frame");
|
||||
import pageModule = require("ui/page");
|
||||
import { Transition as definitionTransition } from "ui/transition";
|
||||
import { NavigationTransition, BackstackEntry } from "ui/frame";
|
||||
import { Page} from "ui/page";
|
||||
import { getClass } from "utils/types";
|
||||
import { device } from "platform";
|
||||
import * as animationModule from "ui/animation";
|
||||
import types = require("utils/types");
|
||||
import trace = require("trace");
|
||||
import lazy from "utils/lazy";
|
||||
import trace = require("trace");
|
||||
var _sdkVersion = lazy(() => parseInt(device.sdkVersion));
|
||||
|
||||
var _sdkVersion = lazy(() => parseInt(platform.device.sdkVersion));
|
||||
var _defaultInterpolator = lazy(() => new android.view.animation.AccelerateDecelerateInterpolator());
|
||||
|
||||
interface CompleteOptions {
|
||||
@@ -15,8 +15,8 @@ interface CompleteOptions {
|
||||
}
|
||||
|
||||
interface ExpandedFragment {
|
||||
enterPopExitTransition: definition.Transition;
|
||||
exitPopEnterTransition: definition.Transition;
|
||||
enterPopExitTransition: definitionTransition;
|
||||
exitPopEnterTransition: definitionTransition;
|
||||
completePageAdditionWhenTransitionEnds: CompleteOptions;
|
||||
completePageRemovalWhenTransitionEnds: CompleteOptions;
|
||||
isDestroyed: boolean;
|
||||
@@ -38,7 +38,7 @@ export function _clearBackwardTransitions(fragment: any): void {
|
||||
var expandedFragment = <ExpandedFragment>fragment;
|
||||
if (expandedFragment.enterPopExitTransition) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`Cleared enterPopExitTransition ${expandedFragment.enterPopExitTransition} for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
trace.write(`Cleared enterPopExitTransition ${expandedFragment.enterPopExitTransition} for ${fragment}`, trace.categories.Transition);
|
||||
}
|
||||
expandedFragment.enterPopExitTransition = undefined;
|
||||
}
|
||||
@@ -47,14 +47,14 @@ export function _clearBackwardTransitions(fragment: any): void {
|
||||
var enterTransition = (<any>fragment).getEnterTransition();
|
||||
if (enterTransition) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`Cleared Enter ${enterTransition.getClass().getSimpleName()} transition for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
trace.write(`Cleared Enter ${enterTransition.getClass().getSimpleName() } transition for ${fragment}`, trace.categories.Transition);
|
||||
}
|
||||
(<any>fragment).setEnterTransition(null);
|
||||
}
|
||||
var returnTransition = (<any>fragment).getReturnTransition();
|
||||
if (returnTransition) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`Cleared Pop Exit ${returnTransition.getClass().getSimpleName()} transition for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
trace.write(`Cleared Pop Exit ${returnTransition.getClass().getSimpleName() } transition for ${fragment}`, trace.categories.Transition);
|
||||
}
|
||||
(<any>fragment).setReturnTransition(null);
|
||||
}
|
||||
@@ -65,7 +65,7 @@ export function _clearForwardTransitions(fragment: any): void {
|
||||
var expandedFragment = <ExpandedFragment>fragment;
|
||||
if (expandedFragment.exitPopEnterTransition) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`Cleared exitPopEnterTransition ${expandedFragment.exitPopEnterTransition} for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
trace.write(`Cleared exitPopEnterTransition ${expandedFragment.exitPopEnterTransition} for ${fragment}`, trace.categories.Transition);
|
||||
}
|
||||
expandedFragment.exitPopEnterTransition = undefined;
|
||||
}
|
||||
@@ -74,21 +74,21 @@ export function _clearForwardTransitions(fragment: any): void {
|
||||
var exitTransition = (<any>fragment).getExitTransition();
|
||||
if (exitTransition) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`Cleared Exit ${exitTransition.getClass().getSimpleName()} transition for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
trace.write(`Cleared Exit ${exitTransition.getClass().getSimpleName() } transition for ${fragment}`, trace.categories.Transition);
|
||||
}
|
||||
(<any>fragment).setExitTransition(null);//exit
|
||||
}
|
||||
var reenterTransition = (<any>fragment).getReenterTransition();
|
||||
if (reenterTransition) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`Cleared Pop Enter ${reenterTransition.getClass().getSimpleName()} transition for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
trace.write(`Cleared Pop Enter ${reenterTransition.getClass().getSimpleName() } transition for ${fragment}`, trace.categories.Transition);
|
||||
}
|
||||
(<any>fragment).setReenterTransition(null);//popEnter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function _setAndroidFragmentTransitions(navigationTransition: frameModule.NavigationTransition, currentFragment: any, newFragment: any, fragmentTransaction: any): void {
|
||||
export function _setAndroidFragmentTransitions(navigationTransition: NavigationTransition, currentFragment: any, newFragment: any, fragmentTransaction: any): void {
|
||||
var name;
|
||||
if (navigationTransition.name) {
|
||||
name = navigationTransition.name.toLowerCase();
|
||||
@@ -196,7 +196,7 @@ export function _setAndroidFragmentTransitions(navigationTransition: frameModule
|
||||
return;
|
||||
}
|
||||
|
||||
var transition: definition.Transition;
|
||||
var transition: definitionTransition;
|
||||
if (name) {
|
||||
if (name.indexOf("slide") === 0) {
|
||||
//HACK: Use an absolute import to work around a webpack issue that doesn't resolve relatively-imported "xxx.android/ios" modules
|
||||
@@ -221,17 +221,17 @@ export function _setAndroidFragmentTransitions(navigationTransition: frameModule
|
||||
}
|
||||
|
||||
if (transition) {
|
||||
var newexpandedFragment = <ExpandedFragment>newFragment;
|
||||
newexpandedFragment.enterPopExitTransition = transition;
|
||||
var newExpandedFragment = <ExpandedFragment>newFragment;
|
||||
newExpandedFragment.enterPopExitTransition = transition;
|
||||
if (currentFragment) {
|
||||
var currentexpandedFragment = <ExpandedFragment>currentFragment;
|
||||
currentexpandedFragment.exitPopEnterTransition = transition;
|
||||
var currentExpandedFragment = <ExpandedFragment>currentFragment;
|
||||
currentExpandedFragment.exitPopEnterTransition = transition;
|
||||
}
|
||||
fragmentTransaction.setCustomAnimations(enterFakeResourceId, exitFakeResourceId, popEnterFakeResourceId, popExitFakeResourceId);
|
||||
}
|
||||
}
|
||||
|
||||
function _setUpNativeTransition(navigationTransition: frameModule.NavigationTransition, nativeTransition: any/*android.transition.Transition*/) {
|
||||
function _setUpNativeTransition(navigationTransition: NavigationTransition, nativeTransition: any/*android.transition.Transition*/) {
|
||||
if (navigationTransition.duration) {
|
||||
nativeTransition.setDuration(navigationTransition.duration);
|
||||
}
|
||||
@@ -252,7 +252,7 @@ export function _onFragmentShown(fragment: any, isBack: boolean): void {
|
||||
var relevantTransition = isBack ? expandedFragment.exitPopEnterTransition : expandedFragment.enterPopExitTransition;
|
||||
if (relevantTransition) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${fragment.getTag() } has been shown when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${relevantTransition}. Will complete page addition when transition ends.`, trace.categories.Transition);
|
||||
trace.write(`${fragment } has been shown when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${relevantTransition}. Will complete page addition when transition ends.`, trace.categories.Transition);
|
||||
}
|
||||
expandedFragment.completePageAdditionWhenTransitionEnds = { isBack: isBack };
|
||||
}
|
||||
@@ -260,7 +260,7 @@ export function _onFragmentShown(fragment: any, isBack: boolean): void {
|
||||
var nativeTransition = isBack ? (<any>fragment).getReenterTransition() : (<any>fragment).getEnterTransition();
|
||||
if (nativeTransition) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${fragment.getTag() } has been shown when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${nativeTransition.getClass().getSimpleName()} transition. Will complete page addition when transition ends.`, trace.categories.Transition);
|
||||
trace.write(`${fragment } has been shown when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${nativeTransition.getClass().getSimpleName() } transition. Will complete page addition when transition ends.`, trace.categories.Transition);
|
||||
}
|
||||
expandedFragment.completePageAdditionWhenTransitionEnds = { isBack: isBack };
|
||||
}
|
||||
@@ -277,7 +277,7 @@ export function _onFragmentHidden(fragment: any, isBack: boolean, destroyed: boo
|
||||
var relevantTransition = isBack ? expandedFragment.enterPopExitTransition : expandedFragment.exitPopEnterTransition;
|
||||
if (relevantTransition) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${fragment.getTag()} has been hidden when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${relevantTransition}. Will complete page removal when transition ends.`, trace.categories.Transition);
|
||||
trace.write(`${fragment} has been hidden when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${relevantTransition}. Will complete page removal when transition ends.`, trace.categories.Transition);
|
||||
}
|
||||
expandedFragment.completePageRemovalWhenTransitionEnds = { isBack: isBack };
|
||||
}
|
||||
@@ -285,7 +285,7 @@ export function _onFragmentHidden(fragment: any, isBack: boolean, destroyed: boo
|
||||
var nativeTransition = isBack ? (<any>fragment).getReturnTransition() : (<any>fragment).getExitTransition();
|
||||
if (nativeTransition) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`${fragment.getTag()} has been hidden when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${nativeTransition.getClass().getSimpleName()} transition. Will complete page removal when transition ends.`, trace.categories.Transition);
|
||||
trace.write(`${fragment} has been hidden when going ${isBack ? "back" : "forward"}, but there is ${transitionType} ${nativeTransition.getClass().getSimpleName() } transition. Will complete page removal when transition ends.`, trace.categories.Transition);
|
||||
}
|
||||
expandedFragment.completePageRemovalWhenTransitionEnds = { isBack: isBack };
|
||||
}
|
||||
@@ -300,11 +300,14 @@ export function _onFragmentHidden(fragment: any, isBack: boolean, destroyed: boo
|
||||
}
|
||||
|
||||
function _completePageAddition(fragment: any, isBack: boolean) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`STARTING ADDITION of ${page}...`, trace.categories.Transition);
|
||||
}
|
||||
var expandedFragment = <ExpandedFragment>fragment;
|
||||
expandedFragment.completePageAdditionWhenTransitionEnds = undefined;
|
||||
var frame = fragment.frame;
|
||||
var entry: frameModule.BackstackEntry = fragment.entry;
|
||||
var page: pageModule.Page = entry.resolvedPage;
|
||||
var entry: BackstackEntry = fragment.entry;
|
||||
var page: Page = entry.resolvedPage;
|
||||
// The original code that was once in Frame onFragmentShown
|
||||
frame._currentEntry = entry;
|
||||
page.onNavigatedTo(isBack);
|
||||
@@ -316,11 +319,14 @@ function _completePageAddition(fragment: any, isBack: boolean) {
|
||||
}
|
||||
|
||||
function _completePageRemoval(fragment: any, isBack: boolean) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`STARTING REMOVAL of ${page}...`, trace.categories.Transition);
|
||||
}
|
||||
var expandedFragment = <ExpandedFragment>fragment;
|
||||
expandedFragment.completePageRemovalWhenTransitionEnds = undefined;
|
||||
var frame = fragment.frame;
|
||||
var entry: frameModule.BackstackEntry = fragment.entry;
|
||||
var page: pageModule.Page = entry.resolvedPage;
|
||||
var entry: BackstackEntry = fragment.entry;
|
||||
var page: Page = entry.resolvedPage;
|
||||
if (page.frame) {
|
||||
frame._removeView(page);
|
||||
// This could be undefined if activity is destroyed (e.g. without actual navigation).
|
||||
@@ -349,12 +355,25 @@ function _completePageRemoval(fragment: any, isBack: boolean) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`DETACHMENT of ${page} has already been done`, trace.categories.Transition);
|
||||
}
|
||||
_removePageNativeViewFromAndroidParent(page);
|
||||
}
|
||||
}
|
||||
|
||||
entry.isNavigation = undefined;
|
||||
}
|
||||
|
||||
export function _removePageNativeViewFromAndroidParent(page: Page): void {
|
||||
if (page._nativeView && page._nativeView.getParent) {
|
||||
var androidParent = page._nativeView.getParent();
|
||||
if (androidParent && androidParent.removeView) {
|
||||
if (trace.enabled) {
|
||||
trace.write(`REMOVED ${page}._nativeView from its Android parent`, trace.categories.Transition);
|
||||
}
|
||||
androidParent.removeView(page._nativeView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _addNativeTransitionListener(fragment: any, nativeTransition: any/*android.transition.Transition*/) {
|
||||
var expandedFragment = <ExpandedFragment>fragment;
|
||||
var transitionListener = new (<any>android).transition.Transition.TransitionListener({
|
||||
@@ -427,17 +446,17 @@ export function _onFragmentCreateAnimator(fragment: any, nextAnim: number): andr
|
||||
var transitionListener = new android.animation.Animator.AnimatorListener({
|
||||
onAnimationStart: function (animator: android.animation.Animator): void {
|
||||
if (trace.enabled) {
|
||||
trace.write(`START ${transitionType} ${transition} for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
trace.write(`START ${transitionType} ${transition} for ${fragment}`, trace.categories.Transition);
|
||||
}
|
||||
},
|
||||
onAnimationRepeat: function (animator: android.animation.Animator): void {
|
||||
if (trace.enabled) {
|
||||
trace.write(`REPEAT ${transitionType} ${transition} for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
trace.write(`REPEAT ${transitionType} ${transition} for ${fragment}`, trace.categories.Transition);
|
||||
}
|
||||
},
|
||||
onAnimationEnd: function (animator: android.animation.Animator): void {
|
||||
if (trace.enabled) {
|
||||
trace.write(`END ${transitionType} ${transition}`, trace.categories.Transition);
|
||||
trace.write(`END ${transitionType} ${transition} for ${fragment}`, trace.categories.Transition);
|
||||
}
|
||||
if (expandedFragment.completePageRemovalWhenTransitionEnds) {
|
||||
_completePageRemoval(fragment, expandedFragment.completePageRemovalWhenTransitionEnds.isBack);
|
||||
@@ -448,7 +467,7 @@ export function _onFragmentCreateAnimator(fragment: any, nextAnim: number): andr
|
||||
},
|
||||
onAnimationCancel: function (animator: android.animation.Animator): void {
|
||||
if (trace.enabled) {
|
||||
trace.write(`CANCEL ${transitionType} ${transition} for ${fragment.getTag()}`, trace.categories.Transition);
|
||||
trace.write(`CANCEL ${transitionType} ${transition} for ${fragment}`, trace.categories.Transition);
|
||||
}
|
||||
if (expandedFragment.completePageRemovalWhenTransitionEnds) {
|
||||
_completePageRemoval(fragment, expandedFragment.completePageRemovalWhenTransitionEnds.isBack);
|
||||
@@ -461,14 +480,39 @@ export function _onFragmentCreateAnimator(fragment: any, nextAnim: number): andr
|
||||
animator.addListener(transitionListener);
|
||||
}
|
||||
|
||||
if (transitionType && !animator) {
|
||||
// Happens when the transaction has setCustomAnimations, but we have cleared the transitions because of CLEARING_HISTORY
|
||||
animator = _createDummyZeroDurationAnimator();
|
||||
}
|
||||
|
||||
return animator;
|
||||
}
|
||||
|
||||
var transitionId = 0;
|
||||
export class Transition implements definition.Transition {
|
||||
let intEvaluator: android.animation.IntEvaluator;
|
||||
function ensureIntEvaluator() {
|
||||
if (!intEvaluator) {
|
||||
intEvaluator = new android.animation.IntEvaluator();
|
||||
}
|
||||
}
|
||||
|
||||
function _createDummyZeroDurationAnimator(): android.animation.Animator {
|
||||
if (trace.enabled) {
|
||||
trace.write(`_createDummyZeroDurationAnimator()`, trace.categories.Transition);
|
||||
}
|
||||
ensureIntEvaluator();
|
||||
let nativeArray = (<any>Array).create(java.lang.Object, 2);
|
||||
nativeArray[0] = java.lang.Integer.valueOf(0);
|
||||
nativeArray[1] = java.lang.Integer.valueOf(1);
|
||||
var animator = android.animation.ValueAnimator.ofObject(intEvaluator, nativeArray);
|
||||
animator.setDuration(0);
|
||||
return animator;
|
||||
}
|
||||
|
||||
export class Transition implements definitionTransition {
|
||||
private _duration: number;
|
||||
private _interpolator: android.view.animation.Interpolator;
|
||||
private _id: number;
|
||||
private static transitionId = 0;
|
||||
|
||||
constructor(duration: number, curve: any) {
|
||||
this._duration = duration;
|
||||
@@ -479,7 +523,7 @@ export class Transition implements definition.Transition {
|
||||
else {
|
||||
this._interpolator = _defaultInterpolator();
|
||||
}
|
||||
this._id = transitionId++;
|
||||
this._id = Transition.transitionId++;
|
||||
}
|
||||
|
||||
public getDuration(): number {
|
||||
@@ -499,6 +543,6 @@ export class Transition implements definition.Transition {
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
return `${types.getClass(this)}@${this._id}`;
|
||||
return `${getClass(this)}@${this._id}`;
|
||||
}
|
||||
}
|
||||
|
||||
8
ui/transition/transition.d.ts
vendored
8
ui/transition/transition.d.ts
vendored
@@ -1,5 +1,6 @@
|
||||
declare module "ui/transition" {
|
||||
import frame = require("ui/frame");
|
||||
import { NavigationTransition } from "ui/frame";
|
||||
import { Page } from "ui/page";
|
||||
|
||||
export module AndroidTransitionType {
|
||||
export var enter: string;
|
||||
@@ -20,11 +21,12 @@
|
||||
//@private
|
||||
export function _clearBackwardTransitions(fragment: any): void;
|
||||
export function _clearForwardTransitions(fragment: any): void;
|
||||
export function _setAndroidFragmentTransitions(navigationTransition: frame.NavigationTransition, currentFragment: any, newFragment: any, fragmentTransaction: any): void;
|
||||
export function _setAndroidFragmentTransitions(navigationTransition: NavigationTransition, currentFragment: any, newFragment: any, fragmentTransaction: any): void;
|
||||
export function _onFragmentCreateAnimator(fragment: any, nextAnim: number): any;
|
||||
export function _onFragmentShown(fragment: any, isBack: boolean): void;
|
||||
export function _onFragmentHidden(fragment: any, isBack: boolean, destroyed: boolean): void;
|
||||
export function _removePageNativeViewFromAndroidParent(page: Page): void;
|
||||
|
||||
export function _createIOSAnimatedTransitioning(navigationTransition: frame.NavigationTransition, nativeCurve: any, operation: number, fromVC: any, toVC: any): any;
|
||||
export function _createIOSAnimatedTransitioning(navigationTransition: NavigationTransition, nativeCurve: any, operation: number, fromVC: any, toVC: any): any;
|
||||
//@endprivate
|
||||
}
|
||||
Reference in New Issue
Block a user