Skip to content

Commit 7ac6e47

Browse files
committed
add collapsable bar functionality
* add collpasableBar api props * replace the Container View with a ScrollView to allow collapsable functionality * user collapasable functionality just if it's passed in props * add collapsable to Examples
1 parent 8c0d6e4 commit 7ac6e47

File tree

3 files changed

+93
-6
lines changed

3 files changed

+93
-6
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React from 'react';
2+
import {
3+
StyleSheet,
4+
View,
5+
} from 'react-native';
6+
7+
import ScrollableTabView, { DefaultTabBar, } from 'react-native-scrollable-tab-view';
8+
import Icon from 'react-native-vector-icons/Ionicons';
9+
10+
export default React.createClass({
11+
render() {
12+
const collapsableComponent = (
13+
<View>
14+
<Icon name='logo-apple' color='black' size={100} style={styles.topIcon} />
15+
<Icon name='logo-android' color='#A4C639' size={100} style={styles.topIcon} />
16+
</View>
17+
);
18+
19+
return <ScrollableTabView collapsableBar={collapsableComponent}
20+
tabBarBackgroundColor="white"
21+
renderTabBar={()=><DefaultTabBar />}
22+
>
23+
<View tabLabel='iOS'>
24+
<Icon name='logo-apple' color='black' size={300} style={styles.icon} />
25+
<Icon name='ios-phone-portrait' color='black' size={300} style={styles.icon} />
26+
<Icon name='logo-apple' color='#DBDDDE' size={300} style={styles.icon} />
27+
<Icon name='ios-phone-portrait' color='#DBDDDE' size={300} style={styles.icon} />
28+
</View>
29+
<View tabLabel='Android'>
30+
<Icon name='logo-android' color='#A4C639' size={300} style={styles.icon} />
31+
<Icon name='logo-android' color='black' size={300} style={styles.icon} />
32+
<Icon name='logo-android' color='#A4C639' size={300} style={styles.icon} />
33+
</View>
34+
</ScrollableTabView>;
35+
},
36+
});
37+
38+
const styles = StyleSheet.create({
39+
icon: {
40+
width: 300,
41+
height: 300,
42+
alignSelf: 'center',
43+
},
44+
topIcon: {
45+
width: 100,
46+
height: 100,
47+
alignSelf: 'center',
48+
},
49+
});

examples/FacebookTabsExample/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import ScrollableTabsExample from './ScrollableTabsExample';
1212
import OverlayExample from './OverlayExample';
1313
import FacebookExample from './FacebookExample';
1414
import DynamicExample from './DynamicExample';
15+
import CollapsableExample from './CollapsableExample';
1516

1617
const HomeScreen = React.createClass({
1718
navigationOptions: {
@@ -56,6 +57,13 @@ const HomeScreen = React.createClass({
5657
>
5758
<Text>Dynamic tabs example</Text>
5859
</TouchableOpacity>
60+
61+
<TouchableOpacity
62+
style={styles.button}
63+
onPress={() => navigate('Collapsable')}
64+
>
65+
<Text>Collapsable content example</Text>
66+
</TouchableOpacity>
5967
</View>;
6068
},
6169
});
@@ -67,6 +75,7 @@ const App = new StackNavigator({
6775
Overlay: { screen: OverlayExample, },
6876
Facebook: { screen: FacebookExample, },
6977
Dynamic: { screen: DynamicExample, },
78+
Collapsable: { screen: CollapsableExample, },
7079
});
7180

7281
export default App;

index.js

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const ScrollableTabView = React.createClass({
3939
scrollWithoutAnimation: PropTypes.bool,
4040
locked: PropTypes.bool,
4141
prerenderingSiblingsNumber: PropTypes.number,
42+
collapsableBar: PropTypes.node,
4243
},
4344

4445
getDefaultProps() {
@@ -179,12 +180,20 @@ const ScrollableTabView = React.createClass({
179180
_composeScenes() {
180181
return this._children().map((child, idx) => {
181182
let key = this._makeSceneKey(child, idx);
183+
let element;
184+
185+
if (!!this.props.collapsableBar) {
186+
element = this.state.currentPage === idx ? child : null;
187+
} else {
188+
element = this._keyExists(this.state.sceneKeys, key) ? child : <View tabLabel={child.props.tabLabel} />;
189+
}
190+
182191
return <SceneComponent
183192
key={child.key}
184-
shouldUpdated={this._shouldRenderSceneKey(idx, this.state.currentPage)}
185-
style={{width: this.state.containerWidth, }}
193+
shouldUpdated={!!this.props.collapsableBar || this._shouldRenderSceneKey(idx, this.state.currentPage)}
194+
style={{ width: this.state.containerWidth, }}
186195
>
187-
{this._keyExists(this.state.sceneKeys, key) ? child : <View tabLabel={child.props.tabLabel}/>}
196+
{element}
188197
</SceneComponent>;
189198
});
190199
},
@@ -216,6 +225,10 @@ const ScrollableTabView = React.createClass({
216225
ref: this._children()[currentPage],
217226
from: prevPage,
218227
});
228+
229+
if (this.contentScrollDistance >= this.collapsableBarHeight) {
230+
this.contentView.scrollTo({ x: 0, y: this.collapsableBarHeight, animated: false, });
231+
}
219232
},
220233

221234
_handleLayout(e) {
@@ -233,6 +246,16 @@ const ScrollableTabView = React.createClass({
233246
return React.Children.map(children, (child) => child);
234247
},
235248

249+
renderCollapsableBar() {
250+
if (!this.props.collapsableBar) {
251+
return null;
252+
}
253+
254+
return React.cloneElement(this.props.collapsableBar, {
255+
onLayout: event => {this.collapsableBarHeight = event.nativeEvent.layout.height;},
256+
});
257+
},
258+
236259
render() {
237260
let overlayTabs = (this.props.tabBarPosition === 'overlayTop' || this.props.tabBarPosition === 'overlayBottom');
238261
let tabBarProps = {
@@ -267,12 +290,18 @@ const ScrollableTabView = React.createClass({
267290
[this.props.tabBarPosition === 'overlayTop' ? 'top' : 'bottom']: 0,
268291
};
269292
}
270-
271-
return <View style={[styles.container, this.props.style, ]} onLayout={this._handleLayout}>
293+
const ContainerView = this.props.collapsableBar ? ScrollView : View;
294+
295+
return <ContainerView style={[styles.container, this.props.style, ]}
296+
onLayout={this._handleLayout}
297+
ref={contentView => {this.contentView = contentView;}}
298+
onMomentumScrollEnd={event => {this.contentScrollDistance = event.nativeEvent.contentOffset.y;}}
299+
stickyHeaderIndices={this.props.collapsableBar ? [1, ] : []}>
300+
{this.renderCollapsableBar()}
272301
{this.props.tabBarPosition === 'top' && this.renderTabBar(tabBarProps)}
273302
{this.renderScrollableContent()}
274303
{(this.props.tabBarPosition === 'bottom' || overlayTabs) && this.renderTabBar(tabBarProps)}
275-
</View>;
304+
</ContainerView>;
276305
},
277306
});
278307

0 commit comments

Comments
 (0)