我是 react-native 动画 API 和 PanResponder API 的新手。
我想创建谷歌地图克隆 UI 和卡片动画,在结果后显示。
我想创建卡片,当用户向上滑动时,卡片到达屏幕顶部,当用户向下滑动时,卡片应该调整到原始位置。
我想实现的谷歌地图演示
我已经为此实现了一些代码,但我面临的问题是卡片在顶部方向上移出屏幕(在卡片到达顶部位置后向上滑动)。有时,向下滑动有效,但并非总是如此。
应用程序.js
import React, { useEffect, useState } from "react";
import {
SafeAreaView,
View,
Text,
Dimensions,
PanResponder,
Animated,
} from "react-native";
import { Searchbar, FAB } from "react-native-paper";
import MapView from "react-native-maps";
import * as Location from "expo-location";
const SCREEN_HEIGHT = Dimensions.get("window").height;
const SCREEN_WIDTH = Dimensions.get("window").width;
const App = () => {
const [latitute, setLatitute] = useState(0);
const [longitute, setLongitute] = useState(0);
const [isLoading, setIsLoading] = useState(true);
const pan = useState(
new Animated.ValueXY({ x: 0, y: SCREEN_HEIGHT - 200 })
)[0];
const panResponder = useState(
PanResponder.create({
onMoveShouldSetPanResponder: () => true,
onPanResponderGrant: () => {
pan.extractOffset();
return true;
},
onPanResponderMove: (e, gestureState) => {
pan.setValue({ x: 0, y: gestureState.dy });
},
onPanResponderRelease: (e, gestureState) => {
if (gestureState.moveY > SCREEN_HEIGHT - 200) {
Animated.spring(pan.y, {
toValue: 0,
tension: 1,
useNativeDriver: true,
}).start();
} else if (gestureState.moveY < 200) {
Animated.spring(pan.y, {
toValue: 0,
tension: 1,
useNativeDriver: true,
}).start();
} else if (gestureState.dy < 0) {
Animated.spring(pan.y, {
toValue: -SCREEN_HEIGHT + 200,
tension: 1,
useNativeDriver: true,
}).start();
} else if (gestureState.dy > 0) {
Animated.spring(pan.y, {
toValue: SCREEN_HEIGHT - 200,
tension: 1,
useNativeDriver: true,
}).start();
}
},
})
)[0];
const animatedHeight = {
transform: pan.getTranslateTransform(),
};
useEffect(() => {
(async () => {
let { status } = await Location.requestPermissionsAsync();
let location = await Location.getCurrentPositionAsync({});
console.log(location);
setLatitute(location.coords.latitude);
setLongitute(location.coords.longitude);
setIsLoading(false);
})();
}, []);
return (
<SafeAreaView
style={{
display: "flex",
flex: 1,
}}
>
{!isLoading && (
<View>
<MapView
style={{ width: SCREEN_WIDTH, height: SCREEN_HEIGHT }}
showsUserLocation
initialRegion={{
latitude: latitute,
longitude: longitute,
latitudeDelta: 0.01,
longitudeDelta: 0.01,
}}
/>
<Searchbar
placeholder="Search"
style={{
position: "absolute",
top: 10,
margin: 10,
}}
icon="menu"
onIconPress={() => {}}
/>
<FAB
style={{
position: "absolute",
top: SCREEN_HEIGHT * 0.8,
left: SCREEN_WIDTH * 0.8,
}}
icon="plus"
onPress={() => console.log("Pressed")}
/>
<Animated.View
style={[
animatedHeight,
{
position: "absolute",
right: 0,
left: 0,
width: SCREEN_WIDTH,
height: SCREEN_HEIGHT,
backgroundColor: "#0af",
borderTopLeftRadius: 25,
borderTopRightRadius: 25,
zIndex: 10,
},
]}
{...panResponder.panHandlers}
>
<View>
<Text>Hi</Text>
</View>
</Animated.View>
</View>
)}
</SafeAreaView>
);
};
export default App;