Created
April 21, 2017 08:10
-
-
Save kmagiera/710460dac3ba722bb6a8d552c343b44a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react' | |
import { View, Image, StyleSheet, ScrollView, Text, Animated, StatusBar, PixelRatio } from 'react-native' | |
import Icon from 'react-native-vector-icons/MaterialIcons'; | |
import MapView from 'react-native-maps'; | |
const AMSTERDAM = { | |
latitude: 52.3702, | |
longitude: 4.8952, | |
latitudeDelta: 0.0922, | |
longitudeDelta: 0.0421, | |
} | |
const OFFSET = 450 | |
class Maps extends Component { | |
render() { | |
return ( | |
<View style={{flex: 1}}> | |
<MapView style={{flex: 1}} initialRegion={AMSTERDAM}/> | |
<Drawer /> | |
</View> | |
) | |
} | |
} | |
class Drawer extends Component { | |
constructor(props) { | |
super(props) | |
this.state = { | |
expanded: false, | |
} | |
} | |
handleEndDrag = (e) => { | |
const targetY = e.nativeEvent.targetContentOffset.y | |
if (targetY < OFFSET) { | |
const snap = targetY < OFFSET / 3 ? 0 : OFFSET | |
this.refs["Scroll"].scrollTo({ y: snap }) | |
} | |
} | |
handleBeginDrag = (e) => { | |
this.setState({ expanded: true }) | |
} | |
handleAnimationEnd = (e) => { | |
const scrollY = e.nativeEvent.contentOffset.y | |
this.setState({ expanded: scrollY > 0 }) | |
} | |
render() { | |
return ( | |
<View style={[styles.container, { overflow: this.state.expanded ? 'visible' : 'hidden' }]}> | |
<ScrollView | |
style={styles.full} | |
stickyHeaderIndices={[1]} | |
showsVerticalScrollIndicator={false} | |
contentInset={{bottom: -255}} | |
ref="Scroll" | |
onScrollEndDrag={this.handleEndDrag} | |
onScrollBeginDrag={this.handleBeginDrag} | |
onMomentumScrollEnd={this.handleAnimationEnd} | |
> | |
<View style={styles.placeholder} /> | |
<View style={styles.header}> | |
<View style={styles.handle} /> | |
<Text style={styles.headerText}>Sticky header (pull here)</Text> | |
</View> | |
<Row icon="event-seat" text="Go watch a movie" color="#3949ab"/> | |
<Row icon="euro-symbol" text="Find some ca$$h" color="#00695c"/> | |
<Row icon="rowing" text="Random guy with a paddle" color="#827717"/> | |
<Row icon="radio" text="Very old radio" color="#6d4c41"/> | |
<Row icon="airplanemode-active" text="Fly away" color="#424242"/> | |
<Row icon="usb" text="Buy some USBs" color="#546e7a"/> | |
<Row icon="explore" text="Maybe use internet explorer" color="#e53935"/> | |
<Row icon="watch" text="Charge your watch..." color="#ff8f00"/> | |
<Row icon="wb-sunny" text="Good weather!" color="#1b5e20"/> | |
<Row icon="local-hospital" text="Need help?" color="#ad1457"/> | |
<Row icon="restaurant" text="Some fancy restaurant" color="#6a1b9a"/> | |
<Row icon="directions-bike" text="Get on a bike" color="#c0ca33"/> | |
<View style={styles.white}/> | |
</ScrollView> | |
</View> | |
) | |
} | |
} | |
const Row = ({icon, text, color}) => ( | |
<View style={styles.row}> | |
<View style={[styles.rowIconContainer, {backgroundColor: color}]}> | |
<Icon name={icon} size={20} color="white" /> | |
</View> | |
<Text style={styles.rowText}>{text}</Text> | |
</View> | |
) | |
const styles = StyleSheet.create({ | |
container: { | |
position: 'absolute', | |
left: 0, | |
right: 0, | |
top: 40 + OFFSET, | |
bottom: 0, | |
}, | |
full: { | |
marginTop: -OFFSET, | |
flex: 1, | |
}, | |
header: { | |
backgroundColor: 'white', | |
height: 62, | |
borderTopWidth: 1 / PixelRatio.get(), | |
borderBottomWidth: 1 / PixelRatio.get(), | |
borderColor: '#8C99A5', | |
alignItems: 'center', | |
}, | |
handle: { | |
width: 40, | |
height: 8, | |
borderRadius: 4, | |
backgroundColor: '#8C99A5', | |
margin: 4, | |
}, | |
placeholder: { | |
height: OFFSET, | |
}, | |
headerText: { | |
flex: 1, | |
fontSize: 22, | |
}, | |
row: { | |
height: 60, | |
flex: 1, | |
flexDirection: 'row', | |
alignItems: 'center', | |
backgroundColor: 'white', | |
borderBottomWidth: 1 / PixelRatio.get(), | |
borderColor: '#8C99A5', | |
}, | |
rowIconContainer: { | |
margin: 10, | |
width: 30, | |
height: 30, | |
borderRadius: 15, | |
alignItems: 'center', | |
justifyContent: 'center', | |
overflow: 'hidden', | |
}, | |
rowText: { | |
fontSize: 18, | |
}, | |
white: { | |
height: 255, | |
backgroundColor: 'white', | |
}, | |
}) | |
export default Maps |
@kmagiera yup Android, also the content behind is clickable on iOS but not on Android... So it looks like that getting this on Android https://material.io/guidelines/components/bottom-sheets.html#bottom-sheets-usage it is very tricky...
Hey @kmagiera - running into a similar issue with Android as above. Any pointers would be much appreciated!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ferrannp is this on iOS or android? I think the targetContentOffset may not be available on android in which case you may need to find another workaround.
As for the content behind being clickable this example should provide that. It works by changing the container size in which the scollview is placed (
this.state.expanded
is responsible for that)Sorry for late response one again