ViewPagerAndroid组件 在更新新的data时 页面显示空
解决办法 在data发生变化时 传入新的data的长度
<ViewPagerAndroid
key={this.props.children.length}
style={{ flex: 1 }}
onPageScroll={this.onPageScroll}
onScrollBeginDrag={this._onScrollBegin}
scrollEnabled={this.props.scrollEnabled}
onPageScrollStateChanged={this.onPageScrollStateChanged}
onPageSelected={this.onPageSelected}
ref={viewPager => { this.viewPager = viewPager; }}
initialPage={this.props.initialPage}>
{this._children().map((child, index) => {
return child;
})}
</ViewPagerAndroid>
import React, { Component } from 'react' import { View, FlatList, Animated, DeviceEventEmitter, ViewPagerAndroid } from 'react-native'; import PropTypes from 'prop-types'; import { Width, isAndroid } from '../../global/rn.base'; const AnimatedFlatList = Animated.createAnimatedComponent(FlatList); class ScrollTabView extends Component { static defaultProps = { horizontal: true, scrollEventThrottle: 16, scrollEnabled: true, pagingEnabled: true, showsHorizontalScrollIndicator: false, showsVerticalScrollIndicator: false, snapToAlignment: 'center', initialPage: 0, onScrollBegin: () => { }, navPosition: 'top', onChangeTab: () => { } }; constructor(props) { super(props); this.state = { viewWidth: Width, refresh:true }; if (props.jumpToView && typeof props.jumpToView === 'function') props.jumpToView(this._goToPage); this.scrollViewProps = { style: this.props.style, currentPage: this.props.initialPage, initialScrollIndex: this.props.initialPage, horizontal: this.props.horizontal, alwaysBounceHorizontal: this.props.alwaysBounceHorizontal, bounces: this.props.bounces, scrollEventThrottle: this.props.scrollEventThrottle, pagingEnabled: this.props.pagingEnabled, snapToAlignment: this.props.snapToAlignment, showsHorizontalScrollIndicator: this.props.showsHorizontalScrollIndicator, showsVerticalScrollIndicator: this.props.showsVerticalScrollIndicator }; } _refresh = (fn) => { this.setState({refresh: !this.state.refresh},()=>{if(fn)fn()}) } componentWillReceiveProps() { this.setState({refresh: !this.state.refresh}) console.log(111) } componentWillMount() { } componentDidUpdate() { } componentDidMount() { } _children(children = this.props.children) { return React.Children.map(children, (child) => child); } _renderTabBar(props) { if (this.props.renderTabBar === false) { return null; } else if (this.props.renderTabBar) { return React.cloneElement(this.props.renderTabBar(props), props); } else { return null; } } _renderScrollableContent = ({ item, index }) => { return <View key={item.props.tabName + '_' + index} style={{ this.state.viewWidth }}> {item} </View> }; _resetScroll = (num, force = false) => { if (isAndroid) this.viewPager.setPageWithoutAnimation(num); let lastNum = this.scrollViewProps.currentPage; this._navBar._resetCurrentPage(num); if (num !== lastNum) { if (isAndroid) { this.viewPager.setPageWithoutAnimation(num); this._dealOffsetParam(num, true); if (this.props.onChangeTab) this.props.onChangeTab({ i: num }); } else { this._scroll.getNode().scrollToIndex({ index: Number(num) }); } this._navBar._resetUnderLine(num); } }; _movingEnd = (event) => { const { x } = event.nativeEvent.contentOffset; let page = parseInt(x / this.state.viewWidth); this.scrollViewProps.currentPage = page; this._dealOffsetParam(x, true); this.props.onChangeTab({ i: page }); }; _listingScroll = (event) => { const { x } = event.nativeEvent.contentOffset; this._dealOffsetParam(x, false); }; _dealOffsetParam(x, isEnd) { if (this._navBar && typeof this._navBar.listenScroll === 'function') this._navBar.listenScroll({ value: isAndroid ? x : (x / this.state.viewWidth), isEnd: isEnd }); } _goToPage = (num, option = {}) => { let { isInit = false, animated = true } = option; let lastNum = this.scrollViewProps.currentPage; this.scrollViewProps.currentPage = num; this._navBar._resetCurrentPage(num); this._onScrollBegin(); if (!isInit) { if (isAndroid) { if (animated) this.viewPager.setPage(num); else this.viewPager.setPageWithoutAnimation(num); } else { this._scroll.getNode().scrollToIndex({ index: Number(num), animated }); } this.props.onChangeTab({ i: num }); if (this.props.onTabClick) this.props.onTabClick(lastNum, num); } }; onPageScroll = ({ nativeEvent }) => { const { offset, position } = nativeEvent; this.scrollViewProps.currentPage = position; this._dealOffsetParam(offset + position, false); }; onPageScrollStateChanged = (type) => { if (type === 'idle') { let position = this.scrollViewProps.currentPage; this._dealOffsetParam(position, true); this.props.onChangeTab({ i: position }) } }; _onScrollBegin = () => { this.props.onScrollBegin && this.props.onScrollBegin(this.scrollViewProps.currentPage); }; render() { let tabBarProps = { tabs: this._children().map((child) => { return { name: child.props.tabName, number: child.props.tabNumber } }), ref: (scroll) => { this._navBar = scroll }, goToPage: this._goToPage, initialPage: this.scrollViewProps.currentPage, scrollEventThrottle: this.props.scrollEventThrottle, }; return ( <View style={this.props.height ? { height: this.props.height } : { flex: 1 }}> {this.props.navPosition === 'top' ? this._renderTabBar(tabBarProps) : null} {isAndroid ? <ViewPagerAndroid key={this.props.children.length} style={{ flex: 1 }} onPageScroll={this.onPageScroll} onScrollBeginDrag={this._onScrollBegin} scrollEnabled={this.props.scrollEnabled} onPageScrollStateChanged={this.onPageScrollStateChanged} onPageSelected={this.onPageSelected} ref={viewPager => { this.viewPager = viewPager; }} initialPage={this.props.initialPage}> {this._children().map((child, index) => { return child; })} </ViewPagerAndroid> : <AnimatedFlatList {...this.scrollViewProps} ref={(scroll) => { this._scroll = scroll }} data={this._children()} scrollEnabled={this.props.scrollEnabled} getItemLayout={(data, index) => ({ length: Width, offset: Width * index, index })} renderItem={this._renderScrollableContent} onMomentumScrollEnd={this._movingEnd}//android onScrollBeginDrag={this._onScrollBegin} onScrollAnimationEnd={this._movingEnd}//ios onScroll={this._listingScroll} /> } {this.props.navPosition === 'bottom' ? this._renderTabBar(tabBarProps) : null} </View> ) } } ScrollTabView.propTypes = { onChangeTab: PropTypes.func, onTabClick: PropTypes.func, initialPage: PropTypes.number }; export default ScrollTabView;