Я реализую проигрыватель панели инструментов в React Native, используя PanResponder
, но у меня есть некоторые проблемы, когда я смахиваю панель инструментов вверх, она пересекает границу экрана и по-прежнему застревает в верхней части, но я не не хочу, чтобы это произошло, я хочу, чтобы пользователь проводил пальцем по верхней панели инструментов, заставляя его оставаться в исходных точках, таких как Soundcloud App, Google musi c Player и др. c.
GIF здесь
Как мне с этим справиться?
вот код или Закуска
class ToolbarPlayer extends Component {
constructor(props) {
super(props);
this._animatedValue = new Animated.ValueXY({ x: 0, y: SCREEN_HEIGHT - 80 });
this._panResponder = PanResponder.create({
onMoveShouldSetPanResponder: () => true,
onPanResponderGrant: (event, gestureState) => {
this._animatedValue.extractOffset();
},
onPanResponderMove: (event, gestureState) => {
this._animatedValue.setValue({ x: 0, y: gestureState.dy });
},
onPanResponderRelease: (event, gestureState) => {
// Bottom player ' when user swipe player over bottom'
if (gestureState.moveY > SCREEN_HEIGHT - 110) {
Animated.spring(this._animatedValue.y, {
toValue: 0,
tension: 1,
}).start();
}
//Bottom player ' when user swipe player over top'
else if (gestureState.moveY < 120) { // Not works :\
Animated.spring(this._animatedValue.y, {
toValue: 0,
tension: 1,
}).start();
} else if (gestureState.dy < 0) {
Animated.spring(this._animatedValue.y, {
toValue: -SCREEN_HEIGHT + 120,
tension: 1,
}).start();
} else if (gestureState.dy > 0) {
Animated.spring(this._animatedValue.y, {
toValue: SCREEN_HEIGHT - 120,
tension: 1,
}).start();
}
},
});
}
render() {
const animatedHeight = {
transform: this._animatedValue.getTranslateTransform(),
};
const animatedImageHeight = this._animatedValue.y.interpolate({
inputRange: [0, SCREEN_HEIGHT - 80],
outputRange: [200, 32],
extrapolate: 'clamp',
});
const animatedSongTitleOpacity = this._animatedValue.y.interpolate({
inputRange: [0, SCREEN_HEIGHT / 2, SCREEN_HEIGHT - 80],
outputRange: [0, 0, 1],
extrapolate: 'clamp',
});
const animatedImageMarginLeft = this._animatedValue.y.interpolate({
inputRange: [0, SCREEN_HEIGHT - 80],
outputRange: [(SCREEN_WIDTH * 0.5) / 2, 5], //when image was in [Top =SCREEN_WIDTH / 2 - 100 , bottom = 5]
extrapolate: 'clamp',
});
const animatedHeaderHeight = this._animatedValue.y.interpolate({
inputRange: [0, SCREEN_HEIGHT - 80],
outputRange: [SCREEN_HEIGHT / 2, 30],
extrapolate: 'clamp',
});
const animatedBackgroundColor = this._animatedValue.y.interpolate({
inputRange: [0, SCREEN_HEIGHT - 80],
outputRange: ['rgba(0,0,0,0.5)', '#00fff0'],
extrapolate: 'clamp',
});
// Content
const animatedSongDetailsOpacity = this._animatedValue.y.interpolate({
inputRange: [0, SCREEN_HEIGHT / 2, SCREEN_HEIGHT - 80],
outputRange: [1, 0, 0],
extrapolate: 'clamp',
});
return (
<Animated.View
style={{ flex: 1, backgroundColor: animatedBackgroundColor }}>
<Animated.View
{...this._panResponder.panHandlers}
style={[
animatedHeight,
{
position: 'absolute',
left: 0,
right: 0,
zIndex: 999,
backgroundColor: '#fff',
height: SCREEN_HEIGHT,
},
]}>
<Animated.View
style={{
height: animatedHeaderHeight,
borderTopWidth: 1,
borderTopColor: '#fff',
flexDirection: 'row',
backgroundColor: '#f8f8f8',
alignItems: 'center',
}}>
{/* Minie Player "image/title/icon 'pouse/play' " */}
<View
style={{
flex: 4,
flexDirection: 'row',
alignItems: 'center',
}}>
<Animated.View
style={{
height: animatedImageHeight,
width: animatedImageHeight,
marginLeft: animatedImageMarginLeft,
}}>
<Image
style={{ flex: 1, width: null, height: null }}
source={{
uri:
'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQCMYdRsaPP2LRTVc4FvvlbmHJH-BbkFhSZpmS-oovLiEP-dkAo',
}}
/>
</Animated.View>
<Animated.Text
style={{
opacity: animatedSongTitleOpacity,
fontSize: 18,
paddingLeft: 10,
}}>
Hello World(Live)
</Animated.Text>
</View>
<Animated.View
style={{
opacity: animatedSongTitleOpacity,
flexDirection: 'row',
flex: 1,
justifyContent: 'space-around',
}}>
<Ionicons name="ios-play" size={25} />
<Ionicons name="ios-pause" size={25} />
</Animated.View>
</Animated.View>
{/* When View is open -Content */}
<Animated.View
style={{
height: animatedHeaderHeight,
opacity: animatedSongDetailsOpacity,
}}>
{/* Song details */}
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'flex-end',
}}>
<Text style={{ fontWeight: 'bold', fontSize: 22 }}>
Hello World (Live)
</Text>
<Text style={{ color: '#fa995f', fontSize: 18 }}>
Without Me - Album (Live)
</Text>
</View>
{/* Time Slider */}
<View
style={{
height: 40,
width: SCREEN_WIDTH,
alignItems: 'center',
}}>
<Text>Slider Here... </Text>
</View>
{/* Controller Icon here */}
<View
style={{
flex: 4,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-around',
}}>
<Ionicons name="ios-fastforward" size={35} />
<Ionicons name="ios-pause" size={50} />
<Ionicons name="ios-rewind" size={35} />
</View>
</Animated.View>
</Animated.View>
</Animated.View>
);
}
}
export default ToolbarPlayer;