fix(tabs): delay loadView when animation runs (#8353)

* fix(tabs): delay loadView when animation runs

* chore: update api.md

* chore: remove unnecessary casting

* test: Added disabled test for changing tabs
This commit is contained in:
Vasil Trifonov
2020-02-21 16:47:33 +02:00
committed by GitHub
parent dd11158374
commit e649a6cfd6
14 changed files with 104 additions and 10 deletions

View File

@ -772,6 +772,9 @@ export class Frame extends View {
animated: boolean;
// (undocumented)
_animationInProgress: boolean;
backStack: Array<BackstackEntry>;
canGoBack(): boolean;
@ -2931,6 +2934,7 @@ export abstract class ViewBase extends Observable {
// (undocumented)
_setupAsRootView(context: any): void;
_setupUI(context: any /* android.content.Context */, atIndex?: number): void;
_shouldDelayLoad(): boolean;
showModal(moduleName: string, modalOptions: ShowModalOptions): ViewBase;
showModal(view: ViewBase, modalOptions: ShowModalOptions): ViewBase;
public readonly style: Style;

View File

@ -0,0 +1,3 @@
<Page class="page" >
<Label text="Inner label 1" backgroundColor="blue"/>
</Page>

View File

@ -0,0 +1,3 @@
<Page class="page">
<Label text="Inner label 2" backgroundColor="red"/>
</Page>

View File

@ -0,0 +1,3 @@
<Page class="page">
<Label text="Inner label 3" backgroundColor="orange"/>
</Page>

View File

@ -0,0 +1,3 @@
<Page class="page">
<Label text="Inner label 4" backgroundColor="green"/>
</Page>

View File

@ -0,0 +1,3 @@
export function onItemTap(args) {
console.log(`Item with index: ${args.index} tapped`);
}

View File

@ -0,0 +1,24 @@
<Page class="page">
<StackLayout>
<Tabs highlightColor="red" offscreenTabLimit="1">
<TabStrip highlightColor="green" itemTap="onItemTap">
<TabStripItem title="1"></TabStripItem>
<TabStripItem title="2"></TabStripItem>
<TabStripItem title="3"></TabStripItem>
<TabStripItem title="4"></TabStripItem>
</TabStrip>
<TabContentItem>
<Frame defaultPage="tabs/frame-in-tabs-inner-page-1"></Frame>
</TabContentItem>
<TabContentItem>
<Frame defaultPage="tabs/frame-in-tabs-inner-page-2"></Frame>
</TabContentItem>
<TabContentItem>
<Frame defaultPage="tabs/frame-in-tabs-inner-page-3"></Frame>
</TabContentItem>
<TabContentItem>
<Frame defaultPage="tabs/frame-in-tabs-inner-page-4"></Frame>
</TabContentItem>
</Tabs>
</StackLayout>
</Page>

View File

@ -283,4 +283,22 @@ describe(`${imagePrefix}-suite`, async function () {
assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
await tabsViewBasePage.navigateBackToSuitMainPage();
});
// it(`${imagePrefix}-frame-in-tabs`, async function () {
// await tabsViewBasePage.navigateToSample("frame-in-tabs");
// await driver.imageHelper.compareScreen();
// // go through the tabs and check that they are loaded
// await tabsViewBasePage.tabOnItem(1);
// await driver.imageHelper.compareScreen();
// await tabsViewBasePage.tabOnItem(2);
// await driver.imageHelper.compareScreen();
// await tabsViewBasePage.tabOnItem(3);
// await driver.imageHelper.compareScreen();
// assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
// await tabsViewBasePage.navigateBackToSuitMainPage();
// });
});

View File

@ -470,6 +470,12 @@ export abstract class ViewBase extends Observable {
*/
_setupAsRootView(context: any): void;
/**
* When returning true the callLoaded method will be run in setTimeout
* Method is intended to be overridden by inheritors and used as "protected"
*/
_shouldDelayLoad(): boolean;
/**
* @private
*/

View File

@ -615,9 +615,17 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
public loadView(view: ViewBase): void {
if (view && !view.isLoaded) {
if (this._shouldDelayLoad()) {
setTimeout(() => view.callLoaded());
} else {
view.callLoaded();
}
}
}
public _shouldDelayLoad(): boolean {
return false;
}
public unloadView(view: ViewBase): void {
if (view && view.isLoaded) {

View File

@ -42,6 +42,7 @@ export class FrameBase extends CustomLayoutView implements FrameDefinition {
public actionBarVisibility: "auto" | "never" | "always";
public _currentEntry: BackstackEntry;
public _animationInProgress = false;
public _executingContext: NavigationContext;
public _isInFrameStack = false;
public static defaultAnimatedNavigation = true;

View File

@ -147,6 +147,10 @@ export class Frame extends View {
* @private
*/
navigationBarHeight: number;
/**
* @private
*/
_animationInProgress: boolean;
/**
* @private
*/

View File

@ -93,7 +93,7 @@ class UIViewControllerImpl extends UIViewController {
return;
}
const frame = this.navigationController ? (<any>this.navigationController).owner : null;
const frame = (this.navigationController ? (<any>this.navigationController).owner : null);
const newEntry = this[ENTRY];
// Don't raise event if currentPage was showing modal page.
@ -230,7 +230,6 @@ class UIViewControllerImpl extends UIViewController {
if (!page || page.modal || page._presentedViewController) {
return;
}
// Forward navigation does not remove page from frame so we raise unloaded manually.
if (page.isLoaded) {
page.callUnloaded();
@ -349,6 +348,10 @@ export class Page extends PageBase {
//
}
public _shouldDelayLoad(): boolean {
return this._frame && this._frame._animationInProgress;
}
public onLoaded(): void {
super.onLoaded();
if (this.hasActionBar) {

View File

@ -1091,7 +1091,18 @@ export class Tabs extends TabsBase {
}
this._currentNativeSelectedIndex = value;
let itemControllerOwner = null;
if (itemController._owner) {
let itemControllerOwner = <Frame>itemController._owner.get();
// do not load new views while the animation is in progress https://stackoverflow.com/a/47031524/613113
itemControllerOwner._animationInProgress = true;
}
this.viewController.setViewControllersDirectionAnimatedCompletion(controllers, navigationDirection, true, (finished: boolean) => {
if (itemControllerOwner) {
itemControllerOwner._animationInProgress = false;
}
if (finished) {
// HACK: UIPageViewController fix; see https://stackoverflow.com/a/17330606
invokeOnRunLoop(() => this.viewController.setViewControllersDirectionAnimatedCompletion(controllers, navigationDirection, false, null));