我在react-native-maps应用程序上对地图标记进行动画处理时遇到问题。标记停留在中心,不随蓝点移动。并且地图屏幕突然发生变化。
我正在使用android模拟器路线模拟器来模拟移动。
我真正想要实现的是平滑地更新地图屏幕上的地图标记,就像默认蓝点在当前位置发生变化时所做的那样。
这是我尝试过的: MapScreen.js
const [
mapRef,
requestLocationPermission,
position,
watchId,
subscribeLocationLocation,
getOneTimeLocation,
setPosition,
] = useLocation();
const [darkMode, setDarkMode] = useState(theme.dark);
useEffect(() => {
requestLocationPermission();
subscribeLocationLocation(user._id);
return () => {
Geolocation.clearWatch(watchId);
};
}, []);
const toggleDarkMode = () => setDarkMode(!darkMode);
console.log(darkMode);
return (
<View style={styles(colors).mapContainerStyles}>
<StatusBar backgroundColor="transparent" translucent={true} />
<View style={styles(colors).container}>
<MapView
userInterfaceStyle={darkMode ? 'dark' : 'light'}
key={darkMode}
ref={mapRef}
region={position}
onRegionChange={() => position}
onRegionChangeComplete={position => setPosition(position)}
style={styles(colors).mapStyle}
initialRegion={position}
customMapStyle={darkMode ? mapStyle : {}}
showsUserLocation={true}
showsMyLocationButton={true}
followsUserLocation={true}
showsCompass={true}
scrollEnabled={true}
zoomEnabled={true}
pitchEnabled={true}
rotateEnabled={true}>
<Marker
draggable
coordinate={{
latitude: position.latitude,
longitude: position.longitude,
}}
onDragEnd={e =>
Alert.alert(JSON.stringify(e.nativeEvent.coordinate))
}
pinColor="green"
title={'Test Marker'}
description={`${position.latitude}, ${position.longitude}`}
/>
</MapView>
<View style={styles(colors).darkModeStyles}>
<DefaultText
textColor={darkMode ? 'white' : 'black'}
textStyle={styles(colors).darkModeTextStyles}
bold={true}
textString={`${darkMode ? 'Light' : 'Dark'} Mode`}
/>
<Switch
trackColor={{false: '#767577', true: '#81b0ff'}}
thumbColor={darkMode ? '#f5dd4b' : '#f4f3f4'}
ios_backgroundColor="#3e3e3e"
onValueChange={toggleDarkMode}
value={darkMode}
/>
{/* <Button onPress={toggleDarkMode} title="Dark Mode" /> */}
</View>
</View>
<View style={styles(colors).informationStyles}>
<Button
onPress={() => getOneTimeLocation()}
title="Get current location"
/>
<Information navigation={navigation} />
</View>
</View>
);
};
useLocation.js
import React, {useState} from 'react';
import {PermissionsAndroid, Platform} from 'react-native';
import Geolocation from '@react-native-community/geolocation';
import socket from './socket';
export default function useLocation() {
// const [currentLongitude, setCurrentLongitude] = useState(0);
// const [currentLatitude, setCurrentLatitude] = useState(0);
const [locationStatus, setLocationStatus] = useState('');
const [watchId, setWatchId] = useState(null);
const mapRef = React.useRef(null);
const [position, setPosition] = useState({
latitude: 9.077751,
longitude: 8.6774567,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
});
const requestLocationPermission = async () => {
console.log('REQUESTING LOCATION PERMISSION!!!!!');
if (Platform.OS === 'ios') {
getOneTimeLocation();
// subscribeLocationLocation();
} else {
console.log('INSIDE OF ANDROID PLATFORM');
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Location Access Required',
message: 'This App needs to Access your location',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('ANDROID PERMISSION HAS BEEN GRANTED!!!');
//To Check, If Permission is granted
getOneTimeLocation();
// subscribeLocationLocation();
} else {
setLocationStatus('Permission Denied');
}
} catch (err) {
console.warn(err);
}
}
};
const getOneTimeLocation = () => {
console.log('GETTING ONE TIME LOCATION!!!');
setLocationStatus('Getting Location ...');
Geolocation.getCurrentPosition(
//Will give you the current location
pos => {
console.log('===============================');
console.log(pos.coords);
console.log('===============================');
const crd = pos.coords;
setLocationStatus('You are Here');
//getting the Latitude from the location json
// setCurrentLongitude(crd.longitude);
// //Setting state Longitude to re re-render the Longitude Text
// setCurrentLatitude(crd.latitude);
console.log('SETTING NEW POSITION GOTTEN FROM DEVICE!!!');
setPosition({
latitude: crd.latitude,
longitude: crd.longitude,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
});
mapRef.current?.animateToRegion(position);
//Setting state Latitude to re re-render the Longitude Text
},
error => {
setLocationStatus(error.message);
console.log(error);
},
{enableHighAccuracy: true, timeout: 25000, maximumAge: 3600000},
);
};
const subscribeLocationLocation = userId => {
console.log('SUBSCRIBING TO LOCATION!!!');
const watchid = Geolocation.watchPosition(
pos => {
console.log(pos);
// setLocationStatus('You are Here');
const crd = pos.coords;
console.log(crd);
setPosition({
latitude: crd.latitude,
longitude: crd.longitude,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
});
// mapRef.current?.animateToRegion(position);
//Setting state Latitude to re re-render the Longitude Text
if (
position.latitude == crd.latitude &&
position.longitude == crd.longitude
) {
console.log('Same position as before');
} else {
socket.emit('updateLocation', {position, userId});
}
},
error => {
setLocationStatus(error.message);
},
{
enableHighAccuracy: true,
distanceFilter: 5000,
interval: 5000,
fastestInterval: 2000,
},
);
setWatchId(watchid);
};
return [
mapRef,
requestLocationPermission,
position,
watchId,
subscribeLocationLocation,
getOneTimeLocation,
setPosition,
];
}
签到地图视图
onUserLocationChange={async (e) => {{/* you can her update the marker but that will make the blue point always appear if u want to remove it u can set showsUserLocation={false} and use const cordsMarkerLocation = await Location.watchPositionAsync(
{ accuracy: Location.Accuracy.High },
(location) => {
setLocationMarker(location.coords);
}
);*/}}