I am having issues animating the map marker on react-native-maps application. the marker stays in the center and do not move with the blue dot. and the map screen changes abruptly.
I am using the android emulator route simulator to simulate moving around.
What I really want to achieve is to update the map marker on the map screen smooothly just like the default blue dot is doing as the current location changes.
This is what I've tried: 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,
];
}

check-in mapview