0Pricing
Android Academy · Lesson

Markers and Camera

Place markers and move the camera.

Markers and Camera is a free Android Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Android Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

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 Marker composables inside the GoogleMap content, with title, snippet and custom icon.
  • Render markers from a data list and handle onClick.
  • Move the camera instantly via position, or smoothly via animate().
  • Fit many points with LatLngBounds and reduce clutter using Clustering.

Next: requesting location permissions the right way so all of this works on real devices.

Frequently asked questions

Is the “Markers and Camera” lesson free?

Yes — the full text of “Markers and Camera” is free to read here on the web, and the Android Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Android Academy course, upgrade to CoddyKit PRO.

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; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

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

  1. Showing a Map
  2. Getting the User Location
  3. Markers and Camera
  4. Location Permissions Done Right
← Back to Android Academy