import { Application , CoercibleProperty , Color , CoreTypes , Font , Frame , ImageSource , Property , Utils , View , getTransformedText , isIOS } from '@nativescript/core' ; import { TabStrip } from '@nativescript-community/ui-material-core/tab-navigation-base/tab-strip' ; import { TabStripItem } from '@nativescript-community/ui-material-core/tab-navigation-base/tab-strip-item' ; import { TabContentItem } from '@nativescript-community/ui-material-core/tab-navigation-base/tab-content-item' ; import { TabsBase , animationEnabledProperty , offscreenTabLimitProperty , swipeEnabledProperty } from './tabs-common' ; import { getIconSpecSize , itemsProperty , selectedIndexProperty , tabStripProperty } from '@nativescript-community/ui-material-core/tab-navigation-base/tab-navigation-base' ; export { TabContentItem , TabStrip , TabStripItem } ; export * from './tabs-common' ; const ACCENT_COLOR = 'colorAccent' ; const PRIMARY_COLOR = 'colorPrimary' ; const DEFAULT_ELEVATION = 4 ; const TABID = '_tabId' ; const INDEX = '_index' ; const ownerSymbol = Symbol ( '_owner' ) ; type PagerAdapter = new ( owner ) => androidx . viewpager . widget . PagerAdapter ; let PagerAdapter ; let TabsBar ; let appResources ; let AttachStateChangeListener ; function makeFragmentName ( viewId , id ) { return 'android:viewpager:' + viewId + ':' + id ; } function getTabById ( id ) { const ref = tabs . find ( ( ref ) => { const tab = ref . get ( ) ; return tab && tab . _domId === id ; } ) ; return ref && ref . get ( ) ; } interface PositionChanger { onSelectedPositionChange ( position , prevPosition ) ; } function initializeNativeClasses ( ) { if ( PagerAdapter ) { return ; } @ NativeClass class TabFragmentImplementation extends org . nativescript . widgets . FragmentBase { private owner : Tabs ; private index : number ; private backgroundBitmap : android . graphics . Bitmap = null ; constructor ( ) { super ( ) ; return global . __native ( this ) ; } static newInstance ( tabId , index ) { const args = new android . os . Bundle ( ) ; args . putInt ( TABID , tabId ) ; args . putInt ( INDEX , index ) ; const fragment = new TabFragmentImplementation ( ) ; fragment . setArguments ( args ) ; return fragment ; } public onCreate ( savedInstanceState ) { super . onCreate ( savedInstanceState ) ; const args = this . getArguments ( ) ; this . owner = getTabById ( args . getInt ( TABID ) ) ; this . index = args . getInt ( INDEX ) ; if ( ! this . owner ) { throw new Error ( 'Cannot find TabView' ) ; } } public onCreateView ( inflater , container , savedInstanceState ) { const tabItem = this . owner . items [ this . index ] ; return tabItem . nativeViewProtected ; } public onDestroyView ( ) { const hasRemovingParent = this . getRemovingParentFragment ( ) ; if ( hasRemovingParent && this . owner . selectedIndex === this . index ) { const bitmapDrawable = new android . graphics . drawable . BitmapDrawable ( appResources , this . backgroundBitmap ) ; this . owner . _originalBackground = this . owner . backgroundColor || new Color ( 'White' ) ; this . owner . nativeViewProtected . setBackgroundDrawable ( bitmapDrawable ) ; this . backgroundBitmap = null ; } super . onDestroyView ( ) ; } public onPause ( ) { const hasRemovingParent = this . getRemovingParentFragment ( ) ; if ( hasRemovingParent && this . owner . selectedIndex === this . index ) { this . backgroundBitmap = this . loadBitmapFromView ( this . owner . nativeViewProtected ) ; } super . onPause ( ) ; } private loadBitmapFromView ( view ) { view . setDrawingCacheEnabled ( true ) ; const bitmap = android . graphics . Bitmap . createBitmap ( view . getDrawingCache ( ) ) ; view . setDrawingCacheEnabled ( false ) ; return bitmap ; } } const POSITION_UNCHANGED = - 1 ; const POSITION_NONE = - 2 ; @ NativeClass class FragmentPagerAdapter extends androidx . viewpager . widget . PagerAdapter { public items : TabContentItem [ ] ; private mCurTransaction : androidx . fragment . app . FragmentTransaction ; private mCurrentPrimaryItem : androidx . fragment . app . Fragment ; constructor ( public owner ) { super ( ) ; return global . __native ( this ) ; } getCount ( ) { const items = this . items ; return items ? items . length : 0 ; } getPageTitle ( index ) { const items = this . items ; if ( index < 0 || index >= items . length ) { return '' ; } return '' ; } startUpdate ( container ) { if ( container . getId ( ) === android . view . View . NO_ID ) { throw new Error ( `ViewPager with adapter ${ this } requires a view containerId` ) ; } } instantiateItem ( container , position ) { const fragmentManager = this . owner . _getRootFragmentManager ( ) ; if ( ! this . mCurTransaction ) { this . mCurTransaction = fragmentManager . beginTransaction ( ) ; } const itemId = this . getItemId ( position ) ; const name = makeFragmentName ( container . getId ( ) , itemId ) ; let fragment = fragmentManager . findFragmentByTag ( name ) ; if ( fragment != null ) { this . mCurTransaction . attach ( fragment ) ; } else { fragment = TabFragmentImplementation . newInstance ( this . owner . _domId , position ) ; this . owner . fragments . push ( fragment ) ; this . mCurTransaction . add ( container . getId ( ) , fragment , name ) ; } if ( fragment !== this . mCurrentPrimaryItem ) { fragment . setMenuVisibility ( false ) ; fragment . setUserVisibleHint ( false ) ; } const tabItems = this . owner . items ; const tabItem = tabItems ? tabItems [ position ] : null ; if ( tabItem ) { tabItem . canBeLoaded = true ; } return fragment ; } getItemPosition ( object ) { return this . items ? POSITION_UNCHANGED : POSITION_NONE ; } destroyItem ( container , position , object ) { if ( ! this . mCurTransaction ) { const fragmentManager = this . owner . _getRootFragmentManager ( ) ; this . mCurTransaction = fragmentManager . beginTransaction ( ) ; } const fragment = object as androidx . fragment . app . Fragment ; const index = this . owner . fragments . indexOf ( fragment ) ; this . mCurTransaction . detach ( fragment ) ; if ( this . mCurrentPrimaryItem === fragment ) { this . mCurrentPrimaryItem = null ; } const tabItems = this . owner . items ; const tabItem = tabItems ? tabItems [ position ] : null ; if ( tabItem ) { tabItem . canBeLoaded = false ; } } setPrimaryItem ( container , position , object ) { const fragment = object as androidx . fragment . app . Fragment ; if ( fragment !== this . mCurrentPrimaryItem ) { if ( this . mCurrentPrimaryItem != null ) { this . mCurrentPrimaryItem . setMenuVisibility ( false ) ; this . mCurrentPrimaryItem . setUserVisibleHint ( false ) ; } if ( fragment != null ) { fragment . setMenuVisibility ( true ) ; fragment . setUserVisibleHint ( true ) ; } this . mCurrentPrimaryItem = fragment ; this . owner . selectedIndex = position ; const tab = this . owner ; const tabItems = tab . items ; const newTabItem = tabItems ? tabItems [ position ] : null ; if ( newTabItem ) { tab . _loadUnloadTabItems ( tab . selectedIndex ) ; } } } finishUpdate ( container ) { this . _commitCurrentTransaction ( ) ; } isViewFromObject ( view , object ) { return ( object as androidx . fragment . app . Fragment ) . getView ( ) === view ; } saveState ( ) { this . _commitCurrentTransaction ( ) ; return null ; } restoreState ( state , loader ) { } getItemId ( position ) { return position ; } private _commitCurrentTransaction ( ) { if ( this . mCurTransaction != null ) { this . mCurTransaction . commitNowAllowingStateLoss ( ) ; this . mCurTransaction = null ; } } } @ NativeClass class TabsBarImplementation extends com . nativescript . material . core . TabsBar implements PositionChanger { constructor ( context , public owner ) { super ( context ) ; return global . __native ( this ) ; } public onSelectedPositionChange ( position , prevPosition ) { const owner = this . owner ; if ( ! owner ) { return ; } const tabStripItems = owner . tabStrip && owner . tabStrip . items ; if ( position >= 0 && tabStripItems && tabStripItems [ position ] ) { tabStripItems [ position ] . _emit ( TabStripItem . selectEvent ) ; owner . _setItemColor ( tabStripItems [ position ] ) ; } if ( prevPosition >= 0 && tabStripItems && tabStripItems [ prevPosition ] ) { tabStripItems [ prevPosition ] . _emit ( TabStripItem . unselectEvent ) ; owner . _setItemColor ( tabStripItems [ prevPosition ] ) ; } } public onTap ( position ) { const owner = this . owner ; if ( ! owner ) { return false ; } const tabStrip = owner . tabStrip ; const tabStripItems = tabStrip && tabStrip . items ; if ( position >= 0 && tabStripItems [ position ] ) { tabStripItems [ position ] . _emit ( TabStripItem . tapEvent ) ; tabStrip . notify ( { eventName : TabStrip . itemTapEvent , object : tabStrip , index : position } ) ; } if ( ! owner . items [ position ] ) { return false ; } return true ; } } @ NativeClass @ Interfaces ( [ android . view . View . OnAttachStateChangeListener ] ) class AttachListener extends java . lang . Object implements android . view . View . OnAttachStateChangeListener { constructor ( ) { super ( ) ; return global . __native ( this ) ; } onViewAttachedToWindow ( view ) { const owner = view [ ownerSymbol ] ; if ( owner ) { owner . _onAttachedToWindow ( ) ; } } onViewDetachedFromWindow ( view ) { const owner = view [ ownerSymbol ] ; if ( owner ) { owner . _onDetachedFromWindow ( ) ; } } } PagerAdapter = FragmentPagerAdapter ; TabsBar = TabsBarImplementation ; AttachStateChangeListener = new AttachListener ( ) ; appResources = Application . android . context . getResources ( ) ; } let defaultAccentColor ; function getDefaultAccentColor ( context ) { if ( defaultAccentColor === undefined ) { defaultAccentColor = Utils . android . resources . getPaletteColor ( ACCENT_COLOR , context ) || 0xff33b5e5 ; } return defaultAccentColor ; } function setElevation ( grid , tabsBar , tabsPosition ) { const compat = androidx . core . view . ViewCompat as any ; if ( compat . setElevation ) { const val = DEFAULT_ELEVATION * Utils . layout . getDisplayDensity ( ) ; if ( tabsPosition === 'top' ) { compat . setElevation ( grid , val ) ; } compat . setElevation ( tabsBar , val ) ; } } export const tabs = new Array < WeakRef < Tabs > > ( ) ; function iterateIndexRange ( index , eps , lastIndex , callback ) { 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 Tabs extends TabsBase { private _tabsBar : com . nativescript . material . core . TabsBar ; private _viewPager : com . nativescript . material . core . TabViewPager ; private _pagerAdapter : androidx . viewpager . widget . PagerAdapter ; private _androidViewId = - 1 ; public _originalBackground : any ; private _textTransform : CoreTypes . TextTransformType = 'uppercase' ; private _selectedItemColor : Color ; private _unSelectedItemColor : Color ; fragments : androidx . fragment . app . Fragment [ ] = [ ] ; private _attachedToWindow = false ; constructor ( ) { super ( ) ; tabs . push ( new WeakRef ( this ) ) ; } get _hasFragments ( ) : boolean { return true ; } public onItemsChanged ( oldItems , newItems ) { super . onItemsChanged ( oldItems , newItems ) ; if ( oldItems ) { oldItems . forEach ( ( item , i , arr ) => { ( item as any ) . index = 0 ; ( item as any ) . tabItemSpec = null ; item . setNativeView ( null ) ; } ) ; } } public createNativeView ( ) { initializeNativeClasses ( ) ; const context = this . _context ; const nativeView = new org . nativescript . widgets . GridLayout ( context ) ; const viewPager = new com . nativescript . material . core . TabViewPager ( context ) ; const tabsBar = new TabsBar ( context , this ) ; const lp = new org . nativescript . widgets . CommonLayoutParams ( ) ; const primaryColor = Utils . android . resources . getPaletteColor ( PRIMARY_COLOR , context ) ; const accentColor = getDefaultAccentColor ( context ) ; lp . row = 1 ; if ( this . tabsPosition === 'top' ) { nativeView . addRow ( new org . nativescript . widgets . ItemSpec ( 1 , org . nativescript . widgets . GridUnitType . auto ) ) ; nativeView . addRow ( new org . nativescript . widgets . ItemSpec ( 1 , org . nativescript . widgets . GridUnitType . star ) ) ; viewPager . setLayoutParams ( lp ) ; } else { nativeView . addRow ( new org . nativescript . widgets . ItemSpec ( 1 , org . nativescript . widgets . GridUnitType . star ) ) ; nativeView . addRow ( new org . nativescript . widgets . ItemSpec ( 1 , org . nativescript . widgets . GridUnitType . auto ) ) ; tabsBar . setLayoutParams ( lp ) ; } nativeView . addView ( viewPager ) ; ( nativeView as any ) . viewPager = viewPager ; const adapter = new PagerAdapter ( this ) ; viewPager . setAdapter ( adapter ) ; ( viewPager as any ) . adapter = adapter ; nativeView . addView ( tabsBar ) ; ( nativeView as any ) . tabsBar = tabsBar ; setElevation ( nativeView , tabsBar , this . tabsPosition ) ; if ( accentColor ) { tabsBar . setSelectedIndicatorColors ( [ accentColor ] ) ; } if ( primaryColor ) { tabsBar . setBackgroundColor ( primaryColor ) ; } return nativeView ; } onSelectedIndexChanged ( oldIndex , newIndex ) { const tabBarImplementation = ( this . _tabsBar as unknown ) as PositionChanger ; if ( tabBarImplementation ) { tabBarImplementation . onSelectedPositionChange ( oldIndex , newIndex ) ; } super . onSelectedIndexChanged ( oldIndex , newIndex ) ; } public initNativeView ( ) { super . initNativeView ( ) ; if ( this . _androidViewId < 0 ) { this . _androidViewId = android . view . View . generateViewId ( ) ; } const nativeView = this . nativeViewProtected ; this . _tabsBar = nativeView . tabsBar ; nativeView [ ownerSymbol ] = this ; const viewPager = nativeView . viewPager ; viewPager . setId ( this . _androidViewId ) ; this . _viewPager = viewPager ; this . _pagerAdapter = viewPager . adapter ; ( this . _pagerAdapter as any ) . owner = this ; } _onAttachedToWindow ( ) { super . _onAttachedToWindow ( ) ; const activity = Application . android . foregroundActivity || Application . android . startActivity ; const lifecycle = activity ?. getLifecycle ?. ( ) . getCurrentState ( ) || androidx . lifecycle . Lifecycle . State . CREATED ; if ( ( this . _manager && this . _manager . isDestroyed ( ) ) || ( activity instanceof androidx . fragment . app . FragmentActivity && ! lifecycle . isAtLeast ( androidx . lifecycle . Lifecycle . State . CREATED ) ) ) { return ; } this . _attachedToWindow = true ; this . _viewPager . setCurrentItem ( this . selectedIndex , false ) ; } _onDetachedFromWindow ( ) { super . _onDetachedFromWindow ( ) ; this . disposeCurrentFragments ( ) ; this . _attachedToWindow = false ; } public _loadUnloadTabItems ( newIndex ) { const items = this . items ; if ( ! items ) { return ; } const lastIndex = items . length - 1 ; const offsideItems = this . offscreenTabLimit ; const toUnload = [ ] ; const 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 . content ) ; } } ) ; const newItem = items [ newIndex ] ; const selectedView = newItem && newItem . content ; if ( selectedView instanceof Frame ) { selectedView . _pushInFrameStackRecursive ( ) ; } toLoad . forEach ( ( index ) => { const item = items [ index ] ; if ( this . isLoaded && items [ index ] ) { item . loadView ( item . content ) ; } } ) ; } public onLoaded ( ) { super . onLoaded ( ) ; if ( this . _originalBackground ) { this . backgroundColor = null ; this . backgroundColor = this . _originalBackground ; this . _originalBackground = null ; } this . setItems ( this . items as any ) ; if ( this . tabStrip ) { this . setTabStripItems ( this . tabStrip . items ) ; } } public onUnloaded ( ) { super . onUnloaded ( ) ; this . setItems ( null ) ; this . setTabStripItems ( null ) ; } public disposeNativeView ( ) { this . _tabsBar . setItems ( null , null ) ; ( this . _pagerAdapter as any ) . owner = null ; this . _pagerAdapter = null ; this . nativeViewProtected . removeOnAttachStateChangeListener ( AttachStateChangeListener ) ; this . nativeViewProtected [ ownerSymbol ] = null ; this . _tabsBar = null ; this . _viewPager = null ; super . disposeNativeView ( ) ; this . disposeCurrentFragments ( ) ; } public _onRootViewReset ( ) { super . _onRootViewReset ( ) ; this . disposeCurrentFragments ( ) ; } private disposeCurrentFragments ( ) { const fragmentManager = this . _getRootFragmentManager ( ) ; const transaction = fragmentManager . beginTransaction ( ) ; const fragments = this . fragments ; for ( let i = 0 ; i < fragments . length ; i ++ ) { transaction . remove ( fragments [ i ] ) ; } transaction . commitNowAllowingStateLoss ( ) ; this . fragments = [ ] ; } private shouldUpdateAdapter ( items ) { if ( ! this . _pagerAdapter ) { return false ; } const currentPagerAdapterItems = ( this . _pagerAdapter as any ) . items ; if ( ! items && ! currentPagerAdapterItems ) { return false ; } if ( ! items || ! currentPagerAdapterItems ) { return true ; } if ( items . length !== currentPagerAdapterItems . length ) { return true ; } const matchingItems = currentPagerAdapterItems . filter ( ( currentItem ) => ! ! items . filter ( ( item ) => item . _domId === currentItem . _domId ) [ 0 ] ) ; if ( matchingItems . length !== items . length ) { return true ; } return false ; } private setItems ( items ) { if ( this . shouldUpdateAdapter ( items ) ) { ( this . _pagerAdapter as any ) . items = items ; if ( items && items . length ) { items . forEach ( ( item , i ) => { ( item as any ) . index = i ; } ) ; } this . _pagerAdapter . notifyDataSetChanged ( ) ; } } private setTabStripItems ( items ) { const length = items ? items . length : 0 ; if ( length === 0 ) { this . _tabsBar . setItems ( null , null ) ; return ; } const tabItems = new Array < com . nativescript . material . core . TabItemSpec > ( ) ; items . forEach ( ( tabStripItem , i , arr ) => { if ( ! this . _unSelectedItemColor ) { this . _unSelectedItemColor = tabStripItem . label ?. style . color ; } tabStripItem . _index = i ; const tabItemSpec = this . createTabItemSpec ( tabStripItem ) ; ( tabStripItem as any ) . tabItemSpec = tabItemSpec ; tabItems . push ( tabItemSpec ) ; } ) ; const tabsBar = this . _tabsBar ; tabsBar . setItems ( tabItems , this . _viewPager ) ; this . tabStrip . setNativeView ( tabsBar ) ; items . forEach ( ( item , i , arr ) => { const tv = tabsBar . getTextViewForItemAt ( i ) ; item . setNativeView ( tv ) ; this . _setItemColor ( item ) ; } ) ; } private getItemLabelTextTransform ( tabStripItem ) { const nestedLabel = tabStripItem . label ; let textTransform = null ; if ( nestedLabel && nestedLabel . style . textTransform !== 'initial' ) { textTransform = nestedLabel . style . textTransform ; } else if ( tabStripItem . style . textTransform !== 'initial' ) { textTransform = tabStripItem . style . textTransform ; } return textTransform || this . _textTransform ; } private createTabItemSpec ( tabStripItem ) { const tabItemSpec = new com . nativescript . material . core . TabItemSpec ( ) ; if ( tabStripItem . isLoaded ) { const nestedLabel = tabStripItem . label ; let title = nestedLabel . text ; const textTransform = this . getItemLabelTextTransform ( tabStripItem ) ; title = getTransformedText ( title , textTransform ) ; tabItemSpec . title = title ; const backgroundColor = tabStripItem . style . backgroundColor ; tabItemSpec . backgroundColor = backgroundColor ? backgroundColor . android : this . getTabBarBackgroundArgbColor ( ) ; const itemColor = this . selectedIndex === tabStripItem . _index ? this . _selectedItemColor : this . _unSelectedItemColor ; const color = itemColor || nestedLabel . style . color ; tabItemSpec . color = color && color . android ; const fontInternal = nestedLabel . style . fontInternal ; if ( fontInternal ) { tabItemSpec . fontSize = fontInternal . fontSize ; tabItemSpec . typeFace = fontInternal . getAndroidTypeface ( ) ; } const iconSource = tabStripItem . image && tabStripItem . image . src ; if ( iconSource ) { const icon = this . getIcon ( tabStripItem , itemColor ) ; if ( icon ) { tabItemSpec . iconDrawable = icon ; } else { } } } return tabItemSpec ; } private getIcon ( tabStripItem , color ? ) { const iconSource = tabStripItem . image && tabStripItem . image . src ; if ( ! iconSource ) { return null ; } let is ; if ( Utils . isFontIconURI ( iconSource ) ) { const fontIconCode = iconSource . split ( '//' ) [ 1 ] ; const target = tabStripItem . image ? tabStripItem . image : tabStripItem ; const font = target . style . fontInternal ; if ( ! color ) { color = target . style . color ; } is = ImageSource . fromFontIconCodeSync ( fontIconCode , font , color ) ; } else { is = ImageSource . fromFileOrResourceSync ( iconSource ) ; } let imageDrawable ; if ( is && is . android ) { let image = is . android ; if ( this . tabStrip && this . tabStrip . isIconSizeFixed ) { image = this . getFixedSizeIcon ( image ) ; } imageDrawable = new android . graphics . drawable . BitmapDrawable ( appResources , image ) ; } else { } return imageDrawable ; } private getFixedSizeIcon ( image ) { const inWidth = image . getWidth ( ) ; const inHeight = image . getHeight ( ) ; const iconSpecSize = getIconSpecSize ( { width : inWidth , height : inHeight } ) ; const widthPixels = iconSpecSize . width * Utils . layout . getDisplayDensity ( ) ; const heightPixels = iconSpecSize . height * Utils . layout . getDisplayDensity ( ) ; const scaledImage = android . graphics . Bitmap . createScaledBitmap ( image , widthPixels , heightPixels , true ) ; return scaledImage ; } public updateAndroidItemAt ( index , spec ) { try { this . _tabsBar . updateItemAt ( index , spec ) ; } catch ( err ) { } } public getTabBarBackgroundColor ( ) { return this . _tabsBar . getBackground ( ) ; } public setTabBarBackgroundColor ( value ) { if ( value instanceof Color ) { this . _tabsBar . setBackgroundColor ( value . android ) ; } else { this . _tabsBar . setBackground ( tryCloneDrawable ( value , this . nativeViewProtected . getResources ( ) ) ) ; } } public getTabBarHighlightColor ( ) { return getDefaultAccentColor ( this . _context ) ; } public setTabBarHighlightColor ( value ) { const color = value instanceof Color ? value . android : value ; this . _tabsBar . setSelectedIndicatorColors ( [ color ] ) ; } public getTabBarSelectedItemColor ( ) { return this . _selectedItemColor ; } public setTabBarSelectedItemColor ( value ) { this . _selectedItemColor = value ; } public getTabBarUnSelectedItemColor ( ) { return this . _unSelectedItemColor ; } public setTabBarUnSelectedItemColor ( value ) { this . _unSelectedItemColor = value ; } private updateItem ( tabStripItem ) { const tabStripItemIndex = this . tabStrip . items . indexOf ( tabStripItem ) ; const tabItemSpec = this . createTabItemSpec ( tabStripItem ) ; this . updateAndroidItemAt ( tabStripItemIndex , tabItemSpec ) ; } public setTabBarItemTitle ( tabStripItem , value ) { this . updateItem ( tabStripItem ) ; } public setTabBarItemBackgroundColor ( tabStripItem , value ) { this . updateItem ( tabStripItem ) ; } public _setItemColor ( tabStripItem ) { if ( ! tabStripItem . nativeViewProtected ) { return ; } const itemColor = tabStripItem . _index === this . selectedIndex ? this . _selectedItemColor : this . _unSelectedItemColor ; if ( ! itemColor ) { return ; } tabStripItem . nativeViewProtected . setTextColor ( itemColor . android ) ; this . setIconColor ( tabStripItem , itemColor ) ; } private setIconColor ( tabStripItem , color ? ) { if ( ! tabStripItem . nativeViewProtected ) { return ; } const tabBarItem = this . _tabsBar . getViewForItemAt ( tabStripItem . _index ) ; const drawable = this . getIcon ( tabStripItem , color ) ; const imgView = tabBarItem . getChildAt ( 0 ) as android . widget . ImageView ; imgView . setImageDrawable ( drawable ) ; if ( color ) { imgView . setColorFilter ( color . android ) ; } } public setTabBarItemColor ( tabStripItem , value ) { const itemColor = tabStripItem . _index === this . selectedIndex ? this . _selectedItemColor : this . _unSelectedItemColor ; if ( itemColor ) { return ; } const androidColor = value instanceof Color ? value . android : value ; tabStripItem . nativeViewProtected . setTextColor ( androidColor ) ; } public setTabBarIconColor ( tabStripItem , value ) { const itemColor = tabStripItem . _index === this . selectedIndex ? this . _selectedItemColor : this . _unSelectedItemColor ; if ( itemColor ) { return ; } this . setIconColor ( tabStripItem ) ; } public setTabBarIconSource ( tabStripItem , value ) { this . updateItem ( tabStripItem ) ; } public setTabBarItemFontInternal ( tabStripItem , value ) { if ( value . fontSize ) { tabStripItem . nativeViewProtected . setTextSize ( value . fontSize ) ; } tabStripItem . nativeViewProtected . setTypeface ( value . getAndroidTypeface ( ) ) ; } public getTabBarItemTextTransform ( tabStripItem ) { return this . getItemLabelTextTransform ( tabStripItem ) ; } public setTabBarItemTextTransform ( tabStripItem , value ) { const nestedLabel = tabStripItem . label ; const title = getTransformedText ( nestedLabel . text , value ) ; tabStripItem . nativeViewProtected . setText ( title ) ; } public getTabBarTextTransform ( ) { return this . _textTransform ; } public setTabBarTextTransform ( value ) { const items = this . tabStrip && this . tabStrip . items ; if ( items ) { items . forEach ( ( tabStripItem ) => { if ( tabStripItem . label && tabStripItem . nativeViewProtected ) { const nestedLabel = tabStripItem . label ; const title = getTransformedText ( nestedLabel . text , value ) ; tabStripItem . nativeViewProtected . setText ( title ) ; } } ) ; } this . _textTransform = value ; } [ selectedIndexProperty . setNative ] ( value ) { this . _viewPager . setCurrentItem ( value , this . animationEnabled ) ; } [ itemsProperty . getDefault ] ( ) { return null ; } [ itemsProperty . setNative ] ( value ) { this . setItems ( value ) ; selectedIndexProperty . coerce ( this as any ) ; } [ tabStripProperty . getDefault ] ( ) { return null ; } [ tabStripProperty . setNative ] ( value ) { this . setTabStripItems ( value . items ) ; } [ swipeEnabledProperty . getDefault ] ( ) { return true ; } [ swipeEnabledProperty . setNative ] ( value ) { this . _viewPager . setSwipePageEnabled ( value ) ; } [ offscreenTabLimitProperty . getDefault ] ( ) { return this . _viewPager . getOffscreenPageLimit ( ) ; } [ offscreenTabLimitProperty . setNative ] ( value ) { this . _viewPager . setOffscreenPageLimit ( value ) ; } [ animationEnabledProperty . setNative ] ( value ) { ( this . _viewPager as any ) . setAnimationEnabled ( value ) ; } } function tryCloneDrawable ( value , resources ) { if ( value ) { const constantState = value . getConstantState ( ) ; if ( constantState ) { return constantState . newDrawable ( resources ) ; } } return value ; }