Open ferrannp opened 7 years ago
I would do something like that, there it is.
import React, { Component, PropTypes } from 'react'
import {
Text,
View,
Animated,
StatusBar,
Dimensions,
StyleSheet,
} from 'react-native'
import Icon from 'react-native-vector-icons/Ionicons'
import {
BottomSheetBehavior,
CoordinatorLayout,
} from 'react-native-bottom-sheet-behavior'
const { width } = Dimensions.get('window')
class SimpleView extends Component {
static contextTypes = {
openDrawer: PropTypes.func,
};
state = {
scrollY: new Animated.Value(0),
};
handleSlide = (e) => {
Animated.event(
[{ nativeEvent: { offset: this.state.scrollY }}, { useNativeDriver: true }]
)(e, this.state)
}
render() {
const opacity = this.state.scrollY.interpolate({
inputRange: [0, 1],
outputRange: [0, 0.65],
})
return (
<CoordinatorLayout style={styles.container}>
<StatusBar translucent backgroundColor="rgba(0, 0, 0, 0.2)" />
<View style={styles.content}>
<View style={styles.toolbarWrapper}>
<Icon.ToolbarAndroid
navIconName={'md-menu'}
style={styles.toolbar}
titleColor="white"
title="Simple Bottom Sheet"
onIconClicked={() => this.context.openDrawer()}
/>
</View>
</View>
<Animated.View style={[styles.overlay, {opacity}]} />
<BottomSheetBehavior
peekHeight={80}
hideable={false}
onSlide={this.handleSlide}>
<View style={styles.bottomSheet}>
<View style={styles.bottomSheetHeader}>
<Text style={styles.label}>BottomSheetBehavior !</Text>
</View>
<View style={styles.bottomSheetContent}>
</View>
</View>
</BottomSheetBehavior>
</CoordinatorLayout>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
content: {
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#fff',
},
overlay: {
position: 'absolute',
top: -24,
left: 0,
right: 0,
bottom: 0,
opacity: 0,
backgroundColor: 'black',
},
toolbarWrapper: {
paddingTop: 24,
marginBottom: 24,
backgroundColor: '#4389f2',
},
toolbar: {
width,
height: 56,
},
bottomSheet: {
backgroundColor: '#4389f2',
},
bottomSheetHeader: {
padding: 28,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
bottomSheetContent: {
height: 200,
padding: 2,
alignItems: 'center',
backgroundColor: '#fff',
},
label: {
fontSize: 18,
fontWeight: 'bold',
color: '#fff',
},
})
export default SimpleView
Nice! Thank you! I was doing something similar, I added a touchable so I can collapse the BottomSheet when clicking the overlay, it might be useful to someone:
<TouchableWithoutFeedback onPress={this._setBottomSheetState}>
<Animated.View style={[styles.overlay, {
opacity: this.state.scrollY.interpolate({
inputRange: [0, 1],
outputRange: [0, 0.4],
})
}]}
pointerEvents={!this._isOpen() ? "none" : "auto"}
/>
</TouchableWithoutFeedback>
Pity we don't have this in JS so can work on iOS too, but for now, it's good in Android thanks to this lib :)
@cesardeazevedo Thanks to Flow and checking API, I think we were not using useNativeDriver
correctly, should be:
_handleSlide = (e) => {
Animated.event(
[{ nativeEvent: { offset: this.state.scrollY }}],
{ useNativeDriver: true }
)(e, this.state);
};
The thing is, like that it crashes, with false
it works. Any ideas?
Oh, so sorry about that, completely my fault, i definitely was using wrong the useNativeDriver
API.
One the things to work around would be to wrap the BottomSheetBehavior together with the createAnimatedComponent
(the FlastList Example does it), that wouldn't cause any crashes, but the transition itself doesn't seems to take any effect with useNativeDrive: true
, but i can be wrong about this approach, I will definitely investigate it, sorry about that.
@cesardeazevedo I think that for useNativeDrive
to work, your library need to handle that in the native side (because with that set to true, it returns an object not a callback).
You are right, i am also thinking in something on this direction, i am trying to getting in deep on the ScrollView implementation, and i think it could be more related on the way that we handle the Animated
API together with createAnimatedComponent
than the native itself, or something in between, i'm not sure, i'm still investigating it, i will reopen this issue for now.
Just like explained here https://material.io/guidelines/components/bottom-sheets.html#bottom-sheets-usage. Is there an easy way?
I think about having an overlay view that use some animation opacity based on the current position of the BottomSheet (full color when is expanded and starting fading color when collapsing). The overlay should also be clickable to close the bottom sheet. Maybe you have an example of it? Thanks :)