@@ -96,10 +96,7 @@ export default class ScrollableTabView extends React.Component {
9696 constructor ( props ) {
9797 super ( props ) ;
9898 this . state = {
99- checkedIndex : this . _getFirstIndex ( ) ,
100- refsObj : { } ,
101- lazyIndexs : this . _initLazyIndexs ( ) ,
102- isRefreshing : false
99+ ...this . _initialState ( )
103100 } ;
104101 this . sectionListScrollY = new Animated . Value ( 0 ) ;
105102 this . carouselScrollX = new Animated . Value ( 0 ) ;
@@ -134,6 +131,15 @@ export default class ScrollableTabView extends React.Component {
134131 this . _initial ( newProps , true ) ;
135132 }
136133
134+ _initialState ( ) {
135+ return {
136+ checkedIndex : this . _getFirstIndex ( ) ,
137+ refsObj : { } ,
138+ lazyIndexs : this . _initLazyIndexs ( ) ,
139+ isRefreshing : false
140+ } ;
141+ }
142+
137143 _initial ( props = this . props , isProcess = false ) {
138144 isProcess && this . _toProcess ( props ) ;
139145 this . tabs = this . _getTabs ( props ) ;
@@ -199,12 +205,25 @@ export default class ScrollableTabView extends React.Component {
199205 return ref => {
200206 if ( this . state . refsObj [ index ] && this . state . refsObj [ index ] === ref ) return ;
201207 this . state . refsObj [ index ] = ref ;
208+ this . state . refsObj [ index ] . __id__ = id ;
202209 this . setState ( {
203210 refsObj : this . state . refsObj
204211 } ) ;
205212 } ;
206213 }
207214
215+ clearStacks = callback => {
216+ this . tabs = [ ] ;
217+ this . badges = [ ] ;
218+ this . stacks = [ ] ;
219+ this . setState (
220+ {
221+ ...this . _initialState ( )
222+ } ,
223+ ( ) => typeof callback === 'function' && callback ( )
224+ ) ;
225+ } ;
226+
208227 getCurrentRef ( index ) {
209228 return this . state . refsObj [ index ?? this . state . checkedIndex ] ;
210229 }
@@ -365,6 +384,7 @@ export default class ScrollableTabView extends React.Component {
365384 const { oneTabHidden, tabsShown, tabsStyle, tabStyle, useScroll, tabsEnableAnimated, useScrollStyle } = this . props ;
366385 const { width } = tabStyle ;
367386 if ( tabsEnableAnimated && tabStyle && width == undefined ) throw new Error ( 'When tabsEnableAnimated is true, the width must be specified for tabStyle' ) ;
387+ if ( useScroll && tabStyle && width == undefined ) throw new Error ( 'When useScroll is true, the width must be specified for tabStyle' ) ;
368388 const renderTab = ! ( oneTabHidden && this . tabs && this . tabs . length == 1 ) && tabsShown ;
369389 const _tabsStyle = Object . assign ( { } , ! useScroll && { alignItems : 'center' , justifyContent : 'space-around' } , styles . tabsStyle , tabsStyle ) ;
370390 this . layoutHeight [ 'tabs' ] = renderTab ? _tabsStyle . height : 0 ;
@@ -414,6 +434,7 @@ export default class ScrollableTabView extends React.Component {
414434 } ) ;
415435 } ;
416436
437+ // 启用 useScroll 情况下保证滚动条跟随
417438 _tabTranslateX ( index = this . state . checkedIndex ) {
418439 const { useScroll } = this . props ;
419440 if ( useScroll && this . scrollview && this . tabWidth ) {
@@ -423,26 +444,31 @@ export default class ScrollableTabView extends React.Component {
423444 }
424445 }
425446
447+ _resetOtherRefs ( ) {
448+ const checkedIndex = this . state . checkedIndex ;
449+ if ( this . state . refsObj && this . state . refsObj [ checkedIndex ] ) this . state . refsObj [ checkedIndex ] = null ;
450+ return this . state . refsObj ;
451+ }
452+
426453 _onTabviewChange ( isCarouselScroll , index ) {
427- const { toHeaderOnTab, toTabsOnTab, onTabviewChanged } = this . props ;
454+ const { enableCachePage , toHeaderOnTab, toTabsOnTab, onTabviewChanged } = this . props ;
428455 if ( index == this . state . checkedIndex ) {
429456 if ( ! isCarouselScroll && toHeaderOnTab ) return this . _scrollTo ( - this . layoutHeight [ 'header' ] ) ;
430457 if ( ! isCarouselScroll && toTabsOnTab ) return this . _scrollTo ( 0 ) ;
431458 return void 0 ;
432459 }
433460 if ( ! this . state . lazyIndexs . includes ( index ) ) this . state . lazyIndexs . push ( index ) ;
434- this . setState (
435- {
436- checkedIndex : index ,
437- lazyIndexs : this . state . lazyIndexs
438- } ,
439- ( ) => {
440- if ( onTabviewChanged ) {
441- const tab = this . tabs [ this . state . checkedIndex ] ;
442- onTabviewChanged ( this . state . checkedIndex , tab && tab . tabLabel ) ;
443- }
461+ let state = {
462+ checkedIndex : index ,
463+ lazyIndexs : this . state . lazyIndexs
464+ } ;
465+ if ( ! enableCachePage ) state . refsObj = this . _resetOtherRefs ( ) ;
466+ this . setState ( state , ( ) => {
467+ if ( onTabviewChanged ) {
468+ const tab = this . tabs [ this . state . checkedIndex ] ;
469+ onTabviewChanged ( this . state . checkedIndex , tab && tab . tabLabel ) ;
444470 }
445- ) ;
471+ } ) ;
446472 this . _tabTranslateX ( index ) ;
447473 // 非滑动触发的情况下需要同步index,避免Carousel无法正常显示
448474 // !isCarouselScroll && this._snapToItem(index);
@@ -464,21 +490,22 @@ export default class ScrollableTabView extends React.Component {
464490 }
465491
466492 _renderItem ( { item, index } ) {
493+ const { enableCachePage, fillScreen, fixedTabs, mappingProps } = this . props ;
467494 const screenHeight = this . _getScreenHeight ( ) ;
468495 return (
469- ( this . props . enableCachePage ? this . props . enableCachePage : this . state . checkedIndex == index ) &&
496+ ( enableCachePage ? enableCachePage : this . state . checkedIndex == index ) &&
470497 ( this . getCurrentRef ( index ) || this . getCurrentRef ( index ) == undefined ) &&
471498 this . _getLazyIndexs ( index ) && (
472499 < View
473500 style = { [
474501 { flex : 1 } ,
475- this . props . enableCachePage && this . state . checkedIndex != index && { maxHeight : screenHeight } ,
476- this . props . enableCachePage && this . state . checkedIndex == index && this . props . fillScreen && { minHeight : screenHeight } ,
477- this . props . enableCachePage && this . state . checkedIndex == index && this . props . fixedTabs && { minHeight : this . _getMaximumScreenHeight ( ) } ,
478- ! this . props . enableCachePage && this . state . checkedIndex == index && { minHeight : screenHeight }
502+ enableCachePage && this . state . checkedIndex != index && { maxHeight : screenHeight } ,
503+ enableCachePage && this . state . checkedIndex == index && fillScreen && { minHeight : screenHeight } ,
504+ enableCachePage && this . state . checkedIndex == index && fixedTabs && { minHeight : this . _getMaximumScreenHeight ( ) } ,
505+ ! enableCachePage && this . state . checkedIndex == index && { minHeight : screenHeight }
479506 ] }
480507 >
481- < item . screen { ...this . _getProps ( this . props . mappingProps ) } { ...( item . toProps || { } ) } />
508+ < item . screen { ...this . _getProps ( mappingProps ) } { ...( item . toProps || { } ) } />
482509 </ View >
483510 )
484511 ) ;
@@ -487,6 +514,7 @@ export default class ScrollableTabView extends React.Component {
487514 _onEndReached ( ) {
488515 const next = ( ) => {
489516 const ref = this . getCurrentRef ( ) ;
517+ ! ref && console . warn ( `The Screen Ref is lost when calling onEndReached. Please confirm whether the Stack is working properly.(index: ${ this . state . checkedIndex } )` ) ;
490518 if ( ref && ref . onEndReached && typeof ref . onEndReached == 'function' ) ref . onEndReached ( ) ;
491519 } ;
492520 const { onBeforeEndReached } = this . props ;
@@ -502,6 +530,7 @@ export default class ScrollableTabView extends React.Component {
502530 _onRefresh ( ) {
503531 const next = ( ) => {
504532 const ref = this . getCurrentRef ( ) ;
533+ ! ref && console . warn ( `The Screen Ref is lost when calling onRefresh. Please confirm whether the Stack is working properly.(index: ${ this . state . checkedIndex } )` ) ;
505534 if ( ref && ref . onRefresh && typeof ref . onRefresh == 'function' ) ref . onRefresh ( this . _toggledRefreshing . bind ( this ) ) ;
506535 } ;
507536 const { onBeforeRefresh } = this . props ;
@@ -545,32 +574,34 @@ export default class ScrollableTabView extends React.Component {
545574 } ;
546575
547576 render ( ) {
577+ const { style, title, onEndReachedThreshold, fixedHeader, tabsEnableAnimated, carouselProps, onScroll, sectionListProps } = this . props ;
548578 return (
549579 < View
550580 onLayout = { ( { nativeEvent } ) => {
551581 const { height } = nativeEvent . layout ;
552582 this . layoutHeight [ 'container' ] = height ;
553583 if ( height !== 0 ) this . _refresh ( ) ;
554584 } }
555- style = { [ styles . container , this . props . style ] }
585+ style = { [ styles . container , style ] }
556586 >
557- { ! ! this . props . title && this . _renderTitle ( ) }
587+ { ! ! title && this . _renderTitle ( ) }
558588 < SectionList
559589 ref = { rf => ( this . section = rf ) }
560590 keyExtractor = { ( item , index ) => `scrollable-tab-view-wrap-${ index } ` }
561591 renderSectionHeader = { this . _renderSectionHeader . bind ( this ) }
562592 onEndReached = { this . _onEndReached . bind ( this ) }
563- onEndReachedThreshold = { this . props . onEndReachedThreshold }
593+ onEndReachedThreshold = { onEndReachedThreshold }
564594 refreshControl = { < RefreshControl refreshing = { this . state . isRefreshing } onRefresh = { this . _onRefresh . bind ( this ) } /> }
565595 sections = { [ { data : [ 1 ] } ] }
566596 stickySectionHeadersEnabled = { true }
567- ListHeaderComponent = { ! this . props . fixedHeader && this . _renderHeader ( ) }
597+ ListHeaderComponent = { ! fixedHeader && this . _renderHeader ( ) }
568598 showsVerticalScrollIndicator = { false }
569599 showsHorizontalScrollIndicator = { false }
570600 renderItem = { ( ) => {
571601 return (
572602 < Carousel
573603 ref = { c => ( this . tabview = c ) }
604+ pagingEnabled = { true }
574605 inactiveSlideScale = { 1 }
575606 data = { this . stacks }
576607 renderItem = { this . _renderItem . bind ( this ) }
@@ -585,7 +616,7 @@ export default class ScrollableTabView extends React.Component {
585616 index
586617 } ) }
587618 onScroll = {
588- this . props . tabsEnableAnimated &&
619+ tabsEnableAnimated &&
589620 Animated . event (
590621 [
591622 {
@@ -599,29 +630,29 @@ export default class ScrollableTabView extends React.Component {
599630 }
600631 )
601632 }
602- { ...this . props . carouselProps }
633+ { ...carouselProps }
603634 />
604635 ) ;
605636 } }
606637 onScrollToIndexFailed = { ( ) => { } }
607638 onScroll = {
608- ! ! this . props . title
639+ ! ! title
609640 ? Animated . event (
610641 [
611642 {
612643 nativeEvent : { contentOffset : { y : this . sectionListScrollY } }
613644 }
614645 ] ,
615646 {
616- listener : ! ! this . props . onScroll && this . props . onScroll . bind ( this ) ,
647+ listener : ! ! onScroll && onScroll . bind ( this ) ,
617648 useNativeDriver : false
618649 }
619650 )
620- : ! ! this . props . onScroll
621- ? this . props . onScroll . bind ( this )
651+ : ! ! onScroll
652+ ? onScroll . bind ( this )
622653 : null
623654 }
624- { ...this . props . sectionListProps }
655+ { ...sectionListProps }
625656 > </ SectionList >
626657 </ View >
627658 ) ;
0 commit comments