Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save adriancbo/6abcdba484bb5d1c7e73434768946215 to your computer and use it in GitHub Desktop.
Save adriancbo/6abcdba484bb5d1c7e73434768946215 to your computer and use it in GitHub Desktop.
Indicator Wrap Content Example by react-native-tab-view@2.10.0
/* @flow */
import * as React from 'react';
import {
StyleSheet, Text
} from 'react-native';
import {
TabBar, TabView
} from 'react-native-tab-view';
import Animated from 'react-native-reanimated';
const SCREEN_WIDTH_RATIO = 3.75;
const NAV_STATE_MAP = {
index : 0,
routes: [
{
key : 'spend',
title : 'Spend',
tabBarTextWidth: 0
},
{
key : 'refund',
title : 'Refund',
tabBarTextWidth: 0
}
]
};
type State = {
navigationState: Object,
};
type Props = {
scene: Object,
style?: Object,
onIndexChange: Function,
}
export default class IndicatorWrapContentTabView extends React.Component<Props, State> {
state = { navigationState: NAV_STATE_MAP };
_renderIndicator = (props: Object) => {
const {
position, navigationState, getTabWidth
} = props;
const inputRange = [
0,
1
];
const translateX = Animated.interpolate(position, {
inputRange : inputRange,
outputRange: inputRange.map(x => {
const i = Math.round(x);
return i * getTabWidth(i) ;
})
});
const currentIndicatorWidth = navigationState.routes[navigationState.index].tabBarTextWidth;
return (
<Animated.View
style={[
styles.container,
{
width : `${100 / navigationState.routes.length}%`,
transform: [{ translateX }]
}
]}
>
<Animated.View
style={[
styles.indicator,
{ width: currentIndicatorWidth }
]}
/>
</Animated.View>
);
};
_renderTabBarLabel = ({
route, focused
}: Object) => (
<Text
onLayout={event => {
const { width } = event.nativeEvent.layout;
const currentRouteKey = route.key;
this.setState(prevState => {
const routes = prevState.navigationState.routes.map(route => {
if (route.key === currentRouteKey) {
route.tabBarTextWidth = Math.round(width);
}
return route;
});
return {
navigationState: {
...prevState.navigationState,
index: prevState.navigationState.index,
routes
}
};
});
}}
style={
focused
? { color: 'rgb(25,29,33)' }
: { color: 'rgb(174,179,192)' }
}
>
{route.title}
</Text>
);
_renderTabBar = (props: Object) => {
let tabWidthStyle = Math.round(Dimensions.get('window').width / SCREEN_WIDTH_RATIO);
return (
<TabBar
{...props}
renderLabel={this._renderTabBarLabel}
renderIndicator={this._renderIndicator}
style={styles.tabbar}
tabStyle={[
tabWidthStyle, { height: 45 }
]}
contentContainerStyle={{
flexDirection: 'row',
flexWrap : 'wrap'
}}
/>
);
};
render() {
return (
<TabView
style={this.props.style}
navigationState={this.state.navigationState}
renderScene={this.props.scene}
lazy={true}
renderTabBar={this._renderTabBar}
onIndexChange={(index) => {
this.setState({
navigationState: {
...this.state.navigationState,
index
}
});
this.props.onIndexChange && this.props.onIndexChange(index);
}}
/>
);
}
}
const styles = StyleSheet.create({
tabbar : { backgroundColor: 'white' },
container: {
flex : 1,
alignItems : 'center',
justifyContent: 'flex-end'
},
indicator: {
height : 3,
backgroundColor: 'orange'
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment