In this tutorial We will learn how to add Custom Marker Items in Google Map Android.
We will follow below steps:
- Design Custom XML Layout file for Google Map Marker.
- Create Google Map Info Window Adapter Class.
- Info Window Data Class (Kotlin) which will be holding location info to be displayed on our custom Google Map Marker.
- Adding Marker Options from Activity/Fragment and displaying custom marker.
Google Map Custom InfoWindowAdapter Example Output

This is how our marker layout will look like. We will be showing following location details in Marker Options.
- Location Name.
- Location Address.
- Location Email Address.
- Location Phone Number.
- Location Opening Hours.
- Location Branch Code.
XML Layout File For Custom Marker
// layout_custom_map_marker.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<ImageView
android:id="@+id/imgCancelMapMarker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_mew_cancel_red" />
<com.es.mewphone.widgets.BoldText
android:id="@+id/txtLocMarkerName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Developine Software"
android:textColor="@color/colorTextdefault"
android:textSize="10sp"
app:layout_constraintStart_toStartOf="parent" />
<com.es.mewphone.widgets.NormalText
android:id="@+id/txtLocMarkerAddress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="Software Technology Park Islamabad"
android:textSize="10sp"
app:layout_constraintEnd_toStartOf="@id/imgCancelMapMarker"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/txtLocMarkerName" />
<ImageView
android:id="@+id/imgLocMarkerEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/txtLocMarkerAddress"
app:srcCompat="@drawable/ic_mew_emailorage" />
<com.es.mewphone.widgets.NormalText
android:id="@+id/txtLocMarkerEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginStart="6dp"
android:layout_marginTop="6dp"
android:text="developine.com@gmail.com"
android:textSize="10sp"
app:layout_constraintStart_toEndOf="@id/imgLocMarkerEmail"
app:layout_constraintTop_toBottomOf="@id/txtLocMarkerAddress" />
<ImageView
android:id="@+id/imgLocMarkerPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtLocMarkerEmail"
app:srcCompat="@drawable/ic_mew_phoneorange" />
<com.es.mewphone.widgets.NormalText
android:id="@+id/txtLocMarkerPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginStart="6dp"
android:layout_marginTop="6dp"
android:text="92 333 8456598"
android:textSize="10sp"
app:layout_constraintStart_toEndOf="@id/imgLocMarkerPhone"
app:layout_constraintTop_toBottomOf="@+id/txtLocMarkerEmail" />
<com.es.mewphone.widgets.BoldText
android:id="@+id/txtOpenningHoursLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/openning_hours"
android:textColor="@color/colorTextdefault"
android:textSize="10sp"
app:layout_constraintTop_toBottomOf="@+id/txtLocMarkerPhone" />
<com.es.mewphone.widgets.NormalText
android:id="@+id/txtOpenningHoursValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="8 AM to 6 PM"
android:textSize="10sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtOpenningHoursLabel" />
<com.es.mewphone.widgets.BoldText
android:id="@+id/txtBranchMarkerLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/branch_code"
android:textColor="@color/colorTextdefault"
android:textSize="10sp"
app:layout_constraintTop_toBottomOf="@+id/txtOpenningHoursValue" />
<com.es.mewphone.widgets.NormalText
android:id="@+id/txtBranchMarkerValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="0404"
android:textSize="10sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtBranchMarkerLabel" />
</android.support.constraint.ConstraintLayout>
Preview of this XML layout file is shown above in screenshot.
Create Info Window Data Class
data class InfoWindowData(val mLocatioName: String,
val mLocationAddres: String,
val mLocationEmail: String,
val mLocationPhone: String,
val mLocationHours: String,
val mLocationBranch: String)
This data class will be holding data for each marker layout.
Create Custom Info Window Adapter Class (Kotlin Code)
class CustomInfoWindowGoogleMap(val context: Context) : GoogleMap.InfoWindowAdapter {
override fun getInfoContents(p0: Marker?): View {
var mInfoView = (context as Activity).layoutInflater.inflate(R.layout.mew_custom_map_marker, null)
var mInfoWindow: InfoWindowData? = p0?.tag as InfoWindowData?
mInfoView.txtLocMarkerName.text = mInfoWindow?.mLocatioName
mInfoView.txtLocMarkerAddress.text = mInfoWindow?.mLocationAddres
mInfoView.txtLocMarkerEmail.text = mInfoWindow?.mLocationEmail
mInfoView.txtLocMarkerPhone.text = mInfoWindow?.mLocationPhone
mInfoView.txtOpenningHoursValue.text = mInfoWindow?.mLocationHours
mInfoView.txtBranchMarkerValue.text = mInfoWindow?.mLocationBranch
return mInfoView
}
override fun getInfoWindow(p0: Marker?): View? {
return null
}
}
Activity Class (Kotlin)
class GoogleMapInfoWindowActivity : AppCompatActivity(), OnMapReadyCallback {
private var mMap: GoogleMap? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_home)
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
mMap!!.uiSettings.isZoomControlsEnabled = true
mMap!!.setMinZoomPreference(11f)
val islamabad = LatLng(33.738045, 73.084488)
val markerOptions = MarkerOptions()
markerOptions.position(islamabad)
.title("Location Details")
.snippet("I am custom Location Marker.")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
val info = InfoWindowData("Developine", "Islamabad Pakistan",
"hammadtariq.me@gmail.com",
"92 333 8456598",
"8 AM to 6 PM",
"0404"
)
val customInfoWindow = CustomInfoWindowGoogleMap(this)
mMap!!.setInfoWindowAdapter(customInfoWindow)
val marker = mMap!!.addMarker(markerOptions)
marker.tag = info
marker.showInfoWindow()
mMap!!.moveCamera(CameraUpdateFactory.newLatLng(islamabad))
}
}
If you run this code custom marker layout will be showing by default on marker.
If you want to disable it
just remove this code line
marker.showInfoWindow()
But when you will click on Marker it will show Location Details inside custom layout (popup).
copyright : http://developine.com/