UNPKG

@nativescript/core

Version:

A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.

286 lines • 11.8 kB
import { Font } from '../styling/font'; import { SegmentedBarItemBase, SegmentedBarBase, selectedIndexProperty, itemsProperty, selectedBackgroundColorProperty } from './segmented-bar-common'; import { AndroidHelper, isEnabledProperty } from '../core/view'; import { colorProperty, fontInternalProperty, fontSizeProperty } from '../styling/style-properties'; import { Color } from '../../color'; import { layout } from '../../utils'; import { SDK_VERSION } from '../../utils/constants'; import { Trace } from '../../trace'; export * from './segmented-bar-common'; const R_ID_TABS = 0x01020013; const R_ID_TABCONTENT = 0x01020011; const R_ATTR_STATE_SELECTED = 0x010100a1; const TITLE_TEXT_VIEW_ID = 16908310; // http://developer.android.com/reference/android/R.id.html#title let selectedIndicatorThickness; let TabHost; let TabChangeListener; let TabContentFactory; // TODO: All TabHost public methods become deprecated in API 30. function initializeNativeClasses() { if (TabChangeListener) { return; } // Indicator thickness for material - 2dip. For pre-material - 5dip. selectedIndicatorThickness = layout.toDevicePixels(SDK_VERSION >= 21 ? 2 : 5); var TabChangeListenerImpl = /** @class */ (function (_super) { __extends(TabChangeListenerImpl, _super); function TabChangeListenerImpl(owner) { var _this = _super.call(this) || this; _this.owner = owner; return global.__native(_this); } TabChangeListenerImpl.prototype.onTabChanged = function (id) { var owner = this.owner; if (owner) { setTimeout(function () { owner.setTabColor(id); }); if (owner.shouldChangeSelectedIndex()) { owner.selectedIndex = parseInt(id); } } }; var _a; TabChangeListenerImpl = __decorate([ Interfaces([android.widget.TabHost.OnTabChangeListener]), __metadata("design:paramtypes", [typeof (_a = typeof SegmentedBar !== "undefined" && SegmentedBar) === "function" ? _a : Object]) ], TabChangeListenerImpl); return TabChangeListenerImpl; }(java.lang.Object)); var TabContentFactoryImpl = /** @class */ (function (_super) { __extends(TabContentFactoryImpl, _super); function TabContentFactoryImpl(owner) { var _this = _super.call(this) || this; _this.owner = owner; return global.__native(_this); } TabContentFactoryImpl.prototype.createTabContent = function (tag) { var tv = new android.widget.TextView(this.owner._context); // This is collapsed by default and made visible // by android when TabItem becomes visible/selected. // TODO: Try commenting visibility change. tv.setVisibility(android.view.View.GONE); tv.setMaxLines(1); tv.setEllipsize(android.text.TextUtils.TruncateAt.END); return tv; }; var _a; TabContentFactoryImpl = __decorate([ Interfaces([android.widget.TabHost.TabContentFactory]), __metadata("design:paramtypes", [typeof (_a = typeof SegmentedBar !== "undefined" && SegmentedBar) === "function" ? _a : Object]) ], TabContentFactoryImpl); return TabContentFactoryImpl; }(java.lang.Object)); var TabHostImpl = /** @class */ (function (_super) { __extends(TabHostImpl, _super); function TabHostImpl(context, attrs) { var _this = _super.call(this, context, attrs) || this; return global.__native(_this); } TabHostImpl.prototype.onAttachedToWindow = function () { // overriden to remove the code that will steal the focus from edit fields. }; return TabHostImpl; }(android.widget.TabHost)); TabHost = TabHostImpl; TabChangeListener = TabChangeListenerImpl; TabContentFactory = TabContentFactoryImpl; } export class SegmentedBarItem extends SegmentedBarItemBase { setupNativeView(tabIndex) { // TabHost.TabSpec.setIndicator DOES NOT WORK once the title has been set. // http://stackoverflow.com/questions/2935781/modify-tab-indicator-dynamically-in-android const titleTextView = this.parent.nativeViewProtected.getTabWidget().getChildAt(tabIndex).findViewById(TITLE_TEXT_VIEW_ID); this.setNativeView(titleTextView); if (titleTextView) { if (this.titleDirty) { this._update(); } } } _update() { const tv = this.nativeViewProtected; if (tv) { let title = this.title; title = title === null || title === undefined ? '' : title; tv.setText(title); this.titleDirty = false; } else { this.titleDirty = true; } } [colorProperty.getDefault]() { return this.nativeViewProtected.getCurrentTextColor(); } [colorProperty.setNative](value) { const color = value instanceof Color ? value.android : value; this.nativeViewProtected.setTextColor(color); } [fontSizeProperty.getDefault]() { return { nativeSize: this.nativeViewProtected.getTextSize() }; } [fontSizeProperty.setNative](value) { if (typeof value === 'number') { this.nativeViewProtected.setTextSize(value); } else { this.nativeViewProtected.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, value.nativeSize); } } [fontInternalProperty.getDefault]() { return this.nativeViewProtected.getTypeface(); } [fontInternalProperty.setNative](value) { this.nativeViewProtected.setTypeface(value instanceof Font ? value.getAndroidTypeface() : value); } [selectedBackgroundColorProperty.getDefault]() { const viewGroup = this.nativeViewProtected.getParent(); return viewGroup.getBackground(); } [selectedBackgroundColorProperty.setNative](value) { const nativeView = this.nativeViewProtected; const viewGroup = nativeView.getParent(); if (value instanceof Color) { const color = value.android; const backgroundDrawable = viewGroup.getBackground(); if (SDK_VERSION > 21 && backgroundDrawable) { const newDrawable = AndroidHelper.getCopyOrDrawable(backgroundDrawable, nativeView.getResources()); AndroidHelper.setDrawableColor(color, newDrawable); viewGroup.setBackground(newDrawable); } else { const stateDrawable = new android.graphics.drawable.StateListDrawable(); const colorDrawable = new org.nativescript.widgets.SegmentedBarColorDrawable(color, selectedIndicatorThickness); const arr = Array.create('int', 1); arr[0] = R_ATTR_STATE_SELECTED; stateDrawable.addState(arr, colorDrawable); stateDrawable.setBounds(0, 15, viewGroup.getRight(), viewGroup.getBottom()); viewGroup.setBackground(stateDrawable); } } else { const backgroundDrawable = AndroidHelper.getCopyOrDrawable(value, nativeView.getResources()); viewGroup.setBackground(backgroundDrawable); } } } export class SegmentedBar extends SegmentedBarBase { shouldChangeSelectedIndex() { return !this._addingTab; } createNativeView() { initializeNativeClasses(); const context = this._context; const nativeView = new TabHost(context, null); const tabHostLayout = new android.widget.LinearLayout(context); tabHostLayout.setOrientation(android.widget.LinearLayout.VERTICAL); const tabWidget = new android.widget.TabWidget(context); tabWidget.setId(R_ID_TABS); tabHostLayout.addView(tabWidget); const frame = new android.widget.FrameLayout(context); frame.setId(R_ID_TABCONTENT); frame.setVisibility(android.view.View.GONE); tabHostLayout.addView(frame); nativeView.addView(tabHostLayout); return nativeView; } initNativeView() { super.initNativeView(); const nativeView = this.nativeViewProtected; const listener = new TabChangeListener(this); nativeView.setOnTabChangedListener(listener); nativeView.listener = listener; nativeView.setup(); this._tabContentFactory = this._tabContentFactory || new TabContentFactory(this); } disposeNativeView() { const nativeView = this.nativeViewProtected; if (nativeView?.listener) { nativeView.listener.owner = null; } super.disposeNativeView(); } onLoaded() { super.onLoaded(); // Can only be applied after view is loaded const tabWidget = this.nativeViewProtected.getTabWidget(); if (tabWidget) { tabWidget.setEnabled(tabWidget.isEnabled()); } } insertTab(tabItem, index) { const tabHost = this.nativeViewProtected; const tab = tabHost.newTabSpec(index + ''); tab.setIndicator(tabItem.title + ''); tab.setContent(this._tabContentFactory); this._addingTab = true; tabHost.addTab(tab); tabItem.setupNativeView(index); this._addingTab = false; } [selectedIndexProperty.getDefault]() { return -1; } [selectedIndexProperty.setNative](value) { this.nativeViewProtected.setCurrentTab(value); } [itemsProperty.getDefault]() { return null; } [itemsProperty.setNative](value) { this.nativeViewProtected.clearAllTabs(); const newItems = value; if (newItems) { newItems.forEach((item, i, arr) => this.insertTab(item, i)); } selectedIndexProperty.coerce(this); } [isEnabledProperty.setNative](value) { const tabWidget = this.nativeViewProtected.getTabWidget(); if (tabWidget) { tabWidget.setEnabled(value); } } setTabColor(index) { try { const tabWidget = this.nativeViewProtected?.getTabWidget(); if (tabWidget) { const unselectedTextColor = this.getColorForAndroid(this.color ?? '#6e6e6e'); const selectedTextColor = this.getColorForAndroid(this?.selectedTextColor ?? '#000000'); const unselectedBackgroundColor = this.getColorForAndroid(this?.backgroundColor ?? '#dbdbdb'); const selectedBackgroundColor = this.getColorForAndroid(this?.selectedBackgroundColor ?? this?.backgroundColor ?? 'blue'); if (tabWidget) { for (let i = 0; i < tabWidget.getTabCount(); i++) { const view = tabWidget.getChildTabViewAt(i); const item = this.items[i]; const textView = item?.nativeViewProtected; view.setBackgroundColor(unselectedBackgroundColor); if (textView) { textView.setTextColor(unselectedTextColor); } if (index == i) { view.setBackgroundColor(selectedBackgroundColor); if (textView) { textView.setTextColor(selectedTextColor); } continue; } } } } } catch (e) { Trace.error(e); } } getColorForAndroid(color) { if (typeof color === 'string') { return new Color(color).android; } else if (color instanceof Color) { return color.android; } } } //# sourceMappingURL=index.android.js.map