Bugdroid vs. Star Wars
[Android] Using layout as custom marker on Google Map API
Here is my first tutorial on Android development.
The purpose of this tutorial is to create custom marker for Google Maps using a layout containing a customizable TextView.
First thing to do, install and configure Google Maps API v2 to obtain an API key (to put in the file manifest.xml).
All the information is here:
http://developer.android.com/google/play-services/maps.html
And to get the api key is here:
https://code.google.com/apis/console/
We create the layout of the application by specifying a fragment referring to the Google Map API (com.google.android.gms.maps.SupportMapFragment).
layout/map_layout.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#FFFFFF" > <fragment android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </RelativeLayout> |
We create a layout with a TextView (dynamic) and ImageView. It will be converted into bitmap to display in the map.
layout/custom_marker_layout.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" > <ImageView android:layout_width="55dp" android:layout_height="65dp" android:src="@drawable/custom_marker" /> <TextView android:id="@+id/num_txt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_marginTop="5dp" android:gravity="center" android:text="20" android:textColor="#ce8223" android:textSize="25dp" android:textStyle="bold" /> </RelativeLayout> |
In CustomMapMarker class, we setup the map (tutorial here).
We get the layout custom_marker_layout with layout inflater service, we change our TextView and convert the view result into a bitmap (with createDrawableFromView method).
CustomMapMarker.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | public class CustomMapMarker extends FragmentActivity { private GoogleMap mMap; private Marker customMarker; private LatLng markerLatLng; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.map_layout); markerLatLng = new LatLng(48.8567,2.3508); setUpMapIfNeeded(); } private void setUpMapIfNeeded() { // Do a null check to confirm that we have not already instantiated the // map. if (mMap == null) { // Try to obtain the map from the SupportMapFragment. mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); // Check if we were successful in obtaining the map. if (mMap != null) { setUpMap(); } } } private void setUpMap() { View marker = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.custom_marker_layout, null); TextView numTxt = (TextView) marker.findViewById(R.id.num_txt); numTxt.setText("27"); customMarker = mMap.addMarker(new MarkerOptions() .position(markerLatLng) .title("Title") .snippet("Description") .icon(BitmapDescriptorFactory.fromBitmap(createDrawableFromView(this, marker)))); final View mapView = getSupportFragmentManager().findFragmentById(R.id.map).getView(); if (mapView.getViewTreeObserver().isAlive()) { mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @SuppressLint("NewApi") // We check which build version we are using. @Override public void onGlobalLayout() { LatLngBounds bounds = new LatLngBounds.Builder().include(markerLatLng).build(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this); } else { mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50)); } }); } } // Convert a view to bitmap public static Bitmap createDrawableFromView(Context context, View view) { DisplayMetrics displayMetrics = new DisplayMetrics(); ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels); view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels); view.buildDrawingCache(); Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); view.draw(canvas); return bitmap; } } |
Preview:
Google Maps Android API v2 useful links:
https://developers.google.com/maps/documentation/android/start
https://developers.google.com/maps/documentation/android/map
https://code.google.com/apis/console/
http://developer.android.com/google/play-services/index.html
Project sources on GitHub:
https://github.com/Nasc/CustomMapMarker
Christmas Avatar
I’ll be there
Laboratory
![]()















