mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
fix tab-view, segmented-bar, action-bar, all ViewBases (#3340)
This commit is contained in:
@@ -87,37 +87,6 @@ export class TabViewBase extends View implements TabViewDefinition, AddChildFrom
|
||||
}
|
||||
}
|
||||
|
||||
public _removeTabs(oldItems: Array<TabViewItemDefinition>) {
|
||||
for (let i = 0, length = oldItems.length; i < length; i++) {
|
||||
let oldItem = oldItems[i];
|
||||
|
||||
if (!oldItem) {
|
||||
throw new Error("TabViewItem at index " + i + " is undefined.");
|
||||
}
|
||||
|
||||
if (!oldItem.view) {
|
||||
throw new Error("TabViewItem at index " + i + " does not have a view.");
|
||||
}
|
||||
this._removeView(oldItem);
|
||||
}
|
||||
}
|
||||
|
||||
public _addTabs(newItems: Array<TabViewItemDefinition>) {
|
||||
// Validate that all items are ok before the native _addTabs code runs.
|
||||
for (let i = 0, length = newItems.length; i < length; i++) {
|
||||
let newItem = newItems[i];
|
||||
|
||||
if (!newItem) {
|
||||
throw new Error(`TabViewItem at index ${i} is undefined.`);
|
||||
}
|
||||
|
||||
if (!newItem.view) {
|
||||
throw new Error(`TabViewItem at index ${i} does not have a view.`);
|
||||
}
|
||||
this._addView(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
get _selectedView(): View {
|
||||
let selectedIndex = this.selectedIndex;
|
||||
return selectedIndex > -1 ? this.items[selectedIndex].view : null;
|
||||
@@ -131,17 +100,21 @@ export class TabViewBase extends View implements TabViewDefinition, AddChildFrom
|
||||
return 0;
|
||||
}
|
||||
|
||||
public _eachChildView(callback: (child: ViewBase) => boolean) {
|
||||
public eachChild(callback: (child: ViewBase) => boolean) {
|
||||
const items = this.items;
|
||||
if (!items) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0, length = items.length; i < length; i++) {
|
||||
let item = items[i];
|
||||
if (item) {
|
||||
if (items) {
|
||||
items.forEach((item, i) => {
|
||||
callback(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public eachChildView(callback: (child: View) => boolean) {
|
||||
const items = this.items;
|
||||
if (items) {
|
||||
items.forEach((item, i) => {
|
||||
callback(item.view);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,11 @@ const PRIMARY_COLOR = "colorPrimary";
|
||||
const DEFAULT_ELEVATION = 4;
|
||||
|
||||
export class TabViewItem extends TabViewItemBase {
|
||||
public _parent: TabView;
|
||||
|
||||
public _update() {
|
||||
if (this._parent) {
|
||||
this._parent._updateTabForItem(this);
|
||||
const parent = <TabView>this.parent;
|
||||
if (parent) {
|
||||
parent._updateTabForItem(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,9 +62,9 @@ function ensurePagerAdapterClass() {
|
||||
}
|
||||
|
||||
let item = this.items[index];
|
||||
if (item.view.parent !== this.owner) {
|
||||
this.owner._addView(item.view);
|
||||
}
|
||||
// if (item.view.parent !== this.owner) {
|
||||
// this.owner._addView(item.view);
|
||||
// }
|
||||
|
||||
if (this[VIEWS_STATES]) {
|
||||
if (traceEnabled) {
|
||||
@@ -92,9 +92,9 @@ function ensurePagerAdapterClass() {
|
||||
|
||||
// Note: this.owner._removeView will clear item.view._nativeView.
|
||||
// So call this after the native instance is removed form the container.
|
||||
if (item.view.parent === this.owner) {
|
||||
this.owner._removeView(item.view);
|
||||
}
|
||||
// if (item.view.parent === this.owner) {
|
||||
// this.owner._removeView(item.view);
|
||||
// }
|
||||
}
|
||||
|
||||
isViewFromObject(view: android.view.View, _object: any) {
|
||||
@@ -122,7 +122,8 @@ function ensurePagerAdapterClass() {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
owner._eachChildView(childCallback);
|
||||
|
||||
owner.eachChildView(childCallback);
|
||||
|
||||
let bundle = new android.os.Bundle();
|
||||
bundle.putSparseParcelableArray(VIEWS_STATES, viewStates);
|
||||
@@ -191,12 +192,12 @@ export class TabView extends TabViewBase {
|
||||
|
||||
this.setElevation();
|
||||
|
||||
let accentColor = ad.resources.getPalleteColor(ACCENT_COLOR, this._context);
|
||||
const accentColor = ad.resources.getPalleteColor(ACCENT_COLOR, this._context);
|
||||
if (accentColor) {
|
||||
this._tabLayout.setSelectedIndicatorColors([accentColor]);
|
||||
}
|
||||
|
||||
let primaryColor = ad.resources.getPalleteColor(PRIMARY_COLOR, this._context);
|
||||
const primaryColor = ad.resources.getPalleteColor(PRIMARY_COLOR, this._context);
|
||||
if (primaryColor) {
|
||||
this._tabLayout.setBackgroundColor(primaryColor);
|
||||
}
|
||||
@@ -207,7 +208,7 @@ export class TabView extends TabViewBase {
|
||||
|
||||
this._viewPager = new android.support.v4.view.ViewPager(this._context);
|
||||
this._viewPager.setId(this._androidViewId);
|
||||
let lp = new org.nativescript.widgets.CommonLayoutParams();
|
||||
const lp = new org.nativescript.widgets.CommonLayoutParams();
|
||||
lp.row = 1;
|
||||
this._viewPager.setLayoutParams(lp);
|
||||
this._grid.addView(this._viewPager);
|
||||
@@ -218,7 +219,7 @@ export class TabView extends TabViewBase {
|
||||
}
|
||||
|
||||
private setElevation() {
|
||||
let compat = <any>android.support.v4.view.ViewCompat;
|
||||
const compat = <any>android.support.v4.view.ViewCompat;
|
||||
if (compat.setElevation) {
|
||||
let val = DEFAULT_ELEVATION * layout.getDisplayDensity();
|
||||
compat.setElevation(this._grid, val);
|
||||
@@ -226,48 +227,31 @@ export class TabView extends TabViewBase {
|
||||
}
|
||||
}
|
||||
|
||||
public _onItemsPropertyChangedSetNativeValue() {
|
||||
throw new Error("Compilation error: Can't find this.previousItems");
|
||||
// let oldItems = <TabViewItem[]>this.previousItems;
|
||||
// if (oldItems) {
|
||||
// oldItems.forEach((oldItem) => {
|
||||
// // _removeView is called within destroyItem method
|
||||
// oldItem._parent = null;
|
||||
// });
|
||||
private setAdapter(items: Array<TabViewItem>) {
|
||||
const length = items ? items.length : 0;
|
||||
if (length === 0) {
|
||||
this._viewPager.setAdapter(null);
|
||||
this._pagerAdapter = null;
|
||||
this._tabLayout.setItems(null, null);
|
||||
return;
|
||||
}
|
||||
|
||||
// this._viewPager.setAdapter(null);
|
||||
// this._pagerAdapter = null;
|
||||
// this._tabLayout.setItems(null, null);
|
||||
// }
|
||||
const tabItems = new Array<org.nativescript.widgets.TabItemSpec>();
|
||||
items.forEach((item, idx, arr) => {
|
||||
tabItems.push(this.createTabItem(item));
|
||||
});
|
||||
|
||||
// let items = <TabViewItem[]>this.items;
|
||||
// if (items) {
|
||||
// let tabItems = new Array<org.nativescript.widgets.TabItemSpec>();
|
||||
// items.forEach((item, idx, arr) => {
|
||||
// if (!item.view) {
|
||||
// throw new Error("View of TabViewItem at index " + idx + " is " + item.view);
|
||||
// }
|
||||
ensurePagerAdapterClass();
|
||||
// TODO: optimize by reusing the adapter and calling setAdapter(null) then the same adapter.
|
||||
this._pagerAdapter = new PagerAdapterClass(this, items);
|
||||
this._viewPager.setAdapter(this._pagerAdapter);
|
||||
|
||||
// item._parent = this;
|
||||
// if (item.view.parent !== this) {
|
||||
// this._addView(item.view, idx);
|
||||
// }
|
||||
// tabItems.push(this.createTabItem(item));
|
||||
// });
|
||||
this._tabLayout.setItems(tabItems, this._viewPager);
|
||||
|
||||
// ensurePagerAdapterClass();
|
||||
// // TODO: optimize by reusing the adapter and calling setAdapter(null) then the same adapter.
|
||||
// this._pagerAdapter = new PagerAdapterClass(this, items);
|
||||
// this._viewPager.setAdapter(this._pagerAdapter);
|
||||
|
||||
// this._tabLayout.setItems(tabItems, this._viewPager);
|
||||
// }
|
||||
|
||||
// let nativeSelectedIndex = this._viewPager.getCurrentItem();
|
||||
// let selectedIndex = this.selectedIndex;
|
||||
// if (selectedIndex < 0) {
|
||||
// this.selectedIndex = nativeSelectedIndex;
|
||||
// }
|
||||
let selectedIndex = this.selectedIndex;
|
||||
if (selectedIndex < 0) {
|
||||
this.selectedIndex = this._viewPager.getCurrentItem();
|
||||
}
|
||||
}
|
||||
|
||||
public _updateTabForItem(item: TabViewItem) {
|
||||
@@ -320,7 +304,7 @@ export class TabView extends TabViewBase {
|
||||
return null;
|
||||
}
|
||||
set [itemsProperty.native](value: TabViewItemBase[]) {
|
||||
this._onItemsPropertyChangedSetNativeValue();
|
||||
this.setAdapter(value);
|
||||
}
|
||||
|
||||
get [tabTextColorProperty.native](): number {
|
||||
|
||||
@@ -121,23 +121,24 @@ function updateItemTitlePosition(tabBarItem: UITabBarItem): void {
|
||||
}
|
||||
|
||||
export class TabViewItem extends TabViewItemBase {
|
||||
public _controller: UIViewController;
|
||||
public _parent: TabView;
|
||||
|
||||
public _update() {
|
||||
if (this._parent && this._controller) {
|
||||
const icon = this._parent._getIcon(this.iconSource);
|
||||
const tabBarItem = UITabBarItem.alloc().initWithTitleImageTag((this.title), icon, this._parent.items.indexOf(this));
|
||||
const parent = <TabView>this.parent;
|
||||
let controller = <UIViewController>this.nativeView;
|
||||
if (parent && controller) {
|
||||
const icon = parent._getIcon(this.iconSource);
|
||||
const index = parent.items.indexOf(this);
|
||||
const tabBarItem = UITabBarItem.alloc().initWithTitleImageTag(this.title, icon, index);
|
||||
if (!icon) {
|
||||
updateItemTitlePosition(tabBarItem);
|
||||
}
|
||||
|
||||
// TODO: Repeating code. Make TabViewItemBase - ViewBase and move the colorProperty on tabViewItem.
|
||||
// Delete the repeating code.
|
||||
const states = getTitleAttributesForStates(this._parent);
|
||||
const states = getTitleAttributesForStates(parent);
|
||||
tabBarItem.setTitleTextAttributesForState(states.normalState, UIControlState.Normal);
|
||||
tabBarItem.setTitleTextAttributesForState(states.selectedState, UIControlState.Selected);
|
||||
this._controller.tabBarItem = tabBarItem;
|
||||
controller.tabBarItem = tabBarItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,47 +227,30 @@ export class TabView extends TabViewBase {
|
||||
}
|
||||
}
|
||||
|
||||
public _removeTabs(oldItems: Array<TabViewItem>) {
|
||||
if (traceEnabled) {
|
||||
traceWrite("TabView._removeTabs(" + oldItems + ");", traceCategories.Debug);
|
||||
}
|
||||
super._removeTabs(oldItems);
|
||||
|
||||
for (let i = 0, length = oldItems.length; i < length; i++) {
|
||||
let oldItem = oldItems[i];
|
||||
oldItem._parent = null;
|
||||
oldItem._controller = null;
|
||||
private setViewControllers(items: Array<TabViewItem>) {
|
||||
const length = items ? items.length : 0;
|
||||
if (length === 0) {
|
||||
this._ios.viewControllers = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this._ios.viewControllers = null;
|
||||
}
|
||||
|
||||
public _addTabs(newItems: Array<TabViewItem>) {
|
||||
if (traceEnabled) {
|
||||
traceWrite("TabView._addTabs(" + newItems + ");", traceCategories.Debug);
|
||||
}
|
||||
super._addTabs(newItems);
|
||||
|
||||
const length = newItems.length;
|
||||
const newControllers: NSMutableArray<any> = NSMutableArray.alloc().initWithCapacity(length);
|
||||
const controllers = NSMutableArray.alloc<UIViewController>().initWithCapacity(length);
|
||||
const states = getTitleAttributesForStates(this);
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
const item = <TabViewItem>newItems[i];
|
||||
const item = items[i];
|
||||
let newController: UIViewController;
|
||||
|
||||
if (item.view.ios instanceof UIViewController) {
|
||||
newController = <UIViewController>item.view.ios;
|
||||
newController = item.view.ios;
|
||||
} else {
|
||||
newController = UIViewController.new();
|
||||
newController.view.addSubview(item.view.ios);
|
||||
}
|
||||
|
||||
item._parent = this;
|
||||
item._controller = newController;
|
||||
item.nativeView = newController;
|
||||
|
||||
const icon = this._getIcon(item.iconSource);
|
||||
|
||||
const tabBarItem = UITabBarItem.alloc().initWithTitleImageTag((item.title || ""), icon, i);
|
||||
if (!icon) {
|
||||
updateItemTitlePosition(tabBarItem);
|
||||
@@ -275,17 +259,17 @@ export class TabView extends TabViewBase {
|
||||
tabBarItem.setTitleTextAttributesForState(states.selectedState, UIControlState.Selected);
|
||||
|
||||
newController.tabBarItem = tabBarItem;
|
||||
newControllers.addObject(newController);
|
||||
controllers.addObject(newController);
|
||||
}
|
||||
|
||||
this._ios.viewControllers = newControllers;
|
||||
this._ios.viewControllers = controllers;
|
||||
this._ios.customizableViewControllers = null;
|
||||
|
||||
// When we set this._ios.viewControllers, someone is clearing the moreNavigationController.delegate, so we have to reassign it each time here.
|
||||
this._ios.moreNavigationController.delegate = this._moreNavigationControllerDelegate;
|
||||
|
||||
if (this._ios.selectedIndex !== this.selectedIndex) {
|
||||
this._ios.selectedIndex = this.selectedIndex;
|
||||
if (this.selectedIndex < 0) {
|
||||
this.selectedIndex = this._ios.selectedIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,19 +383,6 @@ export class TabView extends TabViewBase {
|
||||
}
|
||||
}
|
||||
|
||||
private _onItemsPropertyChangedSetNativeValue() {
|
||||
throw new Error("Compilation error: Can't find this.previousItems");
|
||||
// let oldValue = <TabViewItem[]>this.previousItems;
|
||||
// if (oldValue) {
|
||||
// this._removeTabs(oldValue);
|
||||
// }
|
||||
|
||||
// let newValue = <TabViewItem[]>this.items;
|
||||
// if (newValue) {
|
||||
// this._addTabs(newValue);
|
||||
// }
|
||||
}
|
||||
|
||||
get [selectedIndexProperty.native](): number {
|
||||
return -1;
|
||||
}
|
||||
@@ -429,7 +400,7 @@ export class TabView extends TabViewBase {
|
||||
return null;
|
||||
}
|
||||
set [itemsProperty.native](value: TabViewItemBase[]) {
|
||||
this._onItemsPropertyChangedSetNativeValue();
|
||||
this.setViewControllers(value);
|
||||
}
|
||||
|
||||
get [tabTextColorProperty.native](): UIColor {
|
||||
@@ -479,7 +450,7 @@ export class TabView extends TabViewBase {
|
||||
let items = this.items;
|
||||
if (items && items.length) {
|
||||
for (let i = 0, length = items.length; i < length; i++) {
|
||||
const item = items[i];
|
||||
const item = items[i];
|
||||
if (items[i].iconSource) {
|
||||
(<TabViewItem>items[i])._update();
|
||||
}
|
||||
@@ -495,7 +466,7 @@ function getTitleAttributesForStates(tabView: TabView): { normalState: any, sele
|
||||
}
|
||||
|
||||
const selectedState = {};
|
||||
let tabItemTextColor = tabView.style.tabTextColor;
|
||||
let tabItemTextColor = tabView.style.tabTextColor;
|
||||
if (tabItemTextColor instanceof Color) {
|
||||
selectedState[UITextAttributeTextColor] = tabItemTextColor.ios;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user