Tip:
Highlight text to annotate it
X
ANKUR KOTWEL: Welcome everyone to an Android
Developer Lab Plus.
For those of you that are joining us for the first time,
Android Developer Lab Plus is a show where we go into-- we
do deep dives in Android topics.
So this week, we're talking about the Maps API version 2
that we launched for Android late last year.
We did an introductory dive into it.
And this is a little bit deeper into some
more advanced topics.
So firstly, let me introduce myself.
I'm Ankur Kotwell.
And I'm a developer advocate on the Android team.
And I'm joining you from Sydney, Australia.
I'll pass it over to Jan Felix, who's next.
JAN-FELIX SCHMAKEIT: Yeah, I'm Jan-Felix Schmakeit.
I'm a developer programs engineer on Android.
And I'm also based in Sidney.
TONY CHAN: Hi, my name's Tony Chan.
I'm also a developer advocate, coming here from Hong Kong.
So, hello.
ANKUR KOTWEL: Great.
Yep, great.
Thanks Tony and Jan-Felix.
So Jan-Felix is one of our newest recruits.
You've probably seen him on the Santa Tracker video.
And if you haven't, please go and have a look at the Google
Developers Live presents Santa Tracker for Android, which
heavily uses the Map View API that we're going to be
discussing today.
So that particular session goes into more of the process
behind building the app, the vision, and really how we make
full use of the Map View API library.
So with that being said, let's now move on to today's
presentation.
So Jan-Felix, perhaps you can get us started.
Are you able to see the slides, just to confirm?
JAN-FELIX SCHMAKEIT: Yeah, yeah.
Looks all good from here.
ANKUR KOTWEL: OK.
All yours.
JAN-FELIX SCHMAKEIT: OK.
So, yeah.
So the last [INAUDIBLE] class was giving you a bit of
introduction into the Map View, kind of getting started,
getting your first project up and running, getting the API
key and stuff set up.
And so this week, we will look at some of the
more advanced topics.
So we're-- if you could go to the next slide.
We're going to actually show you a bit of code.
We're going to show you a few examples as well.
So we're going to talk about InfoWindows because there are
different types and ways you can create Info Windows.
We're talking about polylines and--
yeah, polylines.
We're talking a bit about Camera animations.
Because that's one of the really cool features and
something that's really impressive
in the new Map View.
We're going to talk a bit about markers, in particular
custom icons that you will have on markers.
All the demos and all these samples are actually from the
Map View demo project.
So if you want to follow along, want to look at it
later on, you can just get the demo project from the SDK and
just look at the code from there.
OK.
And I think with that we can then dive
into our first topic.
So InfoWindows--
I'm sure most of you have seen these before.
So an InfoWindow is basically pop-up that's
attached to a marker.
So when you click on a marker, that's when the
InfoWindow pops up.
And one thing here to remember is that you can only have one
Info Window at a time.
You tap on the marker, and you get one of these pop-ups.
So let's look at the demo.
There are different types of InfoWindows you can set up.
So you tap on it, and you get-- that was the default
InfoWindow you can get.
There's a custom InfoWindow contents.
And you can also have a complete custom InfoWindow.
And we're going to talk about them in a bit more detail now
to show you how you can actually go about creating
them and setting them up.
ANKUR KOTWEL: So Jan-Felix --sorry to cut in-- what I
might do is just play that one more time because they go a
little bit quickly.
JAN-FELIX SCHMAKEIT: Yeah.
ANKUR KOTWEL: Just talk us through that video
again, could you?
JAN-FELIX SCHMAKEIT: Yes, sure.
So the first thing-- we have a default InfoWindow, we have a
title and a snippet, then we have a custom info content,
where we have-- it looks like a normal InfoWindow, like
default one.
But we have our own content in there, our own layout.
And this is the custom InfoWindow where we have our
own layout.
We have our own backgrounds.
It's completely done by us.
We have some more examples later on in the presentation.
You can see exactly what it looks like and what the
differences are.
So let's look and the InfoWindows in [INAUDIBLE].
So I just said, there are three different types--
default.
And the default one is basically where you have title
and snippet, just basically just plain text.
You can't really customize it any other way.
You can specify title, You can specify snippet.
When you tap on a marker, that pops up.
Custom contents--
that's where you can actually replace a content that goes
inside an InfoWindow.
So you keep the bubble.
That's the default InfoWindow.
But you can actually put your layout in there.
So you can arrange text in any way you want.
You can put your own views in there and so on.
And a custom InfoWindow is going to be completely replace
the entire InfoWindow.
So you can have your own Info bubble, use your own
background, and make it look and style it how you want it
to look like.
So let's look at--
Let's start at the beginning.
Let's look at an example for one of those default
InfoWindows on the next slide, on the slide here.
Basically, all you have to do is you have to add a marker.
Obviously, you have to set the position.
And you just set a title of the snippet.
And as soon as you set the title, the Map View knows that
you want to use the forward implementation of the
InfoWindow.
So in this case, it automatically knows if you
have a title in bold.
And you have a snippet there in the lighter grey color.
And that's all you have to do.
And that's your default implementation.
So it's really easy to get started with that.
But what if you want to do something a bit more advanced?
And you want to put an image in there.
Or you want to style text a bit differently.
Or you want to have different textures in
there you want to update.
That's were custom content comes in.
And the basic idea is that you keep the fourth InfoWindow
bubble, so you don't have to worry about adding the outline
to it, making sure it's centered and all
that kind of stuff.
We just supply a view, a layout.
That's basically what's drawn inside that InfoWindow.
So if you look at some code--
let's look at the layout.
So basically, what we're doing here is we are using a normal
layouts XML file that you've used before.
And in this case, we have a linear layout.
And we have image view in there.
And then we have another--
sorry, another linear layout with text view and another
text view in it.
And basically, all we're doing --if you
go to the next slide--
is basically just inflating that and returning that.
And the way out go about this is by using
an InfoWindow editor.
You basically have to register this InfoWindow editor.
You have to create an Info Window editor.
And basically, there are two methods.
There is the getInfoContents and getInfoWindow.
When you just want to override the content of it, all have to
do is return the view you want to have in the your InfoWindow
from the getInfoContents method.
So whatever you want to put into the InfoWindow, you just
have to return from getInfoContents.
And in our case here, the render method that we're not
showing here, all we're doing there is just inflating a
layout, just as usual.
We're setting our text viewer.
We're updating the image, view, setting the image.
And that's all we're doing.
Then you're just returning the view at the end.
And that's how you can have custom
content in the Info Window.
If you go next slide, you can see there's a custom Window.
And then you can see you have a bit of a gradient in the
background.
So InfoWindow [INAUDIBLE]
a bit of a gradient and the corners around it as well.
And they basically it's the same idea.
You just supply a view.
And that view gets thrown as the Info Window.
So you don't get the default bubble around it.
You just get your view that you've returned.
So if you look at the code, the only difference, the only
thing we have changed is basically we've added a
background to it.
And the trick is to--
if you've used a Nine-Patch for that.
So Nine-Patch means that the image gets scaled up
automatically and stretched in way that makes sense.
In our case here, we're stretching it so that you
always have a gradient at the bottom.
And you're not stretching it past the nose at the bottom
that sits on top of the marker.
And that's the trick to it.
And that's your you custom Info Window.
If you look at the code for this-- again, we're using an
InfoWindow editor.
But this time, we have to return the view from the get
Info Window method instead.
So you have to return null from get Info Window contents,
otherwise that's the one that's going to be used.
So if you return null there and you're return to the view
in get Info Window, that's all you have to do.
And that's what gets drawn instead.
Yeah, so that's really quite simple, right?
So you know how to inflate a layout.
You've used layouts in [INAUDIBLE] before.
But there are few issues with InfoWindow, a few things you
have to be aware of.
One really big thing is that InfoWindows are not live.
So it's not like any other view [INAUDIBLE].
It's not like other views you've used before.
So basically, the Info Window gets rendered to a canvas
beforehand.
So you can't change the text on it live.
You can't change the image that comes.
You can't have custom controls on it like
other buttons or something.
So you have to be aware of that.
So you can't change the text on it unless you recreate the
InfoWindow, you hide it, and display it again.
And because it's rendered in such a way, you also can't
have other listeners on it.
So all you can do is you can register a
InfoWindowClickListener.
And basically, you get an event back when somebody taps
on the InfoWindow.
So by default, it just hides the InfoWindow.
But that's how you would hook into that.
Yeah that's it, all about InfoWindows.
And I think now we have Tony telling us how to draw an
Android in Sidney.
ANKUR KOTWEL: Actually, Jan-Felix, before we just go
ahead, I'm just going to go back a couple of slides, just
point out a couple of things here.
The interesting thing is on this custom window you showed,
you mentioned that we have a gradient.
And we can provide our own border for this.
And you showed us a Nine-Patch here.
The important thing to realize here is things like the shadow
for the window is something that we've added in on
Nine-Patch itself.
It's something the library won't add for you, right?
JAN-FELIX SCHMAKEIT: Yeah, that's right.
So if you want to have the shadow behind it or anything
else, you want to take back on [INAUDIBLE], you
have to do it yourself.
You basically have to provide a different image there.
ANKUR KOTWEL: Yeah, so it takes your image verbatim,
including the little triangle that you see at the bottom
that shows that this is the marker that it's coming from.
So just keep that in mind as you use these more advanced
InfoWindows that you provide everything.
The more custom you go, the more you have
to provide as well.
JAN-FELIX SCHMAKEIT: Yeah, yeah.
That's right.
ANKUR KOTWEL: OK.
Thanks for that.
Tony?
TONY CHAN: Yeah.
Thanks Jan-Felix and Ankur.
So for polylines and polygons, we do have some samples in our
type of project.
But it's only showing lines and rectangles or circle.
So I want to do something a little bit more interesting
today and show you guys how to draw an Android
figure on the map.
So next slide please.
So before that let's go take a look at a quick demo.
So this an Android centering on Sidney.
So we can just play around and move it.
And also we can treat the color, the transparency, the
alpha a little bit.
Right now, I'm changing the color.
And then we can adjust the width of the border, the
borderline as well.
So it's just a quick demo showing what you can do with
polylines and polygons.
Next slide please.
So basically what polylines and polygons do is allow you
guys, developers, to draw shapes on the map.
One thing that's very important is the location, the
points you specify, is in a particular order.
So we'll talk a little more about that later.
Basically, all of these location coordinates are
latitudes and longitudes.
Polylines will display as line segments.
And polygons will just form lines enclosing an area and
create a shape.
But pretty much both of them built from
coordinates, from points.
Next slide.
Yeah.
Both polylines and polygons, they share common properties.
For example, you can change colors, the widths, and the
visibility of those objects.
And for polygons, because its a shape, so you can also
change the fill color as well.
Next slide.
So here's a quick [INAUDIBLE]
input to show you how to add the polylines on the map
quickly and follow the same path,
just like adding markers.
So you have Google Map object.
And then you just do an AddPolyline.
Then you specify a polyline options.
In this here, you add two coordinates and then it will
draw the line for you.
Next slide.
Here's an example of how you change color and width.
One thing you notice is the polyline options object will
return itself after you set a parameter.
So that allows you actually to change all these methods.
So in this example here, I can change the color and the width
at the same time in one line of code.
It's like--
Yeah.
Here in an another example of how to add a polygon.
So for polygons, also follow the same patterns.
You specify a polygon option.
You just need to provide a list of LatLng.
So here you can provide more than two points.
And it will draw the polygon for you.
So we'll go dive into a little bit more detail how a polygon
is drawn in future slides.
Next side please.
ANKUR KOTWEL: So Tony, I have a question here.
TONY CHAN: Yeah?
ANKUR KOTWEL: As you can see, the labels show up on top of
the polylines.
I believe markers are the same, right?
Markers will always show on top of a polyline or polygon,
rather than the other way around.
TONY CHAN: Yeah, I believe so.
And also there is, in the API, there's a scene [INAUDIBLE]
concept.
So if you have multiple polygons, things like that,
and you can actually arrange these polygons in a particular
order using the index.
ANKUR KOTWEL: That's really useful to know.
Thank you.
TONY CHAN: So one thing I want to point out for polygon is
the points you specify must be in counterclockwise order in
order for the field color to work correctly.
So let me use the diagram here to explain a little bit.
So if you draw--
let's say you have a sphere, a circle.
If you draw a line, a circle, within the area.
If you draw it counterclockwise, the thing
actually enclosing in that counterclockwise circle is the
area actually the color is going to be filled.
So in the case here on the right, you can see the circle
is in the clockwise order.
So if you try to imagine you're looking from inside,
from the back--
so it's actually the outside area is actually enclosing.
If you try to imagine, like it's
actually enclosing within--
if you draw a circle anticlockwise.
So that's why when you try to draw a polygon, you always
have to think about drawing it from a counterclockwise order,
so that the right area is going to field
the color you want.
It takes a little bit of thinking to try to imagine the
right hand side.
But this is something you want to keep in mind.
Next slide.
For polygons, you can also change the color and width.
And the method signature's a little bit--
the name is a little bit different.
So for polygon, it's fill color and then stoke width.
Next slide.
One thing interesting about polygons is it allows you to
create some holes.
So in here we call it hollow polygon, within a polygon.
So one thing--
I used this concept to actually draw
the eyes of the Android.
So for the eyes, you just need to specify some points, so
that the API will draw the circles for you.
And after that, after you create those two circle
polygons, you add it to the original polygon using the
method at hold.
And that's how I achieved the effect of having a transparent
eye for the Android.
Next slide.
So here is--
as I mentioned before, we're going to talk a little bit in
more detail how to draw the Android body.
So the digram here shows what kind of points you need to
specify in order to achieve the effect of having an
Android figure body.
So the first point is actually on the right, the top right.
And then you try to draw the semicircle shape using a whole
bunch of points.
We will talk about how to generate these points using an
equation later.
And then, after you draw the semicircle, you need to create
a straight line on the left.
So that's why you need to specify another coordinate on
the lower left corner.
And then the last one is the lower right corner.
And after you specify all these points, the API will
just connect these dots together and then fill the
shape with colors you specified.
Remember, we're using the counterclockwise principle.
And that's why enclosing area is in green in this case.
Next slide.
So now it gets to the equation part.
So how to draw that semicircle?
So it turns out if you go to Wikipedia and try to figure a
way to draw a circle or semicircle, you will find an
equation like the one showing here.
It looks pretty complicated.
But it will help when you look at a figure like this.
So this is a general ellipse equation.
And the phi angle is--
if you try to actually shift the ellipse from the x-axis.
So in this case, the b is the short distance from the center
point of the ellipse to the phi of the ellipse.
And the a is actually the longer
width side of the ellipse.
And acmyc is the center coordinate of the ellipse.
But the good news is if you're not trying to draw a curve
actually with an angle, you can actually greatly simplify
this equation much further.
So next slide, please.
So if we set the phi to zero, then actually everything
becomes much easier.
Because a lot of sine, cosine parameters will become zero
and cancel out.
So we have a much simpler equation here, which is just
the center point plus a cosine theta and b sine theta.
So the theta part allows you to draw, to select some
points, samples, so that you can use those point to draw it
on the map.
So the next slide will show you some code-- how to use
that equation.
So here I create a polygon options.
So let's say I want to draw 400 points to get the curve.
So in usual case, if we want to draw a circle, the phase
variable you probably want to use 2pi divided by
the number of points.
But in this case, I want to draw a semicircle.
So instead of 2pi, I use pi divided by number of points.
And then you have a full loop, going through all these four
hundred points.
And apply the equation, this exact same equation you saw on
top, but in code.
So you use the center of the city you point at.
In this case, I am using Sidney.
So xcmyc is the color coordinate of Sidney.
And then a and b is the width and height of the Android head
you want to have.
So it just some numbers and then multiply by sine theta
and cosine theta in this case in the equation.
So this way you can generate all these points for you to
draw the Android figure.
So I hope that helps you guys understand how to use polygon
and polyline [INAUDIBLE].
Thank you.
JAN-FELIX SCHMAKEIT: Yeah, thanks Tony.
That looks really quite cool.
Yeah.
So now that we have a few things on the map, let's talk
about animating the camera.
We have an example here, a little demo, that shows you
some of the features that you can use.
This is, again, straight from the API demo.
So basically, you can go back and forth
between Sidney and Bondi.
And the Camera animates.
So we're changing the
orientation, change the rotation.
We're changed the tilt.
You can zoom in and zoom out.
And everything is animated.
But if you don't want animations, you can turn them
off as well.
So you can jump straight to a particular location.
And that's what we're going to talk about next.
So if you go to the next slide--
so we're moving the camera.
So there are two ways of doing it.
So either you can animate the camera.
Or you can move the camera.
And animating means the camera actually moves from point A to
point B. So it's animated.
And to do that you have to use the animateCamera method on a
Google Maps object.
And basically you supply a CameraUpdate.
That's mandatory.
And the CameraUpdate basically says, this where the Camera
should point at next.
And we'll talk about that in a second.
The next thing--
you can supply its duration.
So we can say, OK, how long should the animation last for?
And you can register a Callback, so you're notified
when the animation's cancelled or is finished.
But if you don't want animations, you can also move
the Camera.
That's in the next slide.
So we can basically say, on my Google Maps
object, move the Camera.
And all you have to supply there is just the
CameraUpdate, which tells you where the Camera is
going to point at.
So if you go to the next slide--
let's talk about and these CameraUpdate
objects a bit more.
So basically, a CameraUpdate object tells Google Maps how
the Camera should move and what the Camera point at.
At to create one of these, you just use a
CameraUpdateFactory.
And basically, there are a couple of methods you can use
to create one of these objects.
So, for example, if you just want to change the target--
so what the map pointing at, what the center of the map is.
You can use the new LatLng method.
You can just say, OK, point to this LatLng.
If you have a couple of points you want to have on the map,
you can use the LatLngBounds method, and basically just
supply a list of LatLng positions.
And the CameraUpdate makes sure that all these points are
part of the Camera.
You can specify a LatLng and a Zoom level.
You can also scroll the map.
So here, you specify the number of pixels you want to
scroll over a map.
And that's animated, the scroll, if you use the
animateCamera method.
You can zoom in or zoom out.
And it basically means zoom in one Zoom level.
So you don't specify how much you want to zoom in
by or zoom out by.
You just say zoom in or zoom out, just like you already
pressed one of plus or minus buttons
that you've seen before.
You can also use zoomBy and zoomTo.
And basically zoomBy means, OK, and zoom by
this many Zoom levels.
So zoom by 3.5 Zoom levels or 10 or something like that.
Or you can also specify just a Zoom level, rather than
specifying anything else.
And that's how you create one of these CameraUpdate objects
that you then use for the animate or moveCamera methods.
And here, on the next slide, we have a few simple examples.
So if you want to move the Camera to Sidney-- so we want
to keep its current orientation then, its tilt and
Zoom level--
oh, sorry.
In this case, we're changing the Zoom level as well.
So if you want to move the Camera--
we basically called the new LatLng Zoom Method on the
CameraUpdateFactory.
And you have to specify a LatLng object, in this case
that's the center of Sydney.
We can also specify Zoom level because we are using LatLng
Zoom Method.
And what we're doing is-- we basically go to our Maps
object and say move Camera, and here's our Camera update.
And then the Cameras move there straightaway.
There's [INAUDIBLE].
If you want to animate it-- so here's an example.
We're using--
this time we're using the Zoom In, Zoom In CameraUpdate.
We are basically zooming in one Zoom level.
And all we have to do is, again, on you Google Maps
object, called your Animate Camera Method and just supply
a CameraUpdate.
In this case, we're using a Zoom In CameraUpdate object
that we're getting from the CameraUpdateFactory.
So in this case we're not supplying a
length or anything else.
That's cool.
But we actually have full control
over the entire Camera.
So you can specify the target.
You can specify the bearings, or the
orientation of the Camera.
You can specify the tilt, so what angle should the Camera
be pointing at.
And you can also specify Zoom.
Level.
So if you want to specify all these things, just a few of
these things.
You have to use a CameraPosition.Builder.
And the idea is-- you use a CameraPosition.Builder to
build a CameraPosition.
And then you use the CameraUpdateFactory to create
a CameraUpdate.
So the next slide, you will see an example that makes it a
bit more obvious.
So the basic idea is first recreate a CameraPosition.
So we say, OK, using a CameraPosition.Builder--
and can chain all of these statement together.
That's quite nice.
So first, we have to a target, so what should the Camera be
pointing at.
You can specify Zoom level.
You can specify the bearing, the orientation.
You can specify the tilt, the angle.
Then we just build the object.
And so they're actually are not all mandatory.
So you can specify just a few of them.
So if you want to specify just a Zoom level or just bearing
or tilt or something, you can do that as well.
So we create our CameraPosition
using the Build Method.
And then we basically just pass that CameraPosition
object to a CameraUpdateFactory method.
So in this case, the method is called new CameraPosition.
And all you have to do is supply that object into the
new CameraPosition method.
You get a CameraUpdate back that you can just use in your
animateCamera or your moveCamera method.
That sounds really confusing.
But it's actually not too bad when you think about it.
You have to try the CameraPosition, create a
CameraUpdate from the Position.
And then you can use it to animate or move the Camera.
So now we're now animating the Camera.
But we're also--
sometimes you're interested to know when the animation is
finished or when the animation is interrupted.
And if you want to use those features, you have to register
a CancelableCallback.
And the basic idea is you create one of these CallBacks.
You have an unfinished and un-cancelled method--
sorry, unfinished and un-cancelled.
And that code when the animation is interrupted or
when the animation is finished.
And you just have to supply that Callback when you
actually fire-off the animation.
And when you use the animateCamera method, you have
to supply your CameraUpdate.
And you can also supply the Callback there.
That way you get notified when the animation is finished or
is interrupted.
Yeah.
That's just about Camera animations.
And we make quite heavy use of that for the Santa Tracker
application.
So if you want to find out a bit more about how we use some
of these features, have a to look at the GDL Santa Tracker
Android session.
So it's quite interesting.
So let's talk about makers a bit more.
So a marker basically specifies a
single point on a map.
So think about it like a pin.
You put a pin on a map somewhere.
On the next slide, you can see some of the
properties you can define.
So we've seen the position before.
So you have to say where the marker should be, obviously.
You can specify the title and snippet.
That's what's used for the default InfoWindow
implementation.
You can also specify whether it's draggable or not.
That means you can pick up the marker from the
map and move it around.
And you have an example of that a bit later on.
You can make a marker visible or invisible.
And then we have the Icon.
So you can actually change the Icon that the marker has, so
basically the image.
So you can specify a different image you want to use for the
marker instead.
And if you use different Icons, you also probably want
to look at the Anchor.
And the Anchor basically says how is the image placed in
relation to the position that's specified.
Because it's right on top, bit to the left
and bit to the right.
And we have an example of that as well.
So let's talk about custom marker Icons first.
Because I think that's quite interesting.
So an Icon actually comes from a BitmapDiscriptor.
So it's not just a Bitmap.
It's a BitmapDiscriptor.
And to get one of these, you have to use a
BitmapDiscriptorFactory, so another Factory method with
which you can use.
So you can use a default marker.
So defaultMarker is basically the standard marker you've
seen on the map.
We have an example on the next slide.
You can load it in from an Asset.
You can load it from a direct Bitmap, if
you've generated it.
You can get it from a file.
Or you can just use it from the resource, using the
standard Android resource folders that you can use.
So on the next slide, you can see a sample implementation
using the default marker.
So if you just use a default marker icon, you just say--
OK, here's a new marker object.
Here's the marker options, and here's the position, and you
don't specify anything else, you're going get a red marker
there on the map.
But the defaultMarker Factory method from the
BitmapDiscriptorFactory is actually quite smart.
So you can actually specify the color you want for your
default marker.
So you don't necessarily have to always implement your own
Bitmaps or your own Icons.
You might even just be able to take advantage of this.
In this case here, we've specified--
we've added a blue maker.
So you just say--
OK, which hue value do you want to use?
So if you want to specify a value, a color value.
You just use the BitmapDiscriptorFactory.Default
marker method.
And there you can specify a color between zero and 360.
And that's what's then used for the Icon.
But a bit more interesting is even you can
add your own image.
So as I said before, you get it from a resource.
You can load it from the assets.
You can get it from a file.
You can get it a Bitmap.
And here's an example where we load an
image in from the resources.
So we basically have a drawable.
It's called--
It's just an arrow here.
And we use the BitmapDiscriptor
Factory.fromResource method to load that in.
And that's quite easy.
But there's an issue with that.
Because custom--
these images look and behave differently
from the default marker.
So you might have to specify an anchor.
So an anchor basically says, OK, in relation to the
position of the marker--
So will that long position be specified?
Where should we place the image?
So by default--
if you think back to the default marker, you have pin
that the kind of points to a position on the map.
And when the marker actually touches the map, it's at the
bottom center.
So at the bottom and 50% from on left, in the center.
And if you want to specify your own anchor, what you have
to do is you have to specify the ratio of where
it should be placed.
So we have u and v--
very easy to have to specify.
And this is coming from the ratio of the image.
So 0,0 is the top left.
And then 1,1 is the bottom right.
And here's an example that shows you how you can use
those values.
So the top right, for example, is this 1,0.
And here's an example that I put together.
It shows you the impact of these anchor values
and what they do.
So we're using a default marker here, just a stock
[INAUDIBLE] marker.
But we're changing where it's anchored
to the LatLng position.
So the default is .5 and 1.
So that's the bottom center.
And as you can see, that's exactly where it's
touching the map.
And on the image you see, you can see the actual latitude
and longitude we've specified.
That's the blue circle.
So if you make u and v both zero, which means we're
entering the icon on the top left, you can see exactly
what's happened here, right?
So the image, the icon is actually anchored to the
position from the top left.
And if you put a smack *** in the middle, so 0.5 and 0.5,
it's drawn right on top, right on top of the
latitude and longitude.
And then here's a bit offset to the right.
I mean 0.2 and 0.7.
So you can see, so if you take advantage of this feature of
having your own images, you should be quite careful to
make sure that the marker is actually drawn
at the correct spot.
And especially if you move around.
So let's talk about draggable markers.
So you can actually pick up a marker and
actually move it around.
So when you set a marker as being draggable, you get a few
events back that tell if the marker's been picked up, if
the maker has been moved.
And that's what we're doing here.
So again, this is coming from the Maps API demo, if you want
to have a look at this.
So this is actually really easy to do.
So the next slide, you can see some code.
So the basic idea is you have to make the marker draggable.
So there's a set draggable method that you
have to set to true.
Or you can specify it when you create the marker.
And then all you have to do is, you have to implement the
OnMarkerDragListener.
which as the name suggests it gets Callbacks when you move
the marker.
You have to actually register the DragListener.
So on your Google maps object, just say set
OnDirectMarkerListener.
And you just specify the object.
And then you just listen for events.
So there are three events you get back.
So you get a Callback when the the user has started moving
the markers, do dragging the maker across the map.
You get a Callback when the user has finished when he's
taken the finger off the screen and the marker has been
placed somewhere.
And you also get drag events.
So you know exactly where the marker is as the marker moves
over the map.
So if you want to find out where the marker actually is
as it's moving around, all you have to do is just [INAUDIBLE]
getPosition method on your marker.
And that way, you know where it is on a map.
And yeah-- that should give you enough information to get
started with draggable markers.
And yeah--
that's all we have for this week.
So you've learned a bit about InfoWindows.
You've learned about polylines and [INAUDIBLE] on Android.
On a map, you've talked about talked about markers in a bit
more detail and draggable markers.
So, yeah.
Thanks.
ANKUR KOTWEL: Thanks Jan-Felix and Tony.
So we do have a couple questions that have be
submitted on moderator.
But given that we have a couple people here that have
joined the Hangout, let's give them an opportunity to ask
questions first.
So we have Linden and Gevin.
And if either of you are talking right now,
we can't hear you.
Or maybe they're just shy.
And that's not a problem.
What we can do is go to the moderator questions.
So let me just bring those up.
And here we are.
OK.
So first question comes from Max.
I need to draw a single polyline with a colored
gradient onto the map.
API version two does allow only to set a
color, a single color.
Do I need to create a custom TileProvider and do the
drawing on my own?
How can I project getTile xy Zoom parameters to GeoPoints.
And Tony, I believe you looked into this one.
TONY CHAN: Yeah, sure.
So basically, for what you're trying to achieve, I think
TileProvider is probably not the right class
you should look at.
I think--
I suggest you take a look at the ground overlay class.
And usually that's how people use this class that achieve
the effect you're talking about.
So you can draw in a Bitmap.
And then add the bitmap to the overly position and then
overlay that on the map.
So with the ground overlay, you don't need to worry about
all the projection coordinates.
So in the ground overlay class, there are LatLng
parameters you can satisfy to specify the
position, the GeoPoints.
ANKUR KOTWEL: Great.
You gave us a great demo of overlays, Tony, by hiding
behind your overlays then of your name.
But thanks for that.
TONY CHAN: OK.
Sorry about that.
ANKUR KOTWEL: That's all right.
We can see you now.
All right, next question.
Google Map View within a ViewPager running on seemingly
any Samsung device --and I'm told any pre-ICS device--
yields a lingering black visual artifact when moving to
another page.
Any methods you know of to mitigate this problem.
And this is Linden, who's from Bloody-strailia, which is
another way of saying Australia.
So Linden--
just a couple of quick questions on this.
So firstly you said it was any Samsung
and any pre-ICS device.
But you said lingering black visual artifact.
Are you able to describe that in a bit more detail.
Because we went through our bug trackers.
And we couldn't find this particular bug.
So it would be great for us to post this bug on the official
bugs lists on Maps API version two but also get some more
Information, so we can reproduce it.
And Linden might not have a microphone.
He is typing away in the chat.
So he said in a non-Nexus Samsung device.
So what we'll do is we'll give it a shot.
And see how we go.
We haven't had a chance to actually go ahead and write
code to reproduce this issue.
we read it pretty late.
So if you grab the Hot Fan and run it on a tablet in
landscape, you'll see it.
I assume Hot Fan is some open source app or something along
those lines.
So all right, thanks for that.
We will look into that.
And we'll trying to get back to in the next episode and
also offline.
But as I said, it's something that I wasn't aware of.
And when the three of us looked on the bug list it
wasn't immediately obvious anyway.
OK.
Next question.
Can we have free cookies?
Sure I don't have to do that over a Hangout but sure.
Offline map fragments with latitude
and longitude attached.
So currently, there is no API for doing
be the offline support.
I'm not sure what the plans around that are.
Currently, what the team is basically been doing is we
version one out there.
Well, the first release of the vision two load the API.
And a couple of developers, Linden included, have been
putting it through the paces and reported a few bugs.
So I believe that the next release will mainly be a
maintenance release.
But we need to look into this.
So I'll raise it with the engineering team.
As with these sorts of feature requests, what we can do is we
can let the engineers that this is something that
developers are asking for.
And they can prioritize the work accordingly.
I'm sure they know about it already.
It's just a matter of how to do it and when to do it.
So yeah.
Free cookies.
Pop on down sometime and we'll see what we can do for you.
All right, last question.
Is it possible to create a shadow of the marker and its
InfoWindow on the map?
So actually, we sort of alluded to the answer to this
question in the presentation itself.
In that, if you have a custom InfoWindow, you have to draw
the shadow yourself.
And you can do that as part of the image, or as part of the
view, rather, that you provide when you set up a custom
InfoWindow.
And the same thing actually applies to customer markers.
When you specify the image for the marker, you can go ahead
and actually put a drop shadow or whatever in the there.
The library won't do that for you.
So just a transparent image and put the
shadow where need to.
Jan-Felix or Tony, do you want to add anything to that?
JAN-FELIX SCHMAKEIT: No.
That's the only you should keep in mind is that if you
add a shadow to a marker, you always make
the image a lot bigger.
[INAUDIBLE] along with the default marker.
So you definitely have to make sure it's still centered at
the right spot, using some of the tricks I was talking about
at the presentation.
Make sure you anchor it at the right position
ANKUR KOTWEL: Got you, thanks.
Linden has also asked another question.
So given holding a reference to a marker is a bad idea, is
keeping tabs of hash code of markers the best way to keep
track of them?
So you know which marker go pressed.
Sorry, InfoWindows not markers.
So I mean, Linden, the way I would probably do this is use
different listeners or some sort of identifier to track
within your InfoWindowListener to work out
which on got pressed.
Having said that, Jan-Felix anything else you want to add
on top of that?
JAN-FELIX SCHMAKEIT: Yeah, so we actually had to do this for
the Santa Tracker app as well.
And basically we were just keeping track
of it the same way.
And we have registered a few listeners.
And we basically just have a tag for to each of the
markers, so we know which markers has been pressed.
So at first you can only register one listener.
You can't have multiple listeners.
But if you listen for marker kicks, so when you want
display InfoWindow, and when you dismiss the InfoWindow.
So on InfoWindow click--
that's probably the way to do it.
ANKUR KOTWEL: Did that answer your question?
Yep, he said cheers.
All right, let me just do one last refresh of the moderator.
And it doesn't look we have any new questions.
So thanks very much for watching.
ANKUR KOTWEL: Ankur, before we end the show, I want to answer
one of the question asked earlier in [INAUDIBLE]
show about VPN support.
It's a question asked by Phung Lim.
So let me repeat the question here.
So his question was Android 2.8 support IP set VPN using
DSK [INAUDIBLE]
pApn MSchat.
But it is not in Android 4.8.
Why is it removed?
And is it possible implement a VPN client which supports
[INAUDIBLE]
and MSchat or the support is removed in the system level?
So we don't always have the answers.
But most of the time, we try very hard to try to get
everyone answered.
So we followed up with the engineering team.
And we get the following answer.
So one thing is that we haven't changed anything
related to authentication protocols since 2.8.
So our [INAUDIBLE] and chat is supported in the system, then
it will be still supported latest images.
In ICS, we do L2TP only VPN support.
But we also add three commonly used IPsec VPN support.
So if you experience something like that [INAUDIBLE] and chat
is not supported in a particular device, there are a
couple problem area we can think of.
One is the VPN server you're connecting to actually doesn't
support those protocols.
Another responsibility is some OEMs may took away such
support in their OS images.
So I hope that answers your question, Phung.
Thanks.
ANKUR KOTWEL: Yeah, thanks Tony.
I'm glad you reminded me that we were going
to answer that question.
So anyways, that concludes the series that we had
for the Maps API.
So this was part two of the maps series.
But actually, and we're going to add to the playlist.
the Santa Tracker episode that we did on how we build that
app is basically like part three.
It's a little bit more high level.
There's not as much code shown.
But hopefully, as developers, you're able to get some value
out of it and see some of the tricks that we employed and
how we went about it.
So we'll be back again soon with another topic.
And please do let us know there's special areas that
you'd like us to dive into.
And we can prioritize those suggestions as well.
So thank you very much for joining us.
We'll see you next time.
TONY CHAN: Thank you.
JAN-FELIX SCHMAKEIT: See you, thanks