Skip to content

Commit c8bbc93

Browse files
Jasan SinghJasan Singh
authored andcommitted
added scroolable tabview along with a custom tabbar that uses icons instead of default text labels
1 parent 9737b0c commit c8bbc93

File tree

9 files changed

+193
-4
lines changed

9 files changed

+193
-4
lines changed

app/components/TabBar/TabBar.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import React from 'react'
2+
import PropTypes from 'prop-types'
3+
import { View, StyleSheet, Text, ScrollView } from 'react-native'
4+
import ScrollableTabView from 'react-native-scrollable-tab-view'
5+
6+
export default function TabBar(props) {
7+
return (
8+
<ScrollableTabView
9+
style={{marginTop: 20 }}
10+
initialPage={0}
11+
renderTabBar={() => <props.CustomTabBar />}
12+
>
13+
<ScrollView tabLabel="ios-paper" style={styles.tabView}>
14+
<View style={styles.card}>
15+
<Text>News</Text>
16+
</View>
17+
</ScrollView>
18+
<ScrollView tabLabel="ios-people" style={styles.tabView}>
19+
<View style={styles.card}>
20+
<Text>Friends</Text>
21+
</View>
22+
</ScrollView>
23+
<ScrollView tabLabel="ios-chatboxes" style={styles.tabView}>
24+
<View style={styles.card}>
25+
<Text>Messenger</Text>
26+
</View>
27+
</ScrollView>
28+
<ScrollView tabLabel="ios-notifications" style={styles.tabView}>
29+
<View style={styles.card}>
30+
<Text>Notifications</Text>
31+
</View>
32+
</ScrollView>
33+
<ScrollView tabLabel="ios-list" style={styles.tabView}>
34+
<View style={styles.card}>
35+
<Text>Other nav</Text>
36+
</View>
37+
</ScrollView>
38+
</ScrollableTabView>
39+
)
40+
}
41+
42+
TabBar.propTypes = {}
43+
TabBar.defaultProps = {}
44+
45+
const styles = StyleSheet.create({
46+
tabView: {
47+
flex: 1,
48+
padding: 10,
49+
backgroundColor: 'rgba(0,0,0,0.01)',
50+
},
51+
card: {
52+
borderWidth: 1,
53+
backgroundColor: '#fff',
54+
borderColor: 'rgba(0,0,0,0.1)',
55+
margin: 5,
56+
height: 150,
57+
padding: 15,
58+
shadowColor: '#ccc',
59+
shadowOffset: { width: 2, height: 2, },
60+
shadowOpacity: 0.5,
61+
shadowRadius: 3,
62+
},
63+
})

app/components/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ export Hamburger from './Icons/Hamburger'
99
export Settings from './Settings/Settings'
1010
export Close from './Icons/Close'
1111
export FlashNotification from './FlashNotification/FlashNotification'
12+
export TabBar from './TabBar/TabBar'

app/containers/Navigator/ReactModoroNavigator.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import React, { Component } from 'react'
22
import PropTypes from 'prop-types'
33
import { Navigator, Platform } from 'react-native'
4-
import { SplashContainer, FooterTabsContainer, SettingsContainer } from '~/containers'
4+
import { SplashContainer, FooterTabsContainer, SettingsContainer, TabBarContainer } from '~/containers'
55

66
export default class ReactModoroNavigator extends Component {
77
static propTypes = {
88
isAuthed: PropTypes.bool.isRequired
99
}
1010
renderScene = (route, navigator) => {
1111
if (this.props.isAuthed === false) {
12-
return <SplashContainer navigator={navigator} />
12+
return <TabBarContainer navigator={navigator} />
1313
} else if (route.settings === true) {
1414
return <SettingsContainer navigator={navigator} />
1515
} else {

app/containers/TabBar/CustomTabBar.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import React, { Component } from 'react'
2+
import PropTypes from 'prop-types'
3+
import { StyleSheet, Text, View, TouchableOpacity, Animated } from 'react-native'
4+
import Icon from 'react-native-vector-icons/Ionicons'
5+
6+
export default class CustomTabBar extends Component {
7+
static propTypes = {
8+
goToPage: React.PropTypes.func,
9+
activeTab: React.PropTypes.number,
10+
tabs: React.PropTypes.array,
11+
}
12+
static defaultProps = {}
13+
constructor(props) {
14+
super(props)
15+
this.state = {}
16+
this.tabIcons = []
17+
}
18+
19+
componentDidMount() {
20+
this._listener = this.props.scrollValue.addListener(this.setAnimationValue)
21+
}
22+
23+
setAnimationValue = ({ value }) => {
24+
this.tabIcons.forEach((icon, i) => {
25+
const progress = Math.min(1, Math.abs(value - i))
26+
icon.setNativeProps({
27+
style: {
28+
color: this.iconColor(progress),
29+
},
30+
})
31+
})
32+
}
33+
34+
// color between rgb(59,89,152) and rgb(204,204,204)
35+
iconColor = (progress) => {
36+
const red = 59 + (204 - 59) * progress
37+
const green = 89 + (204 - 89) * progress
38+
const blue = 152 + (204 - 152) * progress
39+
return `rgb(${red}, ${green}, ${blue})`
40+
}
41+
42+
render() {
43+
const containerWidth = this.props.containerWidth
44+
const numberOfTabs = this.props.tabs.length
45+
46+
const tabUnderlineStyle = {
47+
position: 'absolute',
48+
width: containerWidth / numberOfTabs,
49+
height: 2,
50+
backgroundColor: 'navy',
51+
bottom: 0,
52+
}
53+
54+
const left = this.props.scrollValue.interpolate({
55+
inputRange: [0, 1, ], outputRange: [0, containerWidth / numberOfTabs, ]
56+
})
57+
return (
58+
<View style={[styles.tabs, this.props.style, ]}>
59+
{this.props.tabs.map((tab, i) => {
60+
return <TouchableOpacity key={tab} onPress={() => this.props.goToPage(i)} style={styles.tab}>
61+
<Icon
62+
name={tab}
63+
size={30}
64+
color={this.props.activeTab === i ? 'rgb(59,89,152)' : 'rgb(204,204,204)'}
65+
ref={(icon) => { this.tabIcons[i] = icon; }}
66+
/>
67+
</TouchableOpacity>;
68+
})}
69+
<Animated.View style={[tabUnderlineStyle, { left, }, this.props.underlineStyle, ]} />
70+
</View>
71+
)
72+
}
73+
}
74+
75+
const styles = StyleSheet.create({
76+
tab: {
77+
flex: 1,
78+
alignItems: 'center',
79+
justifyContent: 'center',
80+
paddingBottom: 10,
81+
},
82+
tabs: {
83+
height: 45,
84+
flexDirection: 'row',
85+
paddingTop: 5,
86+
borderWidth: 1,
87+
borderTopWidth: 0,
88+
borderLeftWidth: 0,
89+
borderRightWidth: 0,
90+
borderBottomColor: 'rgba(0,0,0,0.05)',
91+
},
92+
})
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React, { Component } from 'react'
2+
import PropTypes from 'prop-types'
3+
import CustomTabBar from './CustomTabBar'
4+
import { TabBar } from '~/components'
5+
6+
export default class TabBarContainer extends Component {
7+
8+
static propTypes = {}
9+
static defaultProps = {}
10+
constructor(props) {
11+
super(props)
12+
this.state = {}
13+
}
14+
15+
render() {
16+
return (
17+
<TabBar CustomTabBar={CustomTabBar}/>
18+
)
19+
}
20+
}

app/containers/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ export AppContainer from './App/AppContainer'
44
export FooterTabsContainer from './FooterTabs/FooterTabsContainer'
55
export HomeContainer from './Home/HomeContainer'
66
export LeaderboardContainer from './Leaderboard/LeaderboardContainer'
7-
export SettingsContainer from './Settings/SettingsContainer'
7+
export SettingsContainer from './Settings/SettingsContainer'
8+
export TabBarContainer from './TabBar/TabBarContainer'

ios/ReactModoro.xcodeproj/project.pbxproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,9 @@
669669
CreatedOnToolsVersion = 6.2;
670670
TestTargetID = 13B07F861A680F5B00A75B9A;
671671
};
672+
13B07F861A680F5B00A75B9A = {
673+
DevelopmentTeam = 8MYGVV84ZF;
674+
};
672675
2D02E47A1E0B4A5D006451C7 = {
673676
CreatedOnToolsVersion = 8.2.1;
674677
ProvisioningStyle = Automatic;
@@ -1144,6 +1147,7 @@
11441147
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
11451148
CURRENT_PROJECT_VERSION = 1;
11461149
DEAD_CODE_STRIPPING = NO;
1150+
DEVELOPMENT_TEAM = 8MYGVV84ZF;
11471151
FRAMEWORK_SEARCH_PATHS = (
11481152
"~/Documents/FacebookSDK",
11491153
"$(PROJECT_DIR)",
@@ -1169,6 +1173,7 @@
11691173
buildSettings = {
11701174
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
11711175
CURRENT_PROJECT_VERSION = 1;
1176+
DEVELOPMENT_TEAM = 8MYGVV84ZF;
11721177
FRAMEWORK_SEARCH_PATHS = (
11731178
"~/Documents/FacebookSDK",
11741179
"$(PROJECT_DIR)",

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"react-native-animatable": "^1.1.1",
1515
"react-native-fbsdk": "^0.5.0",
1616
"react-native-navbar": "^1.7.1",
17+
"react-native-scrollable-tab-view": "^0.6.5",
1718
"react-native-slider": "^0.9.1",
1819
"react-native-vector-icons": "^4.0.1",
1920
"react-redux": "^5.0.4",

yarn.lock

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3731,6 +3731,12 @@ react-native-navbar@^1.7.1:
37313731
version "1.7.1"
37323732
resolved "https://registry.yarnpkg.com/react-native-navbar/-/react-native-navbar-1.7.1.tgz#de0e6f8c2156c7e984bb43c76732bd2437b7df0f"
37333733

3734+
react-native-scrollable-tab-view@^0.6.5:
3735+
version "0.6.5"
3736+
resolved "https://registry.yarnpkg.com/react-native-scrollable-tab-view/-/react-native-scrollable-tab-view-0.6.5.tgz#61a46b88d637b192b4868ef3322963f21d46c55f"
3737+
dependencies:
3738+
react-timer-mixin "^0.13.3"
3739+
37343740
react-native-slider@^0.9.1:
37353741
version "0.9.1"
37363742
resolved "https://registry.yarnpkg.com/react-native-slider/-/react-native-slider-0.9.1.tgz#f8ea5e3c48aa3577656719b911fd7dd4c62bf81a"
@@ -3856,7 +3862,7 @@ react-test-renderer@16.0.0-alpha.6:
38563862
fbjs "^0.8.9"
38573863
object-assign "^4.1.0"
38583864

3859-
react-timer-mixin@^0.13.2:
3865+
react-timer-mixin@^0.13.2, react-timer-mixin@^0.13.3:
38603866
version "0.13.3"
38613867
resolved "https://registry.yarnpkg.com/react-timer-mixin/-/react-timer-mixin-0.13.3.tgz#0da8b9f807ec07dc3e854d082c737c65605b3d22"
38623868

0 commit comments

Comments
 (0)