UNPKG

react-native-dynamic-tab-view

Version:
208 lines (186 loc) 5.26 kB
/* eslint-disable react/prop-types */ import React from 'react'; import { View, Dimensions, FlatList } from 'react-native'; import DynamicTabViewScrollHeader from './DynamicTabViewScrollHeader'; import PropTypes from 'prop-types'; class DynamicTabView extends React.Component { constructor(props) { super(props); this.state = { index: this.props.defaultIndex, containerWidth: Dimensions.get('window').width, begin_offset: null, end_offset: null, }; this.defaultStyle = defaultStyle; } componentDidMount() { //HACK let wait = new Promise((resolve) => setTimeout(resolve, 100)); wait.then(() => { this.flatView.scrollToIndex({ index: this.state.index, animated: false }); this.headerRef.scrollHeader(this.state.index); }); } getItemLayout = (data, index) => ({ length: this.state.containerWidth, offset: this.state.containerWidth * index, index, }); goToPage = (index) => { this.setState({ index }); this.flatView.scrollToIndex({ index }); if (this.props.onChangeTab) { this.props.onChangeTab(index); } this.headerRef.scrollHeader(index); }; onScrollBeginDrag = (e) => { var begin_offset = e.nativeEvent.contentOffset.x; //since horizontal scroll view begin // console.log(begin_offset); this.setState({ begin_offset }); }; onScrollEndDrag = (e) => { var end_offset = e.nativeEvent.contentOffset.x; // since horizontal scroll view end // console.log(end_offset) this.setState({ end_offset }); }; // To calculate Page scroll from left->right or right->left _onCalculateIndex = (begin_offset, end_offset, width) => { var begin_offset = this.state.begin_offset; var end_offset = this.state.end_offset; var width = this.state.containerWidth; if (begin_offset < end_offset) { let index = Math.floor(begin_offset / width) + 1; // if Page scroll from left->right, index is increase by 1 if (index < this.props.data.length) { this.goToPage(index); } } else if (begin_offset > end_offset) { let index = Math.ceil(begin_offset / width) - 1; // if Page scroll from right->left, index is decrease by 1 if (index < this.props.data.length && index >= 0) { this.goToPage(index); } } }; _onLayout = (e) => { const { width } = e.nativeEvent.layout; this.setState({ containerWidth: width }); }; _renderTab = ({ item, index }) => { return ( <View style={[ { width: this.state.containerWidth }, this.defaultStyle.tabContainer, this.props.tabContainerStyle, ]} > {/* eslint-disable-next-line react/prop-types */} {this.props.renderTab(item, index)} </View> ); }; _renderHeader = () => { return ( <View style={[ this.defaultStyle.headerContainer, this.props.headerContainerStyle, ]} > <DynamicTabViewScrollHeader ref={(headerRef) => { this.headerRef = headerRef; }} data={this.props.data} goToPage={this.goToPage} selectedTab={this.state.index} headerBackgroundColor={this.props.headerBackgroundColor} headerTextStyle={this.props.headerTextStyle} headerActiveTextStyle={this.props.headerActiveTextStyle} headerUnderlayColor={this.props.headerUnderlayColor} highlightStyle={this.props.highlightStyle} tabItemContainerStyle={this.props.tabItemContainerStyle} activeTabStyle={this.props.activeTabStyle} /> </View> ); }; render() { return ( <View onLayout={this._onLayout} style={[this.defaultStyle.container, this.props.containerStyle]} > {this._renderHeader()} <FlatList {...this.props} horizontal scrollEnabled={this.props.swipeToPage} ref={(flatView) => { this.flatView = flatView; }} styleCustomization={this.props.styleCustomization} renderItem={this._renderTab} scrollEventThrottle={10} keyboardDismissMode={'on-drag'} getItemLayout={this.getItemLayout} pagingEnabled={true} onMomentumScrollBegin={this._onCalculateIndex} onScrollBeginDrag={this.onScrollBeginDrag} onScrollEndDrag={this.onScrollEndDrag} /> </View> ); } } const defaultStyle = { container: { flex: 1, }, headerContainer: { backgroundColor: 'white', }, tabContainer: { flex: 1, }, labelStyle: { color: 'white', }, indicatorStyle: { backgroundColor: 'white', marginVertical: 1, bottom: 4, //indicatorStyle is implemented in absolute in the library height: 4, }, }; DynamicTabView.defaultProps = { defaultIndex: 0, containerStyle: {}, tabContainerStyle: {}, headerContainerStyle: {}, swipeToPage: true, //styles for header headerTextStyle: {}, highlightStyle: {}, noHighlightStyle: {}, }; DynamicTabView.propTypes = { onChangeTab: PropTypes.func, styleCustomization: PropTypes.object, containerStyle: PropTypes.any, tabContainerStyle: PropTypes.any, headerContainerStyle: PropTypes.any, swipeToPage: PropTypes.any, //header style props headerBackgroundColor: PropTypes.any, headerTextStyle: PropTypes.any, headerActiveTextStyle: PropTypes.any, highlightStyle: PropTypes.any, noHighlightStyle: PropTypes.any, headerUnderlayColor: PropTypes.any, // tabItemProps activeTabStyle: PropTypes.any, tabItemContainerStyle: PropTypes.any, }; export default DynamicTabView;