Hello I want to add a draggable marker on the map "change a position of marker-based on map views"
So I use react-native-maps,
when the user swipes the map and changes his location the marker following hem so in my code I log it in the console but I can't see anything in the logs or it's not made in this way!
How can I make it draggable on the map?
here is what I want to achieve
here's my code
import React, {Component} from 'react';
import {StyleSheet, View} from 'react-native';
import MapView, {Marker} from 'react-native-maps';
// create a component
class App extends Component {
state = {
latlng: {
latitude: 35.1790507,
longitude: -6.1389008,
},
};
render() {
return (
<View style={styles.container}>
<MapView
style={styles.map}
region={{
latitude: 35.1790507,
longitude: -6.1389008,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
}}>
<Marker
draggable
coordinate={this.state.latlng}
title="Home"
onDragEnd={e => {
console.log('dragEnd', e.nativeEvent.coordinate);
}}
/>
</MapView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
// height: 400,
// width: 400,
justifyContent: 'flex-end',
alignItems: 'center',
},
map: {
...StyleSheet.absoluteFillObject,
},
});
//make this component available to the app
export default App;
You can use the onRegionChangeComplete property of MapView to achieve this.
First, change the state object like the following:
state = {
markerData: {
latitude: 35.1790507,
longitude: -6.1389008,
},
mapData: {
latitude: 35.1790507,
longitude: -6.1389008,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
},
};
Change your MapView accordingly.
<MapView
style={{flex: 1}}
region={this.state.mapData}
onRegionChangeComplete={this.handleRegionChange}>
<Marker
coordinate={this.state.markerData}
title="Home"
onDragEnd={e => {
console.log('dragEnd', e.nativeEvent.coordinate);
}}
/>
</MapView>
Then define a handler function, which changes the state values when the user drags over the map:
handleRegionChange = mapData => {
this.setState({
markerData: {latitude: mapData.latitude, longitude: mapData.longitude},
mapData,
});
};
Hope this helps.
Related
Styles under the Map component are reducing the size of the map embedded inside the component but not the actual component itself. This will be more clear in the screenshot. I intentionally wrote style={{ width: '10%', height: '10%'}} to show that even if I reduce the size by a lot, the component still remains at the same size.
Code:
import React, { Component } from 'react';
import { Map, GoogleApiWrapper, Marker } from 'google-maps-react';
var config = require("../config/config").default();
export class GoogleMap2 extends Component {
constructor(props) {
super(props);
this.state = {
stores: [{lat: 47.49855629475769, lng: -122.14184416996333},
{latitude: 47.359423, longitude: -122.021071},
{latitude: 47.2052192687988, longitude: -121.988426208496},
{latitude: 47.6307081, longitude: -122.1434325},
{latitude: 47.3084488, longitude: -122.2140121},
{latitude: 47.5524695, longitude: -122.0425407}]
}
}
displayMarkers = () => {
return this.state.stores.map((store, index) => {
return <Marker key={index} id={index} position={{
lat: store.latitude,
lng: store.longitude
}}
onClick={() => console.log("You clicked me!")} />
})
}
render() {
return (
<Map
google={this.props.google}
zoom={8}
style={{ width: '10%', height: '10%'}}
initialCenter={{ lat: 47.444, lng: -122.176}}
>
{this.displayMarkers()}
</Map>
);
}
}
export default GoogleApiWrapper({
apiKey: config.apiKey,
signature: config.signature
})(GoogleMap2)
Screenshot:
As you can see that the component is still having the height: 100% and width: 100% even though I reduced the size of the Map using the style attribute.
Please help me out in the actual reducing of its size.
There is a property of Map component named containerStyle, commonly when you want to change from the default of position "absolute". This will take care of the Map container. Change the styles accordingly.
Here is the new Map component:
<Map
google={this.props.google}
zoom={8}
style={{ width: '10%', height: '10%'}}
containerStyle={{width: "40%", height: "29%", position: "fixed"}}
initialCenter={{ lat: 47.444, lng: -122.176}}
>
{this.displayMarkers()}
</Map>
I would like to update my map to show the user location. Using the code below, I get a world map not a map of the UK, which is what the latitude and longitude should show, can anyone help?
const [location, setLocation] = useState({
initialPosition: {
latitude: 0,
longitude: 0,
latitudeDelta: 0,
longitudeDelta: 0,
},
});
const getLocationPermissions = async () => {
const granted = await request(
Platform.select({
android: PERMISSIONS.ANDROID.ACCESS_COARSE_LOCATION,
ios: PERMISSIONS.IOS.LOCATION_WHEN_IN_USE,
}),
{
title: 'DemoApp',
message: 'App would like access to your location ',
}
);
return granted === RESULTS.GRANTED;
};
useEffect(() => {
// check permission
const isGranted = getLocationPermissions();
if (isGranted) {
// get location
Geolocation.getCurrentPosition((info) => {
let lat = info.coords.latitude;
let long = info.coords.longitude;
// update state with location,latitude: 52.62869394486038
//longitude: -1.9794797216434805
var initialRegion = {
latitude: lat,
longitude: long,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
};
});
} else {
console.log('error');
}
}, []);
return (
<View style={styles.container}>
<MapView style={styles.map} initialRegion={location.initialPosition} />
</View>
);
I am guessing you are using react-native-maps MapView Component, it has a showsUserLocation boolean property.
<MapView
style={styles.map}
showsUserLocation={true}
initialRegion={location.initialPosition}
/>
Perhaps this would resolve it?
After retrieve user location from device, animate map to that region.
import * as React from "react";
import { Text, View, StyleSheet } from "react-native";
import MapView from "react-native-maps";
const App = () => {
const mapRef = React.useRef(null);
React.useEffect(() => {
// Below are mocked location in UK. Retrieve real location
// from device with Geoocation API
// latitude: 52.62869394486038
//longitude: -1.9794797216434805
const userRegion = {
latitude: 52.62869394486038,
longitude: -1.9794797216434805,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
};
mapRef.current?.animateToRegion(userRegion);
}, []);
return (
<View style={styles.container}>
<MapView
ref={mapRef}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
style={styles.mapStyle}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
paddingTop: 10,
backgroundColor: "#ecf0f1",
},
mapStyle: {
...StyleSheet.absoluteFillObject,
},
});
export default App;
Working example snack.
https://snack.expo.dev/#emmbyiringiro/9f04a3
I am starting to "learn" React Native and the first tutorial I see uses a <MapView /> component. I have tried different ways to show a map but I am not able to.
According to the video itself, it imports MapView from expo. But after reading some documentation at the Expo site I changed the import to react-native-maps. The error changes but there is no map at all.
When importing MapView from expo I get an Invariant Violation error. But when importing it from react-native-maps I get a blank screen on Android and iOS simulators.
I found this online real-time editor with their own iOS / Android / Web simulators. This is the example: https://snack.expo.io/B1H3VWtDH
This is the code. It has two lines...
import React from 'react';
import { Text, View } from 'react-native';
import MapView from 'react-native-maps';
function App() {
const [region, setRegion] = React.useState({
latitude: -30.8501718,
longitude: -50.1700368,
latitudeDelta: 0.922,
longitudeDelta: 0.0421
})
return (
<View>
<Text>Map screen</Text>
<MapView
initialRegion={region}
style={{ flex: 1 }}
/>
</View>
);
}
export default App;
What is wrong? Any comments will be appreciated.
After doing "some" research, I was able to fix it by adding CSS-in-JS attributes to the container and the map itself:
According to this issue's reply on GitHub it worked for me.
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import MapView from 'react-native-maps';
function App() {
const [region, setRegion] = React.useState({
latitude: -30.8501718,
longitude: -50.1700368,
latitudeDelta: 0.922,
longitudeDelta: 0.0421
})
return (
<View style={styles.container}>
<Text>Pantalla de inicio</Text>
<MapView
initialRegion={region}
showsUserLocation={true}
showsCompass={true}
rotateEnabled={true}
style={styles.map}
/>
</View>
);
}
export default App;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
top: 0,
left: 0,
right: 0,
bottom: 0,
position: 'absolute'
},
map: {
top: 0,
left: 0,
right: 0,
bottom: 0,
position: 'absolute'
}
});
I had the same problem, the MapView was appear in blank.
I added a style:
style={styles.mapStyle}
to MapView and it works!
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import MapView, { PROVIDER_GOOGLE } from 'react-native-maps';
import { StyleSheet, Text, View, Dimensions } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<MapView
style={{ flex: 1 }}
provider={ PROVIDER_GOOGLE }
showsUserLocation
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421}}
style={styles.mapStyle}
/>
<StatusBar translucent="false" barStyle="light-content"/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
mapStyle: {
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
},
});
I have some issue with Location Button I used react native maps Airbnb in my App,
when the first time I open the app and a map is rendered the button is disappeared but when I close the app * still in background * and reopen them the button appeared well like this GIF,
Link: https://imgur.com/37HF6H5
Note
I have seen all the issues same in the main repo of react native maps
but it's not working!
And other Q,
The App didn't ask me to open the GPS for the first time, just work when I opened manually
I have Android 8 * real device *
Here is my code
import React, { Component } from 'react';
import MapView, { Marker } from 'react-native-maps';
import { View, Text, StyleSheet, Dimensions } from 'react-native';
let { width, height } = Dimensions.get('window');
const LATITUDE = 31.78825;
const LONGITUDE = 34.4324;
const LATITUDE_DELTA = 0.0922;
const LONGITUDE_DELTA = 0.0421;
class Map extends Component {
constructor(props) {
super(props);
this.state = {
error: null,
width: width,
marginBottom: 1,
region: {
latitude: LATITUDE,
longitude: LONGITUDE,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
}
};
}
_findMe = async () => {
this.watchID = await navigator.geolocation.watchPosition(
({ coords }) => {
const { latitude, longitude } = coords
this.setState({
region: {
latitude,
longitude,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
}
})
});
await navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({
region: {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
}
})
},
(error) => console.log(JSON.stringify(error)),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
)
}
componentDidMount() {
this._findMe();
}
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchId);
}
render() {
const { region } = this.state;
return (
<View style={styles.container}>
<MapView
style={[styles.map, { width: this.state.width }]}
style={StyleSheet.absoluteFill}
onMapReady={() => console.log(this.state.region)}
showsUserLocation
followsUserLocation={true}
region={region}
showsMyLocationButton={true}
// style={StyleSheet.absoluteFill}
textStyle={{ color: '#bc8b00' }}
containerStyle={{ backgroundColor: 'white', borderColor: '#BC8B00' }}
>
<Marker
coordinate={this.state.region}
title="Hello"
description="description"
/>
</MapView>
{/* <Text>{this.state.region.latitude}</Text> */}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'space-between',
padding: 30,
flex: 1,
alignItems: 'center'
},
map: {
position: 'absolute',
zIndex: -1,
top: 0,
left: 0,
right: 0,
bottom: 0,
},
});
export default Map;
I know this is an old question but I wanted you share the solution to this bug on android platform.
There are two ways to solve this:
Make custom button, and then onPress using animateToRegion go to users location.
The reason, you are seeing the button after reopening the app is due to repaint/rerender (which solves this issue). So in short if you cause a rerender the button will appear.
snippet to get the idea
constructor(props) {
super(props);
this.state = {
bottomMargin: 1,
};
}
<MapView
showsUserLocation
style={{
marginBottom: this.state.bottomMargin, // using state in styling
...StyleSheet.absoluteFillObject,
}}
region={this.state.region}
onRegionChangeComplete={this.onRegionChange}
onMapReady={() => this.setState({ bottomMargin: 0 })} // this will fire once onReady
/>
I want to set a marker on MapView in React Native, but I can't find any information through official documents of MapView.
If it is not allowed in that way, how can I use existed react module such as react-googlemaps in React Native?
Thank you #naoufal.
Finally I am able to display markers on map for react native IOS.
<View style={styles.container}>
<MapView style={styles.map}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0,
longitudeDelta: 0.0,
}}
>
<MapView.Marker
coordinate={{latitude: 37.78825,
longitude: -122.4324}}
title={"title"}
description={"description"}
/>
</MapView>
</View>
For map and container styles, I have used following styles:
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
map: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}
});
I have referred following link:
React native IOS- Display Markers on map
You can set markers using the annotations prop.
For example:
var markers = [
{
latitude: 45.65,
longitude: -78.90,
title: 'Foo Place',
subtitle: '1234 Foo Drive'
}
];
<MapView
region={...}
annotations={markers}
/>
import MapView, { Marker } from 'react-native-maps';
<View>
<MapView
style={styles.mapStyle}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
<Marker coordinate = {{latitude: 37.78825,longitude: -122.4324}}
pinColor = {"purple"} // any color
title={"title"}
description={"description"}/>
</MapView>
</View>
For those looking for a dynamic (e.g., from API), rather than hardcoded coordinates; here's the copy/paste snippet from one of the screens automatically generated by Expo CLI, included React Hooks:
import axios from "axios";
import MapView from "react-native-maps";
import { Dimensions, StyleSheet } from "react-native";
import { Marker } from "react-native-maps";
import { Text, View } from "../components/Themed";
export default function TabTwoScreen() {
const [markers, setMarkers] = useState(null);
useEffect(() => {
axios({
method: "GET",
url: "https://API_URL...",
headers: {
Authorization: `Bearer MY_TOKEN_ABC123...`,
Accept: "application/json",
},
})
.then((response) => {
setMarkers(response.data.results);
})
.catch((error) => {
console.log(error);
});
}, []); // "[]" makes sure the effect will run only once.
return (
<View style={styles.container}>
<Text style={styles.title}>Tab Two</Text>
<MapView style={styles.map}>
{markers &&
markers.map((marker: any, index: number) => (
<Marker
key={index}
coordinate={{
latitude: marker.location[1],
longitude: marker.location[0],
}}
title={marker.title}
description={marker.description}
/>
))}
</MapView>
</View>
);
}
const styles = StyleSheet.create({
// Add your styles here...
});
Updated code - 2020 | React Native 0.63
import MapView, { Marker } from "react-native-maps";
<MapView
style={styles.mapStyle}
region={{
latitude: this.state.mapLat,
longitude: this.state.mapLong,
latitudeDelta: 0.001663,
longitudeDelta: 0.002001,
}}
onRegionChangeComplete={this.onRegionChange}
>
<Marker
coordinate={{latitude: 51.5078788, longitude: -0.0877321}}
>
</Marker>
</MapView>
According to this issue, it's not exposed yet. You won't be able to use the web-React package either, React Native doesn't work like that.
Two suggestions:
Wait for the above issue to be resolved to get a proper API
Try and use WebView to link to a Google Map with an annotation
I'm not actually certain whether #2 is possible though.
import MapView from 'react-native-maps';
<View style={StyleSheet.absoluteFillObject}>
<MapView style={styles.map}
showsUserLocation //to show user current location when given access
loadingEnabled //to show loading while map loading
style={styles.map}
initialRegion={{
latitude,
longitude,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
{
locations && locations.map((location, index) => {
const {
coords: { latitude, longitude }
} = location;
return (
<MapView.Marker
key={index}
coordinate={{ latitude, longitude }}
title={"title"}
description={"address"}
// onPress={this.onMarkerPress(location)}
/>
)
})
}
</MapView>
</View>```
const styles = StyleSheet.create({
map: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}
});
"dependencies": {
"native-base": "^2.13.8",
"react": "16.9.0",
"react-native": "0.61.2",
"react-native-maps": "git+https://git#github.com/react-native-community/react-native-maps.git"
},
Try using this. Hope it helps to mark for many locations. Happy Coding.
Thank you #zia_qureshi. Finally I am able to display markers on map for react native android.
import MapView, { Marker } from "react-native-maps";
const App = () => {
const [region, setRegion] = useState({
latitude: 51.5078788,
longitude: -0.0877321,
latitudeDelta: 0.009,
longitudeDelta: 0.009
});
return (
<MapView
style={{ flex: 1 }}
region={region}
onRegionChangeComplete={region => setRegion(region)}
>
<Marker coordinate={{ latitude: 51.5078788, longitude: -0.0877321 }} />
</MapView>
);
};
export default App;