To display this on a map, we have this map screen component which currently just has some dummy content
and now we need to be able to render an interactive map and for this, expo again has got us covered.
There, you find the
map view package.
Now this behind the scenes uses a package named React Native maps which you can also use in non-expo
apps,
by the way many of these packages can be used in non-expo apps and that's something I will come back
to in the building apps without expo module
but for now we can simply conveniently install this by running this command and this will install the
React Native maps package and
then we can use it as we see it here in this example.
By the way also check out the official documentation at this link to see way more usage examples in
there because there, you can learn all about how to use this package,
some examples are also shown here in this module of course.
So let's run expo install react-native-maps to install this package here and this will then
allow us to use various components that render interactive maps.
So let's wait for that to finish and with that finished, in the map screen component, we can start using
that map.
Now in there, to use the map, we can import map view from React Native map, so from this package we just
installed and that will allow us to render a map on the screen.
Now how does that work?
Well let's go here into our map screen and instead of returning this view here, I'll return a map view
like that.
Now the map view can be a self-closing tag
for now, we can later also add some markers in there but for now let's just render it like this
and now you need to configure this map view. To be precise,
it needs a region props which tells it where it should be focused on when it loads,
so which map part or which part of the world it should focus on when it loads.
So we need to create such a region here and I'll store that in a constant named map region and a region
is actually an object with four properties and you have to name them like this - latitude and not lat
but really latitude written out, longitude,
latitudeDelta and longitudeDelta.
The deltas basically set the zoom factor because this describes how much space you can see around
the center which you describe with these two points.
So that describes a point, together with the two deltas,
it describes a surface.
So now here, we can start with some dummy values before we
then later also make sure that we can prepopulate this.
So here, I'll set this to dummy value of 37.78 and -122.43
which is in the Bay Area around the Google headquarters and here, latitudeDelta will
take 0.0922 and then 0.0421,
I found that this works quite well as a region.
Of course you can experiment with these numbers but then in the end, pass in this map region here.
Now this should render a map on the screen,
now we just need to be able to reach it and for that
let me go back to the location picker and I want to reach it in two different ways -
one is with the help of a button which I didn't add yet. Besides the get user location button, I want to
have a second button which should sit next to the first one, so I'll add a view to wrap both and then
move this button in here and have a second button in there and this button will generally be configured
in the same way but I will say pick on map and of course, I'll trigger a different method,
different function, here I want to trigger a function which is the pick on map handler and I'll therefore
use this here
and that's one way of selecting this. The other way of selecting this or of going to the map is by clicking
on the map preview. Now before I implement this, let me quickly style this view that holds the two buttons.
I'll give it a style identifier of actions and then down there, actions can be configured in a relatively
straightforward way.
I want to have the item sit next to each other, so flex direction will be a row not column. Justify content
can be space around to distribute the available free space around both buttons, I'll take a width of 100%
for this row and that's actually it.
Now with that, I have my buttons here,
now we need to make sure that we can also tap the map preview and for that, let me go to map preview and
actually wrap this, not in a view but in a touchable component and here I'll just use touchable opacity,
of course you could also go for a different touchable components based on the platform you're running
on,
I want to keep this relatively straightforward, so I'll just replace this view here with touchable opacity,
have my style here,
that's fine but also of course have the onPress handler and there, I want to trigger a function which
I expect to get from outside via props.
I'll just call this onPress too but you could give this prop any name you want.
This now allows us to add an onPress prop on the map preview,
so here in the location picker, I can listen to onPress on the map preview and there of course,
I want to trigger the same function as when I click on the button down there.
I want to trigger the pick on map handler,
so that's what I do.
Now the pick on map handler should simply go to the map screen right,
so in there we can say props.navigation.navigate map and that's it for the second.
So if we now save this, we should be able to reach this full screen interactive map where we can't select
a place yet but at least we can view it.
So now if I click on the plus here and then pick on map, I get an error,
now why is that? Well that's totally unrelated to native modules. You might remember that the navigation prop
is only available on components which are directly loaded as screens which the location picker of course
isn't. Now there
are various workarounds,
there would be a higher order component we can use,
we can also install a React navigation specific hooks package
but here I'll take a simple approach and just make sure that I have a navigation prop on location picker
by going to the new place screen which is where I do use the location picker
and there I'll set this navigation prop and forward props.navigation which I here do have available
because this is a component directly loaded through a navigator,
so now I'm just forwarding access to my navigation props. And with that if we now go back and click this,
we do load this map here or at least a map screen
but where is the map?
Well the map is invisible because, and that's important, for your map you need to add a style and here, I'll
add styles.map and it can be a very simple style but you just need to define how big it should be
because by default, it will not occupy any space.
So by just setting flex to one here and telling it it should take all the space it gets, just by doing
that, you will make sure that you see a map.
So now with that if you click on this, here is our map getting loaded. Now also worth noting, on iOS you
automatically use Apple Maps, though you can also use Google Maps there if you want to, the official
docs tell you how, on Android you always use google maps.
So here if I click on pick on map,
we will also see that once we load that new screen, here it is. Now of course, we can also go to that screen
by clicking on our preview here,
that's what we set up right,
so that also works, of course also works on iOS.
And by the way, the animation here isn't super smooth, on a real device it will be,
so that's not a problem, that's just here on the emulator.
So with that we have our map here and on this map, we can scroll. Again, on the simulator it might be a
bit small, on a real device it won't be.
So here you can scroll around, you will also be able to pinch and zoom later, so you can do all of that and
with that, we see the map.
Now the map is usable but of course, we can't pick a place on there yet,
so that's the next thing we'll need to change.