Skip to content

Instantly share code, notes, and snippets.

@knowbody
Created September 28, 2016 14:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save knowbody/39714588fc56445dbcea9bcc28b700d0 to your computer and use it in GitHub Desktop.
Save knowbody/39714588fc56445dbcea9bcc28b700d0 to your computer and use it in GitHub Desktop.
ScrollTabBar for react-native-tab-view
import React, { Component } from 'react';
import {
Animated,
Dimensions,
StyleSheet,
ScrollView,
TouchableOpacity,
View,
Text,
} from 'react-native';
import { Ionicons } from '@exponent/vector-icons';
import TouchableItem from './TouchableItem';
const VISIBLE_TABS = 5.5;
const styles = StyleSheet.create({
tabBar: {
backgroundColor: 'black',
flexDirection: 'row',
flexWrap: 'nowrap',
elevation: 4,
height: 76,
},
tabLabel: {
color: '#fff',
margin: 8,
fontSize: 20,
fontWeight: '500'
},
tab: {
width: Dimensions.get('window').width / VISIBLE_TABS,
alignSelf: 'center',
},
tabItem: {
flex: 1,
padding: 8,
alignItems: 'center',
justifyContent: 'center',
},
indicator: {
backgroundColor: '#fff',
position: 'absolute',
left: 0,
bottom: 0,
right: 0,
height: 2,
},
});
export default class ScrollTabBar extends Component {
static defaultProps = {
renderLabel: ({ route }) =>
route.title ? <Text style={styles.tabLabel}>{route.title}</Text> : null,
renderIndicator: (props) => {
const { layout: { width }, position } = props;
const { routes } = props.navigationState;
const translateX = Animated.multiply(position, new Animated.Value(width / VISIBLE_TABS));
return (
<Animated.View
style={[
styles.indicator,
{ width: width / VISIBLE_TABS, transform: [{ translateX }] },
props.indicatorStyle
]}
/>
);
}
};
render() {
const { position } = this.props;
const { routes, index } = this.props.navigationState;
const inputRange = routes.map((x, i) => i);
return (
<View style={[styles.tabBar, this.props.style]}>
<TouchableOpacity
style={styles.tab}
onPress={() => this.props.onBack()}
>
<Ionicons
size={30}
color={this.props.backIconColor || `#fff`}
style={[{ alignSelf: 'center', marginTop: 20 }, this.props.closeIconStyle]}
name="ios-arrow-down"
/>
</TouchableOpacity>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
>
{routes.map((route, i) => {
const focused = index === i;
const outputRange = inputRange.map(inputIndex => inputIndex === i ? 1 : 0.7);
const opacity = position.interpolate({
inputRange,
outputRange,
});
const scene = {
route,
focused,
index: i,
};
const label = this.props.renderLabel ? this.props.renderLabel(scene) : null;
return (
<TouchableItem
key={route.key}
style={styles.tab}
onPress={() => this.props.jumpToIndex(i)}
>
<Animated.View style={[styles.tabItem, { opacity }, this.props.tabStyle]}>
{this.props.renderLabel ? this.props.renderLabel(scene) : null}
</Animated.View>
</TouchableItem>
);
})}
{this.props.renderIndicator ? this.props.renderIndicator(this.props) : null}
</ScrollView>
</View>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment