Skip to content

Commit 48c82fe

Browse files
ali-alamineExilz
authored andcommitted
[android] Add customMapStyle prop support to MapView for android (react-native-maps#808)
1 parent 5a06aaf commit 48c82fe

File tree

5 files changed

+271
-1
lines changed

5 files changed

+271
-1
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,24 @@ For Android: add the following line in your AndroidManifest.xml
172172
```
173173
For IOS: configure [App Transport Security](https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33) in your app
174174

175+
### Customizing the map style
175176

177+
Create the json object, or download a generated one from the [google style generator](https://mapstyle.withgoogle.com/).
178+
179+
```jsx
180+
// The generated json object
181+
mapStyle = [ ... ]
182+
183+
render() {
184+
return (
185+
<MapView
186+
region={this.state.region}
187+
onRegionChange={this.onRegionChange}
188+
customMapStyle={mapStyle}
189+
/>
190+
);
191+
}
192+
```
176193

177194
## Examples
178195

@@ -201,6 +218,11 @@ API could.
201218
![](http://i.giphy.com/3o6UB7poyB6YJ0KPWU.gif) ![](http://i.giphy.com/xT77Yc4wK3pzZusEbm.gif)
202219

203220

221+
### Changing the style of the map
222+
223+
![](http://i.imgur.com/a9WqCL6.png)
224+
225+
204226

205227
### Arbitrary React Views as Markers
206228

android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.google.android.gms.maps.MapsInitializer;
2121
import com.google.android.gms.maps.model.LatLng;
2222
import com.google.android.gms.maps.model.LatLngBounds;
23+
import com.google.android.gms.maps.model.MapStyleOptions;
2324

2425
import java.util.Map;
2526

@@ -92,6 +93,11 @@ public void setMapType(AirMapView view, @Nullable String mapType) {
9293
int typeId = MAP_TYPES.get(mapType);
9394
view.map.setMapType(typeId);
9495
}
96+
97+
@ReactProp(name = "customMapStyleString")
98+
public void setMapStyle(AirMapView view, @Nullable String customMapStyleString) {
99+
view.map.setMapStyle(new MapStyleOptions(customMapStyleString));
100+
}
95101

96102
@ReactProp(name = "showsUserLocation", defaultBoolean = false)
97103
public void setShowsUserLocation(AirMapView view, boolean showUserLocation) {

components/MapView.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,21 @@ const propTypes = {
6161
*/
6262
style: View.propTypes.style,
6363

64+
/**
65+
* A json object that describes the style of the map. This is transformed to a string
66+
* and saved in mayStyleString to be sent to android and ios
67+
* https://developers.google.com/maps/documentation/ios-sdk/styling#use_a_string_resource
68+
* https://developers.google.com/maps/documentation/android-api/styling
69+
*/
70+
customMapStyle: PropTypes.array,
71+
72+
/**
73+
* A json string that describes the style of the map
74+
* https://developers.google.com/maps/documentation/ios-sdk/styling#use_a_string_resource
75+
* https://developers.google.com/maps/documentation/android-api/styling
76+
*/
77+
customMapStyleString: PropTypes.string,
78+
6479
/**
6580
* If `true` the app will ask for the user's location.
6681
* Default value is `false`.
@@ -386,12 +401,15 @@ class MapView extends React.Component {
386401
}
387402

388403
_onMapReady() {
389-
const { region, initialRegion } = this.props;
404+
const { region, initialRegion, customMapStyle } = this.props;
390405
if (region) {
391406
this.map.setNativeProps({ region });
392407
} else if (initialRegion) {
393408
this.map.setNativeProps({ region: initialRegion });
394409
}
410+
if (customMapStyle) {
411+
this.map.setNativeProps({ customMapStyleString: JSON.stringify(customMapStyle) });
412+
}
395413
this.setState({ isReady: true });
396414
}
397415

example/App.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import LiteMapView from './examples/LiteMapView';
3131
import CustomTiles from './examples/CustomTiles';
3232
import ZIndexMarkers from './examples/ZIndexMarkers';
3333
import StaticMap from './examples/StaticMap';
34+
import MapStyle from './examples/MapStyle';
3435

3536
const IOS = Platform.OS === 'ios';
3637
const ANDROID = Platform.OS === 'android';
@@ -140,6 +141,7 @@ class App extends React.Component {
140141
[LiteMapView, 'Android Lite MapView'],
141142
[CustomTiles, 'Custom Tiles', true],
142143
[ZIndexMarkers, 'Position Markers with Z-index', true],
144+
[MapStyle, 'Customize the style of the map', true],
143145
]
144146
// Filter out examples that are not yet supported for Google Maps on iOS.
145147
.filter(example => ANDROID || (IOS && (example[2] || !this.state.useGoogleMaps)))

example/examples/MapStyle.js

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
import React from 'react';
2+
import {
3+
StyleSheet,
4+
View,
5+
Dimensions,
6+
} from 'react-native';
7+
8+
import MapView from 'react-native-maps';
9+
10+
const { width, height } = Dimensions.get('window');
11+
12+
const ASPECT_RATIO = width / height;
13+
const LATITUDE = 37.78825;
14+
const LONGITUDE = -122.4324;
15+
const LATITUDE_DELTA = 0.0922;
16+
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO;
17+
18+
const customStyle = [
19+
{
20+
elementType: 'geometry',
21+
stylers: [
22+
{
23+
color: '#242f3e',
24+
},
25+
],
26+
},
27+
{
28+
elementType: 'labels.text.fill',
29+
stylers: [
30+
{
31+
color: '#746855',
32+
},
33+
],
34+
},
35+
{
36+
elementType: 'labels.text.stroke',
37+
stylers: [
38+
{
39+
color: '#242f3e',
40+
},
41+
],
42+
},
43+
{
44+
featureType: 'administrative.locality',
45+
elementType: 'labels.text.fill',
46+
stylers: [
47+
{
48+
color: '#d59563',
49+
},
50+
],
51+
},
52+
{
53+
featureType: 'poi',
54+
elementType: 'labels.text.fill',
55+
stylers: [
56+
{
57+
color: '#d59563',
58+
},
59+
],
60+
},
61+
{
62+
featureType: 'poi.park',
63+
elementType: 'geometry',
64+
stylers: [
65+
{
66+
color: '#263c3f',
67+
},
68+
],
69+
},
70+
{
71+
featureType: 'poi.park',
72+
elementType: 'labels.text.fill',
73+
stylers: [
74+
{
75+
color: '#6b9a76',
76+
},
77+
],
78+
},
79+
{
80+
featureType: 'road',
81+
elementType: 'geometry',
82+
stylers: [
83+
{
84+
color: '#38414e',
85+
},
86+
],
87+
},
88+
{
89+
featureType: 'road',
90+
elementType: 'geometry.stroke',
91+
stylers: [
92+
{
93+
color: '#212a37',
94+
},
95+
],
96+
},
97+
{
98+
featureType: 'road',
99+
elementType: 'labels.text.fill',
100+
stylers: [
101+
{
102+
color: '#9ca5b3',
103+
},
104+
],
105+
},
106+
{
107+
featureType: 'road.highway',
108+
elementType: 'geometry',
109+
stylers: [
110+
{
111+
color: '#746855',
112+
},
113+
],
114+
},
115+
{
116+
featureType: 'road.highway',
117+
elementType: 'geometry.stroke',
118+
stylers: [
119+
{
120+
color: '#1f2835',
121+
},
122+
],
123+
},
124+
{
125+
featureType: 'road.highway',
126+
elementType: 'labels.text.fill',
127+
stylers: [
128+
{
129+
color: '#f3d19c',
130+
},
131+
],
132+
},
133+
{
134+
featureType: 'transit',
135+
elementType: 'geometry',
136+
stylers: [
137+
{
138+
color: '#2f3948',
139+
},
140+
],
141+
},
142+
{
143+
featureType: 'transit.station',
144+
elementType: 'labels.text.fill',
145+
stylers: [
146+
{
147+
color: '#d59563',
148+
},
149+
],
150+
},
151+
{
152+
featureType: 'water',
153+
elementType: 'geometry',
154+
stylers: [
155+
{
156+
color: '#17263c',
157+
},
158+
],
159+
},
160+
{
161+
featureType: 'water',
162+
elementType: 'labels.text.fill',
163+
stylers: [
164+
{
165+
color: '#515c6d',
166+
},
167+
],
168+
},
169+
{
170+
featureType: 'water',
171+
elementType: 'labels.text.stroke',
172+
stylers: [
173+
{
174+
color: '#17263c',
175+
},
176+
],
177+
},
178+
];
179+
180+
class MapStyle extends React.Component {
181+
constructor(props) {
182+
super(props);
183+
184+
this.state = {
185+
};
186+
}
187+
188+
render() {
189+
return (
190+
<View style={styles.container}>
191+
<MapView
192+
provider={this.props.provider}
193+
style={styles.map}
194+
initialRegion={{
195+
latitude: LATITUDE,
196+
longitude: LONGITUDE,
197+
latitudeDelta: LATITUDE_DELTA,
198+
longitudeDelta: LONGITUDE_DELTA,
199+
}}
200+
customMapStyle={customStyle}
201+
/>
202+
</View>
203+
);
204+
}
205+
}
206+
207+
MapStyle.propTypes = {
208+
provider: MapView.ProviderPropType,
209+
};
210+
211+
const styles = StyleSheet.create({
212+
container: {
213+
...StyleSheet.absoluteFillObject,
214+
justifyContent: 'flex-end',
215+
alignItems: 'center',
216+
},
217+
map: {
218+
...StyleSheet.absoluteFillObject,
219+
},
220+
});
221+
222+
module.exports = MapStyle;

0 commit comments

Comments
 (0)