mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
fix-next(tabview): visually pre-load tab items on android (#5495)
This commit is contained in:
@@ -5,6 +5,7 @@ import * as trace from "tns-core-modules/trace";
|
||||
trace.addCategories(trace.categories.NativeLifecycle);
|
||||
trace.addCategories(trace.categories.Navigation);
|
||||
trace.addCategories(trace.categories.Transition);
|
||||
|
||||
trace.enable();
|
||||
|
||||
var countResume = 0;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as TKUnit from "../../TKUnit";
|
||||
import * as helper from "../helper";
|
||||
import { isIOS, isAndroid } from "tns-core-modules/platform";
|
||||
import { Label } from "tns-core-modules/ui/label";
|
||||
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout";
|
||||
import * as frameModule from "tns-core-modules/ui/frame";
|
||||
@@ -201,8 +202,15 @@ export function testLoadedAndUnloadedAreFired_WhenNavigatingAwayAndBack() {
|
||||
|
||||
topFrame.currentPage.id = null;
|
||||
|
||||
TKUnit.arrayAssert(loadedEventsCount, [2, 0]);
|
||||
TKUnit.arrayAssert(unloadedEventsCount, [1, 0]);
|
||||
if (isIOS) {
|
||||
TKUnit.arrayAssert(loadedEventsCount, [2, 0]);
|
||||
TKUnit.arrayAssert(unloadedEventsCount, [1, 0]);
|
||||
}
|
||||
|
||||
if (isAndroid) {
|
||||
TKUnit.arrayAssert(loadedEventsCount, [2, 2]);
|
||||
TKUnit.arrayAssert(unloadedEventsCount, [1, 1]);
|
||||
}
|
||||
}
|
||||
|
||||
function _clickTheFirstButtonInTheListViewNatively(tabView: TabView) {
|
||||
|
||||
@@ -1,81 +1,253 @@
|
||||
import * as helper from "../helper";
|
||||
import TKUnit = require("../../TKUnit");
|
||||
import { isIOS, isAndroid } from "tns-core-modules/platform";
|
||||
import { _resetRootView } from "tns-core-modules/application/";
|
||||
import { Frame, NavigationEntry } from "tns-core-modules/ui/frame";
|
||||
import { Page } from "tns-core-modules/ui/page";
|
||||
import { TabView, TabViewItem } from "tns-core-modules/ui/tab-view";
|
||||
|
||||
export function test_whenChangingTabsWithFramesCorrectEventsAreRaised() {
|
||||
const actualEventsRaised = [];
|
||||
|
||||
function attachPageEventHandlers(page: Page) {
|
||||
page.on(Page.loadedEvent, () => actualEventsRaised.push(`${page.id} loaded`));
|
||||
page.on(Page.unloadedEvent, () => actualEventsRaised.push(`${page.id} unloaded`));
|
||||
page.on(Page.navigatingToEvent, () => actualEventsRaised.push(`${page.id} navigatingTo`));
|
||||
page.on(Page.navigatingFromEvent, () => actualEventsRaised.push(`${page.id} navigatingFrom`));
|
||||
page.on(Page.navigatedToEvent, () => actualEventsRaised.push(`${page.id} navigatedTo`));
|
||||
page.on(Page.navigatedFromEvent, () => actualEventsRaised.push(`${page.id} navigatedFrom`));
|
||||
function waitUntilNavigatedTo(pages: Page[], action: Function) {
|
||||
let completed = 0;
|
||||
function navigatedTo(args) {
|
||||
args.object.page.off("navigatedTo", navigatedTo);
|
||||
completed++;
|
||||
}
|
||||
|
||||
function attachFrameEventHandlers(frame: Frame) {
|
||||
frame.on(Frame.loadedEvent, () => actualEventsRaised.push(`${frame.id} loaded`));
|
||||
frame.on(Frame.unloadedEvent, () => actualEventsRaised.push(`${frame.id} unloaded`));
|
||||
pages.forEach(page => page.on("navigatedTo", navigatedTo));
|
||||
action();
|
||||
TKUnit.waitUntilReady(() => completed === pages.length, 100);
|
||||
}
|
||||
|
||||
function createPage(i: number) {
|
||||
const page = new Page();
|
||||
page.id = `Tab${i} Frame${i} Page${i}`;
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
function createFrame(i: number, page: Page) {
|
||||
const frame = new Frame();
|
||||
frame.navigate(() => page);
|
||||
frame.id = `Tab${i} Frame${i}`;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
function createTabItem(i: number, frame: Frame) {
|
||||
const tabEntry = new TabViewItem();
|
||||
tabEntry.title = "Tab " + i;
|
||||
tabEntry.view = frame;
|
||||
tabEntry["index"] = i;
|
||||
|
||||
return tabEntry;
|
||||
}
|
||||
|
||||
function createTabItemsWithFrames(count: number) {
|
||||
const items = [];
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
const page = createPage(i);
|
||||
const frame = createFrame(i, page);
|
||||
const tabItem = createTabItem(i, frame);
|
||||
|
||||
items.push({ page, frame, tabItem });
|
||||
}
|
||||
|
||||
const page1 = new Page();
|
||||
page1.id = "Tab1 Frame1 Page1";
|
||||
attachPageEventHandlers(page1);
|
||||
return items;
|
||||
}
|
||||
|
||||
const frame1 = new Frame();
|
||||
frame1.navigate(() => page1);
|
||||
frame1.id = "Tab1 Frame1";
|
||||
attachFrameEventHandlers(frame1);
|
||||
export function test_ios_and_android_offset_zero_should_raise_same_events() {
|
||||
let actualEventsRaised = [];
|
||||
|
||||
const page2 = new Page();
|
||||
page2.id = "Tab2 Frame2 Page2";
|
||||
attachPageEventHandlers(page2);
|
||||
function resetActualEventsRaised() {
|
||||
for (var i = 0; i < actualEventsRaised.length; i++) {
|
||||
actualEventsRaised[i] = [];
|
||||
}
|
||||
}
|
||||
|
||||
const frame2 = new Frame();
|
||||
frame2.navigate(() => page2);
|
||||
frame2.id = "Tab2 Frame2";
|
||||
attachFrameEventHandlers(frame2);
|
||||
function attachEventHandlers(i: number, item) {
|
||||
actualEventsRaised.push([]);
|
||||
|
||||
const page = item.page;
|
||||
page.on(Page.loadedEvent, () => actualEventsRaised[i].push(`${page.id} loaded`));
|
||||
page.on(Page.unloadedEvent, () => actualEventsRaised[i].push(`${page.id} unloaded`));
|
||||
page.on(Page.navigatingToEvent, () => actualEventsRaised[i].push(`${page.id} navigatingTo`));
|
||||
page.on(Page.navigatingFromEvent, () => actualEventsRaised[i].push(`${page.id} navigatingFrom`));
|
||||
page.on(Page.navigatedToEvent, () => actualEventsRaised[i].push(`${page.id} navigatedTo`));
|
||||
page.on(Page.navigatedFromEvent, () => actualEventsRaised[i].push(`${page.id} navigatedFrom`));
|
||||
|
||||
const frame = item.frame;
|
||||
frame.on(Frame.loadedEvent, () => actualEventsRaised[i].push(`${frame.id} loaded`));
|
||||
frame.on(Frame.unloadedEvent, () => actualEventsRaised[i].push(`${frame.id} unloaded`));
|
||||
}
|
||||
|
||||
const items = createTabItemsWithFrames(3);
|
||||
|
||||
items.forEach((item, i) => {
|
||||
attachEventHandlers(i, item);
|
||||
});
|
||||
|
||||
const tabView = new TabView();
|
||||
const tabEntry1 = new TabViewItem();
|
||||
tabEntry1.title = "frame1";
|
||||
tabEntry1.view = frame1;
|
||||
const tabEntry2 = new TabViewItem();
|
||||
tabEntry2.title = "frame2";
|
||||
tabEntry2.view = frame2;
|
||||
tabView.items = [tabEntry1, tabEntry2];
|
||||
tabView.items = items.map(item => item.tabItem);
|
||||
|
||||
// iOS cannot preload tab items
|
||||
// Android preloads 1 tab item to the sides by default
|
||||
// set this to 0, so that both platforms behave the same.
|
||||
tabView.androidOffscreenTabLimit = 0;
|
||||
|
||||
const entry: NavigationEntry = {
|
||||
create: () => tabView
|
||||
};
|
||||
|
||||
helper.waitUntilNavigatedTo(page1, () => _resetRootView(entry));
|
||||
helper.waitUntilNavigatedTo(page2, () => tabView.selectedIndex = 1);
|
||||
tabView.selectedIndex = 0;
|
||||
TKUnit.waitUntilReady(() => page1.isLoaded);
|
||||
helper.waitUntilNavigatedTo(items[0].page, () => _resetRootView(entry));
|
||||
|
||||
const expectedEventsRaised = [
|
||||
"Tab1 Frame1 loaded",
|
||||
"Tab1 Frame1 Page1 navigatingTo",
|
||||
"Tab1 Frame1 Page1 loaded",
|
||||
"Tab1 Frame1 Page1 navigatedTo",
|
||||
"Tab1 Frame1 Page1 unloaded",
|
||||
"Tab1 Frame1 unloaded",
|
||||
"Tab2 Frame2 loaded",
|
||||
"Tab2 Frame2 Page2 navigatingTo",
|
||||
"Tab2 Frame2 Page2 loaded",
|
||||
"Tab2 Frame2 Page2 navigatedTo",
|
||||
"Tab2 Frame2 Page2 unloaded",
|
||||
"Tab2 Frame2 unloaded",
|
||||
"Tab1 Frame1 Page1 loaded",
|
||||
"Tab1 Frame1 loaded"
|
||||
const expectedEventsRaisedAfterTabCreated = [
|
||||
[
|
||||
"Tab0 Frame0 loaded",
|
||||
"Tab0 Frame0 Page0 navigatingTo",
|
||||
"Tab0 Frame0 Page0 loaded",
|
||||
"Tab0 Frame0 Page0 navigatedTo",
|
||||
],
|
||||
[],
|
||||
[]
|
||||
];
|
||||
|
||||
TKUnit.arrayAssert(actualEventsRaised, expectedEventsRaised);
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterTabCreated);
|
||||
|
||||
resetActualEventsRaised();
|
||||
helper.waitUntilNavigatedTo(items[2].page, () => tabView.selectedIndex = 2);
|
||||
|
||||
const expectedEventsRaisedAfterSelectThirdTab = [
|
||||
[
|
||||
"Tab0 Frame0 Page0 unloaded",
|
||||
"Tab0 Frame0 unloaded",
|
||||
],
|
||||
[],
|
||||
[
|
||||
"Tab2 Frame2 loaded",
|
||||
"Tab2 Frame2 Page2 navigatingTo",
|
||||
"Tab2 Frame2 Page2 loaded",
|
||||
"Tab2 Frame2 Page2 navigatedTo"
|
||||
]
|
||||
];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterSelectThirdTab);
|
||||
|
||||
resetActualEventsRaised();
|
||||
tabView.selectedIndex = 0;
|
||||
TKUnit.waitUntilReady(() => items[0].page.isLoaded);
|
||||
|
||||
const expectedEventsRaisedAfterReturnToFirstTab = [
|
||||
[
|
||||
"Tab0 Frame0 Page0 loaded",
|
||||
"Tab0 Frame0 loaded",
|
||||
],
|
||||
[],
|
||||
[
|
||||
"Tab2 Frame2 Page2 unloaded",
|
||||
"Tab2 Frame2 unloaded",
|
||||
]
|
||||
];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterReturnToFirstTab);
|
||||
}
|
||||
|
||||
export function test_android_default_offset_should_preload_1_tab_on_each_side() {
|
||||
let actualEventsRaised = [];
|
||||
|
||||
function resetActualEventsRaised() {
|
||||
for (var i = 0; i < actualEventsRaised.length; i++) {
|
||||
actualEventsRaised[i] = [];
|
||||
}
|
||||
}
|
||||
|
||||
function attachEventHandlers(i: number, item) {
|
||||
actualEventsRaised.push([]);
|
||||
|
||||
const page = item.page;
|
||||
page.on(Page.loadedEvent, () => actualEventsRaised[i].push(`${page.id} loaded`));
|
||||
page.on(Page.unloadedEvent, () => actualEventsRaised[i].push(`${page.id} unloaded`));
|
||||
page.on(Page.navigatingToEvent, () => actualEventsRaised[i].push(`${page.id} navigatingTo`));
|
||||
page.on(Page.navigatingFromEvent, () => actualEventsRaised[i].push(`${page.id} navigatingFrom`));
|
||||
page.on(Page.navigatedToEvent, () => actualEventsRaised[i].push(`${page.id} navigatedTo`));
|
||||
page.on(Page.navigatedFromEvent, () => actualEventsRaised[i].push(`${page.id} navigatedFrom`));
|
||||
|
||||
const frame = item.frame;
|
||||
frame.on(Frame.loadedEvent, () => actualEventsRaised[i].push(`${frame.id} loaded`));
|
||||
frame.on(Frame.unloadedEvent, () => actualEventsRaised[i].push(`${frame.id} unloaded`));
|
||||
}
|
||||
|
||||
if (isAndroid) {
|
||||
const items = createTabItemsWithFrames(3);
|
||||
|
||||
items.forEach((item, i) => {
|
||||
attachEventHandlers(i, item);
|
||||
});
|
||||
|
||||
const tabView = new TabView();
|
||||
tabView.items = items.map(item => item.tabItem);
|
||||
|
||||
const entry: NavigationEntry = {
|
||||
create: () => tabView
|
||||
};
|
||||
|
||||
waitUntilNavigatedTo([items[0].page, items[1].page], () => _resetRootView(entry));
|
||||
|
||||
const expectedEventsRaisedAfterTabCreated = [
|
||||
[
|
||||
"Tab0 Frame0 loaded",
|
||||
"Tab0 Frame0 Page0 navigatingTo",
|
||||
"Tab0 Frame0 Page0 loaded",
|
||||
"Tab0 Frame0 Page0 navigatedTo",
|
||||
],
|
||||
[
|
||||
"Tab1 Frame1 loaded",
|
||||
"Tab1 Frame1 Page1 navigatingTo",
|
||||
"Tab1 Frame1 Page1 loaded",
|
||||
"Tab1 Frame1 Page1 navigatedTo",
|
||||
],
|
||||
[]
|
||||
];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterTabCreated);
|
||||
|
||||
resetActualEventsRaised();
|
||||
helper.waitUntilNavigatedTo(items[2].page, () => tabView.selectedIndex = 2);
|
||||
|
||||
const expectedEventsRaisedAfterSelectThirdTab = [
|
||||
[
|
||||
"Tab0 Frame0 Page0 unloaded",
|
||||
"Tab0 Frame0 unloaded",
|
||||
],
|
||||
[],
|
||||
[
|
||||
"Tab2 Frame2 loaded",
|
||||
"Tab2 Frame2 Page2 navigatingTo",
|
||||
"Tab2 Frame2 Page2 loaded",
|
||||
"Tab2 Frame2 Page2 navigatedTo"
|
||||
]
|
||||
];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterSelectThirdTab);
|
||||
|
||||
resetActualEventsRaised();
|
||||
tabView.selectedIndex = 0;
|
||||
TKUnit.waitUntilReady(() => items[0].page.isLoaded);
|
||||
|
||||
const expectedEventsRaisedAfterReturnToFirstTab = [
|
||||
[
|
||||
"Tab0 Frame0 Page0 loaded",
|
||||
"Tab0 Frame0 loaded",
|
||||
],
|
||||
[],
|
||||
[
|
||||
"Tab2 Frame2 Page2 unloaded",
|
||||
"Tab2 Frame2 unloaded",
|
||||
]
|
||||
];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterReturnToFirstTab);
|
||||
}
|
||||
}
|
||||
|
||||
export function tearDownModule() {
|
||||
|
||||
@@ -176,6 +176,18 @@ export class Frame extends FrameBase {
|
||||
}
|
||||
}
|
||||
|
||||
onUnloaded() {
|
||||
if (this._currentEntry && this._currentEntry.fragment) {
|
||||
const manager: android.app.FragmentManager = this._getFragmentManager();
|
||||
|
||||
const transaction = manager.beginTransaction();
|
||||
transaction.remove(this._currentEntry.fragment);
|
||||
transaction.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
super.onUnloaded();
|
||||
}
|
||||
|
||||
private createFragment(backstackEntry: BackstackEntry, fragmentTag: string): android.app.Fragment {
|
||||
ensureFragmentClass();
|
||||
const newFragment = new fragmentClass();
|
||||
@@ -569,7 +581,8 @@ function findPageForFragment(fragment: android.app.Fragment, frame: Frame) {
|
||||
callbacks.entry = entry;
|
||||
entry.fragment = fragment;
|
||||
_updateTransitions(entry);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new Error(`Could not find a page for ${fragmentTag}.`);
|
||||
}
|
||||
}
|
||||
@@ -697,13 +710,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
this.frame._addView(page);
|
||||
}
|
||||
|
||||
// Load page here even if root view is not loaded yet.
|
||||
// Otherwise it will show as blank,
|
||||
// The case is Tab->Frame->Page activity recreated, fragments are
|
||||
// created before Tab loads its items.
|
||||
// TODO: addCheck if the fragment is visible so we don't load pages
|
||||
// that are not in the selectedIndex of the Tab!!!!!!
|
||||
if (!page.isLoaded) {
|
||||
if (frame.isLoaded && !page.isLoaded) {
|
||||
page.callLoaded();
|
||||
}
|
||||
|
||||
|
||||
@@ -71,9 +71,8 @@ export abstract class TabViewItemBase extends ViewBase implements TabViewItemDef
|
||||
public loadView(view: ViewBase): void {
|
||||
const tabView = this.parent as TabViewBase;
|
||||
if (tabView && tabView.items) {
|
||||
const index = tabView.items.indexOf(this);
|
||||
// Don't load items until their fragments are instantiated.
|
||||
if (index === tabView.selectedIndex && (<TabViewItemDefinition>this).canBeLoaded) {
|
||||
if ((<TabViewItemDefinition>this).canBeLoaded) {
|
||||
super.loadView(view);
|
||||
}
|
||||
}
|
||||
@@ -185,21 +184,7 @@ export class TabViewBase extends View implements TabViewDefinition, AddChildFrom
|
||||
}
|
||||
|
||||
public onSelectedIndexChanged(oldIndex: number, newIndex: number): void {
|
||||
const items = this.items;
|
||||
if (!items) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldItem = items[oldIndex];
|
||||
if (oldItem) {
|
||||
oldItem.unloadView(oldItem.view);
|
||||
}
|
||||
|
||||
const newItem = items[newIndex];
|
||||
if (newItem && this.isLoaded) {
|
||||
newItem.loadView(newItem.view);
|
||||
}
|
||||
|
||||
// to be overridden in platform specific files
|
||||
this.notify(<SelectedIndexChangedEventData>{ eventName: TabViewBase.selectedIndexChangedEvent, object: this, oldIndex, newIndex });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
TabViewBase, TabViewItemBase, itemsProperty, selectedIndexProperty,
|
||||
tabTextColorProperty, tabBackgroundColorProperty, selectedTabTextColorProperty,
|
||||
androidSelectedTabHighlightColorProperty, androidOffscreenTabLimitProperty,
|
||||
fontSizeProperty, fontInternalProperty, View, layout, traceCategory, traceEnabled,
|
||||
fontSizeProperty, fontInternalProperty, View, layout, traceCategory, traceEnabled,
|
||||
traceWrite, Color
|
||||
} from "./tab-view-common"
|
||||
import { textTransformProperty, TextTransform, getTransformedText } from "../text-base";
|
||||
@@ -55,6 +55,7 @@ function initializeNativeClasses() {
|
||||
}
|
||||
|
||||
static newInstance(tabId: number, index: number): TabFragmentImplementation {
|
||||
|
||||
const args = new android.os.Bundle();
|
||||
args.putInt(TABID, tabId);
|
||||
args.putInt(INDEX, index);
|
||||
@@ -74,7 +75,13 @@ function initializeNativeClasses() {
|
||||
}
|
||||
|
||||
public onCreateView(inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle): android.view.View {
|
||||
return this.tab.items[this.index].view.nativeViewProtected;
|
||||
const tabItem = this.tab.items[this.index];
|
||||
|
||||
return tabItem.view.nativeViewProtected;
|
||||
}
|
||||
|
||||
public onDestroyView() {
|
||||
super.onDestroyView();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +162,10 @@ function initializeNativeClasses() {
|
||||
const fragment: android.app.Fragment = <android.app.Fragment>object;
|
||||
this.mCurTransaction.detach(fragment);
|
||||
|
||||
if (this.mCurrentPrimaryItem === fragment) {
|
||||
this.mCurrentPrimaryItem = null;
|
||||
}
|
||||
|
||||
const tabItems = this.owner.items;
|
||||
const tabItem = tabItems ? tabItems[position] : null;
|
||||
if (tabItem) {
|
||||
@@ -177,13 +188,14 @@ function initializeNativeClasses() {
|
||||
|
||||
this.mCurrentPrimaryItem = fragment;
|
||||
this.owner.selectedIndex = position;
|
||||
}
|
||||
|
||||
const tab = this.owner;
|
||||
const tabItems = tab.items;
|
||||
const newTabItem = tabItems ? tabItems[position] : null;
|
||||
if (newTabItem && tab.isLoaded) {
|
||||
newTabItem.loadView(newTabItem.view);
|
||||
const tab = this.owner;
|
||||
const tabItems = tab.items;
|
||||
const newTabItem = tabItems ? tabItems[position] : null;
|
||||
|
||||
if (newTabItem) {
|
||||
tab._loadUnloadTabItems(tab.selectedIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,6 +348,14 @@ function setElevation(grid: org.nativescript.widgets.GridLayout, tabLayout: org.
|
||||
|
||||
export const tabs = new Array<WeakRef<TabView>>();
|
||||
|
||||
function iterateIndexRange(index: number, eps: number, lastIndex: number, callback: (i) => void) {
|
||||
const rangeStart = Math.max(0, index - eps);
|
||||
const rangeEnd = Math.min(index + eps, lastIndex);
|
||||
for (let i = rangeStart; i <= rangeEnd; i++) {
|
||||
callback(i);
|
||||
}
|
||||
}
|
||||
|
||||
export class TabView extends TabViewBase {
|
||||
private _tabLayout: org.nativescript.widgets.TabLayout;
|
||||
private _viewPager: android.support.v4.view.ViewPager;
|
||||
@@ -429,6 +449,38 @@ export class TabView extends TabViewBase {
|
||||
(<any>this._pagerAdapter).owner = this;
|
||||
}
|
||||
|
||||
public _loadUnloadTabItems(newIndex: number) {
|
||||
const items = this.items;
|
||||
const lastIndex = this.items.length - 1;
|
||||
const offsideItems = this.androidTabsPosition === "top" ? this.androidOffscreenTabLimit : 0;
|
||||
|
||||
let toUnload = [];
|
||||
let toLoad = [];
|
||||
|
||||
iterateIndexRange(newIndex, offsideItems, lastIndex, (i) => toLoad.push(i));
|
||||
|
||||
items.forEach((item, i) => {
|
||||
const indexOfI = toLoad.indexOf(i);
|
||||
if (indexOfI < 0) {
|
||||
toUnload.push(i);
|
||||
}
|
||||
});
|
||||
|
||||
toUnload.forEach(index => {
|
||||
const item = items[index];
|
||||
if (items[index]) {
|
||||
item.unloadView(item.view);
|
||||
}
|
||||
});
|
||||
|
||||
toLoad.forEach(index => {
|
||||
const item = items[index];
|
||||
if (this.isLoaded && items[index]) {
|
||||
item.loadView(item.view);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public onLoaded(): void {
|
||||
super.onLoaded();
|
||||
|
||||
@@ -464,7 +516,7 @@ export class TabView extends TabViewBase {
|
||||
if (!this._pagerAdapter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const currentPagerAdapterItems = (<any>this._pagerAdapter).items;
|
||||
|
||||
// if both values are null, should not update
|
||||
@@ -483,7 +535,7 @@ export class TabView extends TabViewBase {
|
||||
}
|
||||
|
||||
const matchingItems = currentPagerAdapterItems.filter((currentItem) => {
|
||||
return !!items.filter((item) => {
|
||||
return !!items.filter((item) => {
|
||||
return item._domId === currentItem._domId
|
||||
})[0];
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { TabViewItem as TabViewItemDefinition } from ".";
|
||||
import { Font } from "../styling/font";
|
||||
|
||||
import { ios as iosView } from "../core/view";
|
||||
import { ios as iosView, ViewBase } from "../core/view";
|
||||
import {
|
||||
TabViewBase, TabViewItemBase, itemsProperty, selectedIndexProperty,
|
||||
tabTextColorProperty, tabBackgroundColorProperty, selectedTabTextColorProperty, iosIconRenderingModeProperty,
|
||||
@@ -158,6 +158,17 @@ export class TabViewItem extends TabViewItemBase {
|
||||
this.setNativeView(undefined);
|
||||
}
|
||||
|
||||
public loadView(view: ViewBase): void {
|
||||
const tabView = this.parent as TabViewBase;
|
||||
if (tabView && tabView.items) {
|
||||
const index = tabView.items.indexOf(this);
|
||||
|
||||
if (index === tabView.selectedIndex) {
|
||||
super.loadView(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public _update() {
|
||||
const parent = <TabView>this.parent;
|
||||
const controller = this.__controller;
|
||||
@@ -229,6 +240,25 @@ export class TabView extends TabViewBase {
|
||||
//
|
||||
}
|
||||
|
||||
public onSelectedIndexChanged(oldIndex: number, newIndex: number): void {
|
||||
const items = this.items;
|
||||
if (!items) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldItem = items[oldIndex];
|
||||
if (oldItem) {
|
||||
oldItem.unloadView(oldItem.view);
|
||||
}
|
||||
|
||||
const newItem = items[newIndex];
|
||||
if (newItem && this.isLoaded) {
|
||||
newItem.loadView(newItem.view);
|
||||
}
|
||||
|
||||
super.onSelectedIndexChanged(oldIndex, newIndex);
|
||||
}
|
||||
|
||||
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
||||
const width = layout.getMeasureSpecSize(widthMeasureSpec);
|
||||
const widthMode = layout.getMeasureSpecMode(widthMeasureSpec);
|
||||
|
||||
Reference in New Issue
Block a user