react-native ViewPagerAndroid 坑1
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={{ width: 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;

浙公网安备 33010602011771号