Android Maps Api V2 Draw Circle
Overview
This guide will instruct you on how utilize the Google Maps API v2 library to create a map inside your application's activities and/or fragments.
Setup Map If Necessary
For full setup instructions, see our Google Maps Setup Guide. Assuming you have added the GoogleMap
v2 MapFragment
to your layout, you should first run this method onCreate()
. In my case, I am using the SupportMapFragment, either will piece of work.
protected void setUpMapIfNeeded () { // Do a nix check to confirm that we accept not already instantiated the map. if ( mapFragment == zippo ) { mapFragment = (( SupportMapFragment ) getSupportFragmentManager (). findFragmentById ( R . id . map )); // Check if we were successful in obtaining the map. if ( mapFragment != null ) { mapFragment . getMapAsync ( new OnMapReadyCallback () { @Override public void onMapReady ( GoogleMap map ) { loadMap ( map ); } }); } } } // The Map is verified. It is now safe to manipulate the map. protected void loadMap ( GoogleMap googleMap ) { if ( googleMap != cypher ) { // ... employ map here } }
Afterward you take run that it is safe for you to begin adding markers.
Configuring Initial State
The Maps API allows you to configure the initial state of the map including blazon, position, controls, and much more:
<fragment xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:map= "http://schemas.android.com/apk/res-auto" android:name= "com.google.android.gms.maps.SupportMapFragment" android:id= "@+id/map" android:layout_width= "match_parent" android:layout_height= "match_parent" map:cameraBearing= "112.five" map:cameraTargetLat= "-33.796923" map:cameraTargetLng= "150.922433" map:cameraTilt= "30" map:cameraZoom= "13" map:mapType= "normal" map:uiCompass= "fake" map:uiRotateGestures= "true" map:uiScrollGestures= "false" map:uiTiltGestures= "truthful" map:uiZoomControls= "fake" map:uiZoomGestures= "true" />
See the official docs for more configuration options.
Controlling the Camera
The map location center and zoom tin be manipulated using the moveCamera or animateCamera which both have a CameraUpdate object. For example, to retarget the camera to a new latitude and longitude we tin do:
LatLng latLng = new LatLng ( breadth , longitude ); CameraUpdate cameraUpdate = CameraUpdateFactory . newLatLng ( latLng ); map . animateCamera ( cameraUpdate );
Cheque the CameraUpdateFactory for the bachelor camera update types including newLatLng
, newLatLngZoom
, zoomTo
, and more.
Adding Markers to Map Fragment
We tin can add a marker to the map with the following code specifying the position (LatLng
), icon (BitmapDescriptor
), title, and snippet:
// Set up the color of the mark to green BitmapDescriptor defaultMarker = BitmapDescriptorFactory . defaultMarker ( BitmapDescriptorFactory . HUE_GREEN ); // listingPosition is a LatLng betoken LatLng listingPosition = new LatLng (- 33.867 , 151.206 ); // Create the marker on the fragment Marker mapMarker = map . addMarker ( new MarkerOptions () . position ( listingPosition ) . title ( "Some championship here" ) . snippet ( "Some description here" ) . icon ( defaultMarker ));
Attaching Click Handler to Markers
We can attach a click handler to a mark once the map is loaded with:
protected void loadMap ( GoogleMap googleMap ) { if ( googleMap != null ) { // Attach marker click listener to the map here map . setOnMarkerClickListener ( new GoogleMap . OnMarkerClickListener () { public boolean onMarkerClick ( Marker marker ) { // Handle marker click here } }); // ... } }
Associating Markers to Models
Markers have express information and associating a marking to the underlying data model tin can be hard without creating an associated hash map to rails the mappings betwixt a mark'due south id and the associated data model. Refer to this stackoverflow post for specifics.
Custom Marker Drawables
We tin too use custom markers based on any arbitrary drawable. For bitmap-based drawables, employ:
// Define custom marker BitmapDescriptor customMarker = BitmapDescriptorFactory . fromResource ( R . drawable . house_flag );
See how to use vector-based drawables equally map markers.
BitmapDescriptorFactory provides other color or icon loading options.
Speech Bubbles
Add the Google Maps Android Utility library to your app/build.gradle
file:
dependencies { implementation 'com.google.maps.android:android-maps-utils:0.5+' }
Employ the IconGenerator
class included in this library and prepare the color and text of this speech bubble:
IconGenerator iconGenerator = new IconGenerator ( MapDemoActivity . this ); // Possible color options: // STYLE_WHITE, STYLE_RED, STYLE_BLUE, STYLE_GREEN, STYLE_PURPLE, STYLE_ORANGE iconGenerator . setStyle ( IconGenerator . STYLE_GREEN ); // Swap text here to live within oral communication bubble Bitmap bitmap = iconGenerator . makeIcon ( title ); // Use BitmapDescriptorFactory to create the marker BitmapDescriptor icon = BitmapDescriptorFactory . fromBitmap ( bitmap );
When adding a mark, utilize this icon instead of the default one:
Marker mapMarker = map . addMarker ( new MarkerOptions () // add options hither . icon ( icon ));
Enable Markers to be Draggable
First, set the action to implement OnMarkerDragListener
and set the map to mind for drag events:
public class MapDemoActivity extends AppCompatActivity implements GoogleMap . OnMarkerDragListener { private GoogleMap map ; protected void loadMap ( GoogleMap googleMap ) { map = googleMap ; if ( map != nil ) { map . setOnMarkerDragListener ( this ); } }
You and so must implement the onMarkerDragStart()
, onMarkerDrag()
, and onMarkerDragEnd()
methods for your activeness:
@Override public void onMarkerDragStart ( Marker mark ) { } @Override public void onMarkerDrag ( Marker marker ) { } @Override public void onMarkerDragEnd ( Marker marker ) { // Exercise MOST Work HERE }
Finally, when creating markers, brand sure to prepare the draggable land to true
:
marker . setDraggable ( truthful );
To verify, create a marker and concord down the mouse push for a few seconds before moving information technology. If you lot likewise accept a long click listener may also interfere, make sure your cursor is pointing directly at a marker icon.
Show AlertDialog on LongClick
You can use the following lawmaking to bring up an AlertDialog
for users to type a message on MapLongClick
consequence. On completion, we tin add a marker to the map which when pressed displays the message typed.
Create Alert Dialog Template
First, we demand to create a new xml file in res/layout/message_item.xml
which will be displayed equally the alert window:
<?xml version="1.0" encoding="utf-viii"?> <RelativeLayout android:id= "@+id/layout_root" xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "match_parent" android:layout_height= "match_parent" android:padding= "10dp" > <EditText android:id= "@+id/etTitle" android:layout_width= "match_parent" android:layout_height= "wrap_content" android:layout_alignLeft= "@+id/etSnippet" android:paddingTop= "20dp" android:hint= "Title" ></EditText> <EditText android:id= "@+id/etSnippet" android:layout_below= "@id/etTitle" android:layout_width= "match_parent" android:layout_height= "wrap_content" android:hint= "Snippet" ></EditText> </RelativeLayout>
Implement OnMapLongClickListener Event
If we want to setup a long click listener, we demand to add implements GoogleMap.OnMapLongClickListener
in our Activeness and setup the listener for the map:
public class MapDemoActivity extends AppCompatActivity implements GoogleMap . OnMapLongClickListener { ... protected void loadMap ( GoogleMap googleMap ) { map = googleMap ; if ( map != null ) { // Attach long click listener to the map hither map . setOnMapLongClickListener ( this ); // ... } } ... // Fires when a long press happens on the map @Override public void onMapLongClick ( concluding LatLng point ) { Toast . makeText ( this , "Long Press" , Toast . LENGTH_LONG ). prove (); // Custom code hither... } }
Brand certain to have your activeness implement from the OnMapLongClickListener
for this to work properly. Now, when we run this, nosotros should meet a toast when the user long clicks on the map.
Define the Alert Dialog
Adjacent, let's trigger an alert dialog which volition be displayed to accept input from the user within MapDemoActivity
:
// ... @Override public void onMapLongClick ( LatLng point ) { Toast . makeText ( getApplicationContext (), "Long Press" , Toast . LENGTH_LONG ). prove (); // Custom code here... // Display the alert dialog showAlertDialogForPoint ( betoken ); } // Display the warning that adds the marking private void showAlertDialogForPoint ( final LatLng point ) { // inflate message_item.xml view View messageView = LayoutInflater . from ( MapDemoActivity . this ). inflate ( R . layout . message_item , null ); // Create alert dialog builder AlertDialog . Builder alertDialogBuilder = new AlertDialog . Builder ( this ); // prepare message_item.xml to AlertDialog builder alertDialogBuilder . setView ( messageView ); // Create alarm dialog last AlertDialog alertDialog = alertDialogBuilder . create (); // Configure dialog push (OK) alertDialog . setButton ( DialogInterface . BUTTON_POSITIVE , "OK" , new DialogInterface . OnClickListener () { @Override public void onClick ( DialogInterface dialog , int which ) { // Define color of marking icon BitmapDescriptor defaultMarker = BitmapDescriptorFactory . defaultMarker ( BitmapDescriptorFactory . HUE_GREEN ); // Extract content from alert dialog String title = (( EditText ) alertDialog . findViewById ( R . id . etTitle )). getText (). toString (); String snippet = (( EditText ) alertDialog . findViewById ( R . id . etSnippet )). getText (). toString (); // Creates and adds marking to the map Marker mark = map . addMarker ( new MarkerOptions () . position ( point ) . championship ( title ) . snippet ( snippet ) . icon ( defaultMarker )); } }); // Configure dialog button (Abolish) alertDialog . setButton ( DialogInterface . BUTTON_NEGATIVE , "Cancel" , new DialogInterface . OnClickListener () { public void onClick ( DialogInterface dialog , int id ) { dialog . abolish (); } }); // Display the dialog alertDialog . bear witness (); } // ...
When nosotros run the app at present, the long click on the map should trigger a dialog which allows united states of america to enter text which will be associated with a map marker.
Falling Pin Animation
To implement the falling pivot animation, add together a marker to the desired position in map and and then call this office with that marker. This part uses a Handler
to animate the mark over fourth dimension by setting the anchor.
private void dropPinEffect ( final Marker marker ) { // Handler allows u.s.a. to repeat a code block after a specified delay final android . os . Handler handler = new android . os . Handler (); concluding long get-go = SystemClock . uptimeMillis (); final long elapsing = 1500 ; // Use the bounce interpolator final android . view . animation . Interpolator interpolator = new BounceInterpolator (); // Animate marker with a bounciness updating its position every 15ms handler . post ( new Runnable () { @Override public void run () { long elapsed = SystemClock . uptimeMillis () - starting time ; // Calculate t for bounce based on elapsed time float t = Math . max ( i - interpolator . getInterpolation (( float ) elapsed / duration ), 0 ); // Set the anchor marking . setAnchor ( 0.5f , 1.0f + 14 * t ); if ( t > 0.0 ) { // Postal service this issue once again 15ms from now. handler . postDelayed ( this , 15 ); } else { // done elapsing, bear witness window mark . showInfoWindow (); } } }); }
Review the repeating periodic tasks guide for a meliorate understanding of the Handler
pattern used higher up to animate the marker over time.
Adjacent, in private void showAlertDialogForPoint
add the call to dropPinEffect(marker);
at the end to animate the placement of the marker:
// Display the alert that adds the mark individual void showAlertDialogForPoint ( last LatLng point ) { // ... alertDialog . setButton ( DialogInterface . BUTTON_POSITIVE , "OK" , new DialogInterface . OnClickListener () { @Override public void onClick ( DialogInterface dialog , int which ) { // Ascertain colour of marker icon BitmapDescriptor defaultMarker = BitmapDescriptorFactory . defaultMarker ( BitmapDescriptorFactory . HUE_GREEN ); // Extract content from warning dialog Cord championship = (( EditText ) alertDialog . findViewById ( R . id . etTitle )) . getText (). toString (); String snippet = (( EditText ) alertDialog . findViewById ( R . id . etSnippet )) . getText (). toString (); // Creates and adds marking to the map Marker marker = map . addMarker ( new MarkerOptions (). position ( bespeak ) . title ( title ). snippet ( snippet ). icon ( defaultMarker )); // Breathing marker using driblet effect // --> Phone call the dropPinEffect method here dropPinEffect ( mark ); } }); // ... }
Customize InfoWindow
If you lot want to use your own layout instead of the default options, you can do and so by creating your own InfoWindowAdapter
seen below. Create a layout file in res/layout/custom_info_window.xml
:
<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "match_parent" android:layout_height= "match_parent" android:background= "#FFFFFF" android:orientation= "vertical" > <TextView android:id= "@+id/tv_info_window_title" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:textColor= "#ff669900" android:textStyle= "bold" android:singleLine= "true" /> <TextView android:id= "@+id/tv_info_window_description" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:textColor= "#ff0099cc" android:text= "Hours" /> </LinearLayout>
And here is the code you need to implement your own InfoWindowAdapter
form.
class CustomWindowAdapter implements InfoWindowAdapter { LayoutInflater mInflater ; public CustomWindowAdapter ( LayoutInflater i ){ mInflater = i ; } // This defines the contents within the info window based on the marker @Override public View getInfoContents ( Marker marker ) { // Getting view from the layout file View five = mInflater . inflate ( R . layout . custom_info_window , null ); // Populate fields TextView championship = ( TextView ) v . findViewById ( R . id . tv_info_window_title ); title . setText ( marker . getTitle ()); TextView clarification = ( TextView ) 5 . findViewById ( R . id . tv_info_window_description ); description . setText ( marker . getSnippet ()); // Return info window contents return v ; } // This changes the frame of the info window; returning zero uses the default frame. // This is simply the border and pointer surrounding the contents specified to a higher place @Override public View getInfoWindow ( Marker mark ) { return null ; } }
Yous would employ this by setting your InfoWindowAdapter
to this new class after you accept initialized your map. In the case of our instance running this line after calling loadMap()
in onCreate()
.
map . setInfoWindowAdapter ( new CustomWindowAdapter ( getLayoutInflater ()));
This volition employ the custom adapter to create the information window, allowing us to customize how the information is displayed.
Loading Remote Images into InfoWindow Contents
If you lot are loading remote images into an InfoWindow, there is a common trouble where the paradigm doesn't load properly the first time you open the window for each item. The hacky solution is to refresh the window after a delay. The improve solution is to trigger the window to refresh afterward the image is finished downloading.
Customizing the InfoWindow Frame
When creating a custom information window on the map, the developer can choose to override either getInfoContents
(as shown above) which allows you to customize just the contents of the window but still keep the default info window frame and background. If instead the desired behavior is to provide a view that volition exist used for the unabridged info window, nosotros need to override getInfoWindow
instead of getInfoContents
. Notation that but i of these can be overridden for a item adapter. Encounter further discussion in this stackoverflow post, this infowindow tutorial or on the official google docs.
Drawing Shapes on the Map
The map supports arbitrary cartoon of lines and diverse shapes on the surface including polylines (continued lines), polygons (enclosed regions) and circles. For boosted details on drawing shapes on the map, check out the official maps guide.
Polylines
Drawing polylines allows united states of america to connect multiple dots using lines. To draw these connecting lines, simply specify each coordinate that should exist continued.
// Instantiates a new Polyline object and adds points to define a rectangle PolylineOptions rectOptions = new PolylineOptions () . add together ( new LatLng ( 37.35 , - 122.0 )) . add ( new LatLng ( 37.45 , - 122.0 )) // North of the previous betoken, but at the aforementioned longitude . add ( new LatLng ( 37.45 , - 122.ii )) // Same latitude, and 30km to the west . add ( new LatLng ( 37.35 , - 122.2 )) // Aforementioned longitude, and 16km to the due south . add ( new LatLng ( 37.35 , - 122.0 )); // Closes the polyline. // Get back the mutable Polyline Polyline polyline = myMap . addPolyline ( rectOptions );
Polygons
Polygons are designed to ascertain regions within a closed loop with the interior filled in:
// Instantiates a new Polygon object and adds points to define a rectangle PolygonOptions rectOptions = new PolygonOptions () . add ( new LatLng ( 37.35 , - 122.0 ), new LatLng ( 37.45 , - 122.0 ), new LatLng ( 37.45 , - 122.two ), new LatLng ( 37.35 , - 122.two ), new LatLng ( 37.35 , - 122.0 )) . strokeColor ( Color . RED ). fillColor ( Color . BLUE )); // Go back the mutable Polygon Polygon polygon = myMap . addPolygon ( rectOptions );
Circles
Cartoon circles requires specifying the center and radius of the circle:
// Instantiates a new CircleOptions object and defines the center and radius CircleOptions circleOptions = new CircleOptions () . center ( new LatLng ( 37.4 , - 122.one )) . radius ( 1000 )); // In meters // Get back the mutable Circumvolve Circumvolve circle = myMap . addCircle ( circleOptions );
For additional details on drawing shapes on the map, cheque out the official maps guide.
Creating Ground or Tile Overlays
Ground overlays are image overlays that are tied to latitude/longitude coordinates, so they move when yous elevate or zoom the map.
A tile overlay, sometimes chosen a tile layer, is a drove of images that are displayed on top of the base map tiles.
Change Map Type
In improver to the standard "normal" map, there are several other map types available including Terrain (MAP_TYPE_TERRAIN
), Hybrid (MAP_TYPE_HYBRID
), and Satellite (MAP_TYPE_SATELLITE
). To gear up the type, call setMapType
with i of the following options:
mapFragment . getMapAsync ( new OnMapReadyCallback () { @Override public void onMapReady ( GoogleMap map ) { // One time map is loaded // Supported types include: MAP_TYPE_NORMAL, MAP_TYPE_SATELLITE // MAP_TYPE_TERRAIN, MAP_TYPE_HYBRID map . setMapType ( GoogleMap . MAP_TYPE_SATELLITE ); } });
The various types are illustrated below:
Using Vectors As Map Markers
Showtime install the com.google.maps.android:android-maps-utils
library.
In order to use an .xml file / vector for a map marker it must first be inflated into layout and so converted into a bitmap.
Turn the drawable.xml file into a bitmap:
public Bitmap getMarker () { IconGenerator iconGen = new IconGenerator ( context ); // Ascertain the size yous desire from dimensions file int shapeSize = context . getResources (). getDimensionPixelSize ( R . dimen . custom_marker_size ); Drawable shapeDrawable = ResourcesCompat . getDrawable ( context . getResources (), R . drawable . custom_marker , zippo ); iconGen . setBackground ( shapeDrawable ); // Create a view container to set the size View view = new View ( context ); view . setLayoutParams ( new ViewGroup . LayoutParams ( shapeSize , shapeSize )); iconGen . setContentView ( view ); // Create the bitmap Bitmap bitmap = iconGen . makeIcon (); return bitmap ; }
Eat the Bitmap in your Marker Creator:
Marking mapMarker = map . addMarker ( new MarkerOptions () . position ( listingPosition ) . icon ( BitmapDescriptorFactory . fromBitmap ( getMarker ()));
Marking Clustering
Before diving in, you will need to have the maps utility library installed.
The clustering utility allows you lot to manage how markers return at different zoom levels. Instead of the map keeping track of markers, information technology will at present track objects and so return them as clusters or markers depending on the zoom and the distance betwixt marker points.
This section shows how to implement clusters that will appear equally individual markers when zoomed in. And it will testify how to support click events on the markers.
Showtime create a course MyItem
that implements ClusterItem
:
public grade MyItem implements ClusterItem { private final LatLng mPosition ; public MyItem ( double lat , double lng ) { mPosition = new LatLng ( lat , lng ); } @Override public LatLng getPosition () { return mPosition ; } }
In your map activeness, add the ClusterManager
and feed it the cluster items:
public class MapActivity extends AppCompatActivity { @Override protected void onCreate ( Parcel savedInstanceState ) { ... setUpClusterer () } private void setUpClusterer () { // Declare a variable for the cluster manager. private ClusterManager < MyItem > mClusterManager ; private List < MyItem > myItems ; // Initialize the director mClusterManager = new ClusterManager < MyItem >( this , getMap ()); // Betoken the map's listeners at the listeners implemented by the cluster manager. // This will afterward allow onClusterItemClick to piece of work. getMap (). setOnMarkerClickListener ( mClusterManager ); // Add cluster items (markers) to the cluster manager. myItems = yourWayOfPopulating (); mClusterManager . addItems ( myItems ); // Let the cluster manager know you've made changes mClusterManager . cluster () } }
At this point, yous should be able to render default markers that cluster. In lodge use customized markers you will need to extend DefaultClusterRenderer
and build your ain renderer class:
individual void setUpClusterer () { ... mClusterManager = new ClusterManager < MyItem >( this , getMap ()); // Set our custom renderer mClusterManager . setRenderer ( new MyItemRenderer ()); ... }
Define the MyItemRenderer
course:
public class MyItemRenderer extends DefaultClusterRenderer < MyItem >{ public MyItemRenderer ( ClusterManager < MyItem > clusterManager ) { super ( getApplicationContext (), getMap (), clusterManager ); } @Override protected void onBeforeClusterItemRendered ( MyItem myItem , MarkerOptions markerOptions ) { // Customize the marking here markerOptions . position ( myItem . getLatLng ()) . icon ( BitmapDescriptorFactory . fromBitmap ( getMarker ())); } @Override protected void onBeforeClusterRendered ( Cluster < MyItem > cluster , MarkerOptions markerOptions ) { // Customize the cluster here markerOptions . icon ( BitmapDescriptorFactory . fromBitmap ( getMarker ())) } }
In order to support click events on the mark take your parent activity implement OnClusterItemClickListener
:
public class MapActivity extends AppCompatActivity implements ClusterManager . OnClusterItemClickListener < MyItem >{ ... @Override public boolean onClusterItemClick ( MyItem particular ) { // Exercise a click thing here return false ; } }
For additional data check out the google tutorial. This google app contains code samples for a customized map with cluster icons. This mail on stack overflow goes into deep detail on styling a cluster icon.
Utility Library
For boosted features such equally rut maps, marker clusters, calculating distances and more exist certain to check out the maps utility library. Watch this video introduction for a brief overview.
References
- Measure your altitude using Google Maps API - Android tutorial in Kotlin
Source: https://guides.codepath.com/android/Google-Maps-API-v2-Usage
0 Response to "Android Maps Api V2 Draw Circle"
Post a Comment