Markers and Camera
Place markers and move the camera.
Markers and Camera is a free Android Academy lesson on CoddyKit. This is lesson 3 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Android Academy learning path, and your progress syncs across the web and the CoddyKit app. The Android Academy course includes 4 lessons in total.
Marking the Map
A blank map is just tiles. Markers turn it into information — a pin for a shop, a restaurant, the user's destination. And the camera moves the viewport to wherever the story needs.
In this lesson you'll add markers, customize them, group them in clusters, and animate the camera smoothly between places.
Adding a Marker
In maps-compose, markers are composables you place inside the GoogleMap content lambda. Each Marker takes a MarkerState holding its position.
import com.google.maps.android.compose.Marker
import com.google.maps.android.compose.rememberMarkerState
@Composable
fun MapWithMarker() {
val position = LatLng(37.7749, -122.4194)
GoogleMap(modifier = Modifier.fillMaxSize()) {
Marker(
state = rememberMarkerState(position = position),
title = "San Francisco",
snippet = "Welcome to SF"
)
}
}Title, Snippet and Info Windows
The title and snippet appear in the default info window when the user taps a marker. Tapping shows the title in bold with the snippet beneath it.
For full control you can supply a MarkerInfoWindow with your own composable content.
Marker(
state = rememberMarkerState(position = LatLng(48.8584, 2.2945)),
title = "Eiffel Tower",
snippet = "Paris, France",
// The info window pops up on tap by default
)Customizing the Marker Icon
Pass a BitmapDescriptor via the icon parameter to change a marker's look. defaultMarker(hue) recolors the standard pin; you can also build one from a drawable.
import com.google.android.gms.maps.model.BitmapDescriptorFactory
Marker(
state = rememberMarkerState(position = LatLng(35.6895, 139.6917)),
title = "Tokyo",
icon = BitmapDescriptorFactory.defaultMarker(
BitmapDescriptorFactory.HUE_AZURE
)
)Many Markers from Data
Real apps render markers from a list. Loop over your data inside the map content and emit a Marker for each item. Use a stable key per item.
data class Place(val name: String, val latLng: LatLng)
@Composable
fun PlacesMap(places: List<Place>) {
GoogleMap(modifier = Modifier.fillMaxSize()) {
places.forEach { place ->
Marker(
state = rememberMarkerState(position = place.latLng),
title = place.name
)
}
}
}Handling Marker Clicks
Each Marker accepts an onClick lambda. Return true to consume the event (suppressing the default info window) or false to let the default behavior run.
Marker(
state = rememberMarkerState(position = LatLng(40.7128, -74.0060)),
title = "New York",
onClick = {
// handle the tap, e.g. open a detail screen
true // consume the event
}
)Moving the Camera Instantly
To jump the viewport without animation, set the camera position directly on the CameraPositionState. This is a hard cut — the map teleports.
val cameraPositionState = rememberCameraPositionState()
// Instant move
cameraPositionState.position = CameraPosition.fromLatLngZoom(
LatLng(51.5074, -0.1278), // London
14f
)Animating the Camera
For a polished feel, animate the camera with animate(). It's a suspending call, so launch it from a coroutine scope. Use a CameraUpdate to describe the target.
import com.google.android.gms.maps.CameraUpdateFactory
val scope = rememberCoroutineScope()
Button(onClick = {
scope.launch {
cameraPositionState.animate(
CameraUpdateFactory.newLatLngZoom(
LatLng(48.8566, 2.3522), 13f
),
durationMs = 1000
)
}
}) { Text("Fly to Paris") }Fitting Multiple Markers
To show several markers at once, build a LatLngBounds that contains them all, then animate to it with newLatLngBounds plus padding in pixels.
import com.google.android.gms.maps.model.LatLngBounds
val bounds = LatLngBounds.Builder().apply {
places.forEach { include(it.latLng) }
}.build()
scope.launch {
cameraPositionState.animate(
CameraUpdateFactory.newLatLngBounds(bounds, 100) // 100px padding
)
}Clustering Many Markers
Hundreds of markers overwhelm a map. The maps-compose-utils library provides Clustering, which groups nearby markers into a single bubble that splits as you zoom in.
import com.google.maps.android.compose.clustering.Clustering
@Composable
fun ClusteredMap(items: List<MyClusterItem>) {
GoogleMap(modifier = Modifier.fillMaxSize()) {
Clustering(items = items)
}
}Reading the Camera State
You can also read the camera. cameraPositionState.position gives the current target and zoom, and isMoving tells you whether the user is currently panning. Useful for lazily loading data only for the visible region.
LaunchedEffect(cameraPositionState.isMoving) {
if (!cameraPositionState.isMoving) {
val center = cameraPositionState.position.target
// fetch data near `center`
}
}Quick Check
You want the camera to glide smoothly to a new location over one second instead of jumping. Which is correct?
Recap
You can now make a map informative and dynamic:
- Place
Markercomposables inside theGoogleMapcontent, withtitle,snippetand customicon. - Render markers from a data list and handle
onClick. - Move the camera instantly via
position, or smoothly viaanimate(). - Fit many points with
LatLngBoundsand reduce clutter usingClustering.
Next: requesting location permissions the right way so all of this works on real devices.
Learn Kotlin with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 36
- Lessons
- 152
Frequently Asked Questions
Is the “Markers and Camera” lesson free?
Yes — any 3 lessons of the Android Academy learning path, including “Markers and Camera”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Android Academy course includes 4 lessons in total.
What will I learn in “Markers and Camera”?
Place markers and move the camera. You practise Android Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Android Academy?
No prior experience is required. Android Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.
How long does the “Markers and Camera” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Android Academy lesson?
Yes. Every Android Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Showing a Map
- Getting the User Location
- Markers and Camera
- Location Permissions Done Right