> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/help/llms.txt)

# Add Interactions to your Map in Android

This tutorial teaches you how to add interactions to your map using the Mapbox Maps SDK for Android with the [Interactions API](https://docs.mapbox.com/android/maps/guides/user-interaction/interactions/).

You'll learn how to:

-   Set configuration options for the Standard Style.
-   Add interactions to map elements in the Standard style using the [Interactions API](https://docs.mapbox.com/android/maps/guides/user-interaction/interactions/).
-   Set a feature's feature-state to change its appearance when a user interacts with it.
-   Import a style with custom data to your map at runtime.
-   Add interactions to the featuresets in the imported style.
-   Create a custom `ViewAnnotation` to display information about a selected feature.

When you complete this tutorial, you will have a map that allows users to interact with place labels and hotel listings in New York City.

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/help/help/assets/medias/tutorials--android-interactions-complete-da91a9ae6108d09f362d96ebd35e8082.webm).

## Prerequisites

Before you begin, you will need:

-   A **Mapbox account**: [Sign up](https://account.mapbox.com/auth/signup/) for free or [log in](https://console.mapbox.com/) if you already have an account.
-   **A project with the Maps SDK installed**: Follow the [Getting Started with the Maps SDK for Android](https://docs.mapbox.com/android/maps/guides/install/) guide.
-   **Familiarity with Android development**: Beginner experience with Jetpack Compose, Kotlin, and Android Studio.

This tutorial assumes you have a basic understanding of Kotlin and Android development and requires you to have setup the **Mapbox Maps SDK for Android** for a Jetpack Compose project as covered in our [Getting Started with Mapbox on Android](https://docs.mapbox.com/android/maps/guides/install/) guide. That guide walks you through adding the **Mapbox Maps SDK for Android** dependency (version 11.13.0 or later) and adding your public access token to your project's `mapbox_access_token.xml` file.

The Getting Started guide should leave you with a new Compose project open in Android with a globe displayed.

![Screenshot of an Android app showing a globe.](https://docs.mapbox.com/help/assets/ideal-img/tutorials--android-interactions-1.b4370ff.480.png)

## Add Interactions to your Map with the Standard Style

The [Mapbox Standard Style](https://docs.mapbox.com/map-styles/standard/guides/) is a good starting point for adding interactions to your map. When creating a new project, the Mapbox Standard Style is the default style. It has predefined [configuration options](https://docs.mapbox.com/map-styles/standard/guides/#configuration) that allow you to set lighting conditions, label visibility, and other map features. Also, the Standard Style defines several [Featuresets](https://docs.mapbox.com/map-styles/standard/guides/#interactions-with-featuresets)—Standard Buildings, Standard Place Labels, and Standard POIs—that you can use to add interactions to your map.

To start, set the Map's camera to New York City and change the `lightPreset` configuration option for standard to `dawn`. Replace the `setContent` block in your `MainActivity.kt` file with the following code:

```kotlin
package com.example.interactions // Your package name here

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.mapbox.geojson.Point
import com.mapbox.maps.extension.compose.MapboxMap
import com.mapbox.maps.extension.compose.animation.viewport.rememberMapViewportState
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.unit.dp
import com.mapbox.maps.dsl.cameraOptions
import com.mapbox.maps.extension.compose.style.standard.LightPresetValue
import com.mapbox.maps.extension.compose.style.standard.MapboxStandardStyle
import com.mapbox.maps.extension.compose.style.standard.rememberStandardStyleState
import android.util.Log

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MapboxMap(
                Modifier.fillMaxSize().padding(top = 20.dp),
                mapViewportState = rememberMapViewportState {
                    setCameraOptions(
                        cameraOptions {
                            center(Point.fromLngLat(-73.99, 40.72))
                            zoom(11.0)
                            pitch(45.0)
                        }
                    )
                },
                style = {
                    MapboxStandardStyle(
                        standardStyleState = rememberStandardStyleState {
                            configurationsState.apply {
                                lightPreset = LightPresetValue.DAWN
                            }
                            interactionsState.onPlaceLabelsClicked { placeLabel, context ->
                                placeLabel.name?.let { Log.d("InteractionsApp", it) }
                                Log.d("InteractionsApp", context.coordinateInfo.coordinate.toString())
                                return@onPlaceLabelsClicked true
                            }
                        }
                    )
                }
            )
        }
    }
}
```

Now, add your first interaction by setting an interaction handler on the `StandardPlaceLabels` featureset in the Standard Style. When a user taps on a place label, the color of the label to red. To do this, first add an [`onPlaceLabelsClicked()`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.extension.compose.style.standard.generated/-standard-style-interactions-state/on-place-labels-clicked.html) interaction state to the style, right below the configuration state block.

```kotlin
package com.example.interactions // Your package name here

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.mapbox.geojson.Point
import com.mapbox.maps.extension.compose.MapboxMap
import com.mapbox.maps.extension.compose.animation.viewport.rememberMapViewportState
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.unit.dp
import com.mapbox.maps.dsl.cameraOptions
import com.mapbox.maps.extension.compose.style.standard.LightPresetValue
import com.mapbox.maps.extension.compose.style.standard.MapboxStandardStyle
import com.mapbox.maps.extension.compose.style.standard.rememberStandardStyleState
import android.util.Log

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MapboxMap(
                Modifier.fillMaxSize().padding(top = 20.dp),
                mapViewportState = rememberMapViewportState {
                    setCameraOptions(
                        cameraOptions {
                            center(Point.fromLngLat(-73.99, 40.72))
                            zoom(11.0)
                            pitch(45.0)
                        }
                    )
                },
                style = {
                    MapboxStandardStyle(
                        standardStyleState = rememberStandardStyleState {
                            configurationsState.apply {
                                lightPreset = LightPresetValue.DAWN
                            }
                            interactionsState.onPlaceLabelsClicked { placeLabel, context ->
                                placeLabel.name?.let { Log.d("InteractionsApp", it) }
                                Log.d("InteractionsApp", context.coordinateInfo.coordinate.toString())
                                return@onPlaceLabelsClicked true
                            }
                        }
                    )
                }
            )
        }
    }
}
```

In the `onPlaceLabelsClicked` method you can write a closure that will be called when a user clicks a map place label feature. `onPlaceLabelsClicked` targets the `StandardPlaceLabels` featureset, which contains place labels such as the names of countries, cities, and neighborhoods. When a user taps on a place label, the provided closure will be called. When writing your closure you can access properties of the specific tapped feature (`placeLabel`) and the interaction context (`context`). For example, the above code will print the name of the place label and the coordinate of the tap to the console.

These properties are available in the closure because we are targeting the `StandardPlaceLabels` featureset meaning the `placeLabel` object has a type of [`StandardPlaceLabelsFeature`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.interactions.standard.generated/-standard-place-labels-feature/). This `placeLabel` object will contain information about the place label, such as its name, properties, and geometry. The `context` is of type [`InteractionContext`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps/-interaction-context/) and contains information about the interaction itself, such as the coordinate of the tap in latitude and longitude and the screen coordinate of the tap in pixels.

> **Note: Standard Style Featuresets**
> 
> Each featureset in the Mapbox Standard Style is typed, meaning that you can access the properties of features in that featureset directly. This allows you to work with the features in a type-safe way, making it easier to work with the data and reducing the risk of runtime errors.

Now, change that code so when a user selects a place label its color changes to red. First, create a new mutable list of [`StandardPlaceLabelsFeature`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.interactions.standard.generated/-standard-place-labels-feature/)s to hold the selected place labels. This will allow us to keep track of which place labels have been selected and update the map as needed. Name this variable `selectedPlaces` and add it to the `setContent` block.

```kotlin
package com.example.interactions // Your package name here

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.mapbox.geojson.Point
import com.mapbox.maps.extension.compose.MapboxMap
import com.mapbox.maps.extension.compose.animation.viewport.rememberMapViewportState
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.unit.dp
import com.mapbox.maps.dsl.cameraOptions
import com.mapbox.maps.extension.compose.style.standard.LightPresetValue
import com.mapbox.maps.extension.compose.style.standard.MapboxStandardStyle
import com.mapbox.maps.extension.compose.style.standard.rememberStandardStyleState
import android.util.Log
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import com.mapbox.maps.interactions.standard.generated.StandardPlaceLabelsFeature

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val selectedPlaces = remember {
                mutableStateListOf<StandardPlaceLabelsFeature>()
            }

            MapboxMap(
                Modifier.fillMaxSize().padding(top = 20.dp),
                mapViewportState = rememberMapViewportState {
                    setCameraOptions(
                        cameraOptions {
                            center(Point.fromLngLat(-73.99, 40.72))
                            zoom(11.0)
                            pitch(45.0)
                        }
                    )
                },
                style = {
                    MapboxStandardStyle(
                        standardStyleState = rememberStandardStyleState {
                            configurationsState.apply {
                                lightPreset = LightPresetValue.DAWN
                            }
                            interactionsState.onPlaceLabelsClicked { placeLabel, _ ->
                                placeLabel.setStandardPlaceLabelsState {
                                    select(select = true)
                                }
                                selectedPlaces.add(placeLabel)
                                return@onPlaceLabelsClicked true
                            }
                            interactionsState.onMapLongClicked { _ ->
                                selectedPlaces.forEach {
                                    it.removeFeatureState()
                                }
                                return@onMapLongClicked true
                            }
                        }
                    )
                }
            )
        }
    }
}
```

Then, update the `onPlaceLabelsClicked` function to add the clicked place label to the `selectedPlaces` list. Next, change the [`FeatureState`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.interactions/-feature-state/) of the `select` property to true. The default color for selected place labels is red.

Each typed [`FeaturesetFeature`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.interactions/-featureset-feature/) has different state properties that you can set to change the appearance of the feature. For `StandardPlaceLabelsFeature`, you can set the [feature state](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.interactions.standard.generated/-standard-place-labels-state/) for `hide`, `select`, and `highlight`. Replace the `Log.d` lines you added before with the following code that sets the `select` property to true on the selected place label and it to the `selectedPlaces` list.

```kotlin
package com.example.interactions // Your package name here

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.mapbox.geojson.Point
import com.mapbox.maps.extension.compose.MapboxMap
import com.mapbox.maps.extension.compose.animation.viewport.rememberMapViewportState
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.unit.dp
import com.mapbox.maps.dsl.cameraOptions
import com.mapbox.maps.extension.compose.style.standard.LightPresetValue
import com.mapbox.maps.extension.compose.style.standard.MapboxStandardStyle
import com.mapbox.maps.extension.compose.style.standard.rememberStandardStyleState
import android.util.Log
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import com.mapbox.maps.interactions.standard.generated.StandardPlaceLabelsFeature

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val selectedPlaces = remember {
                mutableStateListOf<StandardPlaceLabelsFeature>()
            }

            MapboxMap(
                Modifier.fillMaxSize().padding(top = 20.dp),
                mapViewportState = rememberMapViewportState {
                    setCameraOptions(
                        cameraOptions {
                            center(Point.fromLngLat(-73.99, 40.72))
                            zoom(11.0)
                            pitch(45.0)
                        }
                    )
                },
                style = {
                    MapboxStandardStyle(
                        standardStyleState = rememberStandardStyleState {
                            configurationsState.apply {
                                lightPreset = LightPresetValue.DAWN
                            }
                            interactionsState.onPlaceLabelsClicked { placeLabel, _ ->
                                placeLabel.setStandardPlaceLabelsState {
                                    select(select = true)
                                }
                                selectedPlaces.add(placeLabel)
                                return@onPlaceLabelsClicked true
                            }
                            interactionsState.onMapLongClicked { _ ->
                                selectedPlaces.forEach {
                                    it.removeFeatureState()
                                }
                                return@onMapLongClicked true
                            }
                        }
                    )
                }
            )
        }
    }
}
```

Further, add an additional [`onMapLongClicked`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.extension.compose.style.standard.generated/-standard-style-interactions-state/on-map-long-clicked.html) interaction, targeting the map itself. The `onMapLongClicked` takes a closure that is called when the interaction occurs. In this case, we will remove all elements from `selectedPlaces`, which will remove the red coloring of the selected place labels.

```kotlin
package com.example.interactions // Your package name here

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.mapbox.geojson.Point
import com.mapbox.maps.extension.compose.MapboxMap
import com.mapbox.maps.extension.compose.animation.viewport.rememberMapViewportState
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.unit.dp
import com.mapbox.maps.dsl.cameraOptions
import com.mapbox.maps.extension.compose.style.standard.LightPresetValue
import com.mapbox.maps.extension.compose.style.standard.MapboxStandardStyle
import com.mapbox.maps.extension.compose.style.standard.rememberStandardStyleState
import android.util.Log
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import com.mapbox.maps.interactions.standard.generated.StandardPlaceLabelsFeature

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val selectedPlaces = remember {
                mutableStateListOf<StandardPlaceLabelsFeature>()
            }

            MapboxMap(
                Modifier.fillMaxSize().padding(top = 20.dp),
                mapViewportState = rememberMapViewportState {
                    setCameraOptions(
                        cameraOptions {
                            center(Point.fromLngLat(-73.99, 40.72))
                            zoom(11.0)
                            pitch(45.0)
                        }
                    )
                },
                style = {
                    MapboxStandardStyle(
                        standardStyleState = rememberStandardStyleState {
                            configurationsState.apply {
                                lightPreset = LightPresetValue.DAWN
                            }
                            interactionsState.onPlaceLabelsClicked { placeLabel, _ ->
                                placeLabel.setStandardPlaceLabelsState {
                                    select(select = true)
                                }
                                selectedPlaces.add(placeLabel)
                                return@onPlaceLabelsClicked true
                            }
                            interactionsState.onMapLongClicked { _ ->
                                selectedPlaces.forEach {
                                    it.removeFeatureState()
                                }
                                return@onMapLongClicked true
                            }
                        }
                    )
                }
            )
        }
    }
}
```

Your app should now look like the image below. When you tap on a place label, it will change to red. When you long press on the map, all selected place labels will be deselected and return to their original color.

![Screenshot of an Android app showing a map of New York City with several selected red place labels.](https://docs.mapbox.com/help/assets/ideal-img/tutorials--android-interactions-2.867fbec.480.png)

## Import another style to your map

When working with the Mapbox Standard Style you can [import additional styles](https://docs.mapbox.com/map-styles/standard/guides/#style-imports) to your map. This allows you to add specific data and featuresets to your map. For this tutorial, you will need to download the `new-york-hotels` style, which contains a featureset of hotels data, and add it to your Android Studio project. To add the file to your project, in the directory view right-click on `app` then select `New` > `Folder` > `Assets Folder`. In the newly-created `assets` folder, paste the `new-york-hotels.json` file.

[Download JSON](https://docs.mapbox.com/help/help/data/new-york-hotels.json)

### Import the New York Hotels Style

To import the `new-york-hotels` style, you will need to add a new [`StyleImport`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.extension.compose.style.imports/-style-imports-scope/-style-import.html) to the `styleImportsContent` block in your `setContent` function. The `importId` is the name of the style you are importing, and the `style` is the path to the style file. The `styleImportState` is a state object that holds the state of the style import. Add the following code to the `MapboxStandardStyle` block, right below the `standardStyleState` block:

```kotlin
package com.example.interactions // Your package name here

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.mapbox.geojson.Point
import com.mapbox.maps.extension.compose.MapboxMap
import com.mapbox.maps.extension.compose.animation.viewport.rememberMapViewportState
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.unit.dp
import com.mapbox.maps.dsl.cameraOptions
import com.mapbox.maps.extension.compose.style.standard.LightPresetValue
import com.mapbox.maps.extension.compose.style.standard.MapboxStandardStyle
import com.mapbox.maps.extension.compose.style.standard.rememberStandardStyleState
import android.util.Log
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import com.mapbox.maps.interactions.standard.generated.StandardPlaceLabelsFeature

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val selectedPlaces = remember {
                mutableStateListOf<StandardPlaceLabelsFeature>()
            }

            MapboxMap(
                Modifier.fillMaxSize().padding(top = 20.dp),
                mapViewportState = rememberMapViewportState {
                    setCameraOptions(
                        cameraOptions {
                            center(Point.fromLngLat(-73.99, 40.72))
                            zoom(11.0)
                            pitch(45.0)
                        }
                    )
                },
                style = {
                    MapboxStandardStyle(
                        standardStyleState = rememberStandardStyleState {
                            configurationsState.apply {
                                lightPreset = LightPresetValue.DAWN
                            }
                            interactionsState.onPlaceLabelsClicked { placeLabel, _ ->
                                placeLabel.setStandardPlaceLabelsState {
                                    select(select = true)
                                }
                                selectedPlaces.add(placeLabel)
                                return@onPlaceLabelsClicked true
                            }
                            interactionsState.onMapLongClicked { _ ->
                                selectedPlaces.forEach {
                                    it.removeFeatureState()
                                }
                                return@onMapLongClicked true
                            }
                        },
                        styleImportsContent = {
                            StyleImport(
                                importId = "new-york-hotels",
                                style = "asset://new-york-hotels.json",
                                styleImportState = rememberStyleImportState()
                            )
                        }
                    )
                }
            )
        }
    }
}
```

If you rebuild your app, you should see the new style imported into your map. It will show subway lines, small circles representing real estate listings, and several pop-ups with price information about the listings.

![Screenshot of an Android app showing a map of New York City with hotel listings.](https://docs.mapbox.com/help/assets/ideal-img/tutorials--android-interactions-3.93bec04.480.png)

## Add a Click Interaction to the Hotel Listings

Next, add a [`ClickInteraction`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps/-click-interaction/) to the real estate listings. The `new-york-hotels` style contains a featureset called `hotels-price`. This featureset exposes the price of hotels in New York City. To add a `ClickInteraction` to the `hotels-price` featureset, first add a new variable to your `setContent` block. This will hold the selected price label when it is clicked.

```kotlin
package com.example.interactions // Your package name here

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.mapbox.geojson.Point
import com.mapbox.maps.extension.compose.MapboxMap
import com.mapbox.maps.extension.compose.animation.viewport.rememberMapViewportState
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.unit.dp
import com.mapbox.maps.dsl.cameraOptions
import com.mapbox.maps.extension.compose.style.standard.LightPresetValue
import com.mapbox.maps.extension.compose.style.standard.MapboxStandardStyle
import com.mapbox.maps.extension.compose.style.standard.rememberStandardStyleState
import android.util.Log
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import com.mapbox.maps.extension.compose.style.imports.rememberStyleImportState
import com.mapbox.maps.interactions.standard.generated.StandardPlaceLabelsFeature
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.getValue
import com.mapbox.maps.interactions.FeatureState
import com.mapbox.maps.interactions.FeaturesetFeature
import com.mapbox.maps.extension.compose.annotation.ViewAnnotation
import com.mapbox.maps.viewannotation.viewAnnotationOptions
import androidx.compose.foundation.layout.Box
import com.mapbox.maps.viewannotation.geometry
import androidx.compose.ui.draw.shadow
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val selectedPlaces = remember {
                mutableStateListOf<StandardPlaceLabelsFeature>()
            }

            var selectedPriceLabel by remember {
                mutableStateOf<FeaturesetFeature<FeatureState>?>(null)
            }

            MapboxMap(
                Modifier.fillMaxSize().padding(top = 20.dp),
                mapViewportState = rememberMapViewportState {
                    setCameraOptions(
                        cameraOptions {
                            center(Point.fromLngLat(-73.99, 40.72))
                            zoom(11.0)
                            pitch(45.0)
                        }
                    )
                },
                style = {
                    MapboxStandardStyle(
                        standardStyleState = rememberStandardStyleState {
                            configurationsState.apply {
                                lightPreset = LightPresetValue.DAWN
                            }
                            interactionsState.onPlaceLabelsClicked { placeLabel, _ ->
                                placeLabel.setStandardPlaceLabelsState {
                                    select(select = true)
                                }
                                selectedPlaces.add(placeLabel)
                                return@onPlaceLabelsClicked true
                            }
                            interactionsState.onMapLongClicked { _ ->
                                selectedPlaces.forEach {
                                    it.removeFeatureState()
                                }
                                return@onMapLongClicked true
                            }
                        },
                        styleImportsContent = {
                            StyleImport(
                                importId = "new-york-hotels",
                                style = "asset://new-york-hotels.json",
                                styleImportState = rememberStyleImportState {
                                    interactionsState.onFeaturesetClicked("hotels-price") { priceLabel, _ ->
                                        if (selectedPriceLabel?.id != priceLabel.id) {
                                            selectedPriceLabel = priceLabel
                                            selectedPriceLabel?.setFeatureState(
                                                FeatureState {
                                                    addBooleanState("hidden", true)
                                                }
                                            )
                                        }
                                        return@onFeaturesetClicked true
                                    }
                                }
                            )
                        }
                    )
                }
            ) {
                selectedPriceLabel?.let {
                    ViewAnnotation(
                        options = viewAnnotationOptions {
                            // Fallback to the center of the map if the geometry is null
                            geometry(selectedPriceLabel?.geometry ?: Point.fromLngLat(-73.99, 40.72))
                        }
                    ) {
                        Box(
                            modifier = Modifier
                                .shadow(
                                    elevation = 8.dp,
                                )
                                .background(MaterialTheme.colorScheme.primary)
                        ) {
                            Column(
                                modifier = Modifier
                                    .align(Alignment.Center)
                                    .padding(20.dp)
                            ) {
                                Text(
                                    text = "${selectedPriceLabel?.properties?.getString("name")}",
                                    fontSize = 20.sp,
                                    color = Color.White
                                )
                                Text(
                                    text = "$${selectedPriceLabel?.properties?.getString("price")}",
                                    fontSize = 15.sp,
                                    color = Color.White
                                )
                            }
                        }
                    }
                }
            }
        }
    }
}
```

Then add the following code to your `StyleImport` body, replacing the existing `rememberStyleImportState()`. This will add a `onFeaturesetClicked` interaction to the `hotels-price` featureset. When a user clicks on a price label the code will confirm that the clicked price label is not already selected. It will then set the `selectedPriceLabel` to the clicked price label and set the Feature's `hidden` FeatureState to `true`. This will hide the selected price label from the map.

```kotlin
package com.example.interactions // Your package name here

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.mapbox.geojson.Point
import com.mapbox.maps.extension.compose.MapboxMap
import com.mapbox.maps.extension.compose.animation.viewport.rememberMapViewportState
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.unit.dp
import com.mapbox.maps.dsl.cameraOptions
import com.mapbox.maps.extension.compose.style.standard.LightPresetValue
import com.mapbox.maps.extension.compose.style.standard.MapboxStandardStyle
import com.mapbox.maps.extension.compose.style.standard.rememberStandardStyleState
import android.util.Log
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import com.mapbox.maps.extension.compose.style.imports.rememberStyleImportState
import com.mapbox.maps.interactions.standard.generated.StandardPlaceLabelsFeature
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.getValue
import com.mapbox.maps.interactions.FeatureState
import com.mapbox.maps.interactions.FeaturesetFeature
import com.mapbox.maps.extension.compose.annotation.ViewAnnotation
import com.mapbox.maps.viewannotation.viewAnnotationOptions
import androidx.compose.foundation.layout.Box
import com.mapbox.maps.viewannotation.geometry
import androidx.compose.ui.draw.shadow
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val selectedPlaces = remember {
                mutableStateListOf<StandardPlaceLabelsFeature>()
            }

            var selectedPriceLabel by remember {
                mutableStateOf<FeaturesetFeature<FeatureState>?>(null)
            }

            MapboxMap(
                Modifier.fillMaxSize().padding(top = 20.dp),
                mapViewportState = rememberMapViewportState {
                    setCameraOptions(
                        cameraOptions {
                            center(Point.fromLngLat(-73.99, 40.72))
                            zoom(11.0)
                            pitch(45.0)
                        }
                    )
                },
                style = {
                    MapboxStandardStyle(
                        standardStyleState = rememberStandardStyleState {
                            configurationsState.apply {
                                lightPreset = LightPresetValue.DAWN
                            }
                            interactionsState.onPlaceLabelsClicked { placeLabel, _ ->
                                placeLabel.setStandardPlaceLabelsState {
                                    select(select = true)
                                }
                                selectedPlaces.add(placeLabel)
                                return@onPlaceLabelsClicked true
                            }
                            interactionsState.onMapLongClicked { _ ->
                                selectedPlaces.forEach {
                                    it.removeFeatureState()
                                }
                                return@onMapLongClicked true
                            }
                        },
                        styleImportsContent = {
                            StyleImport(
                                importId = "new-york-hotels",
                                style = "asset://new-york-hotels.json",
                                styleImportState = rememberStyleImportState {
                                    interactionsState.onFeaturesetClicked("hotels-price") { priceLabel, _ ->
                                        if (selectedPriceLabel?.id != priceLabel.id) {
                                            selectedPriceLabel = priceLabel
                                            selectedPriceLabel?.setFeatureState(
                                                FeatureState {
                                                    addBooleanState("hidden", true)
                                                }
                                            )
                                        }
                                        return@onFeaturesetClicked true
                                    }
                                }
                            )
                        }
                    )
                }
            ) {
                selectedPriceLabel?.let {
                    ViewAnnotation(
                        options = viewAnnotationOptions {
                            // Fallback to the center of the map if the geometry is null
                            geometry(selectedPriceLabel?.geometry ?: Point.fromLngLat(-73.99, 40.72))
                        }
                    ) {
                        Box(
                            modifier = Modifier
                                .shadow(
                                    elevation = 8.dp,
                                )
                                .background(MaterialTheme.colorScheme.primary)
                        ) {
                            Column(
                                modifier = Modifier
                                    .align(Alignment.Center)
                                    .padding(20.dp)
                            ) {
                                Text(
                                    text = "${selectedPriceLabel?.properties?.getString("name")}",
                                    fontSize = 20.sp,
                                    color = Color.White
                                )
                                Text(
                                    text = "$${selectedPriceLabel?.properties?.getString("price")}",
                                    fontSize = 15.sp,
                                    color = Color.White
                                )
                            }
                        }
                    }
                }
            }
        }
    }
}
```

The code hides the selected price label from the map so that it can be replaced with a custom [`ViewAnnotation`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.extension.compose.annotation/-view-annotation.html). Add the following code to the bottom of the `MapboxMap` function. This will create a custom `ViewAnnotation` that displays the name and price of the selected hotel listing. The `ViewAnnotation` will be displayed at the location of the selected price label.

```kotlin
package com.example.interactions // Your package name here

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.mapbox.geojson.Point
import com.mapbox.maps.extension.compose.MapboxMap
import com.mapbox.maps.extension.compose.animation.viewport.rememberMapViewportState
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.unit.dp
import com.mapbox.maps.dsl.cameraOptions
import com.mapbox.maps.extension.compose.style.standard.LightPresetValue
import com.mapbox.maps.extension.compose.style.standard.MapboxStandardStyle
import com.mapbox.maps.extension.compose.style.standard.rememberStandardStyleState
import android.util.Log
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import com.mapbox.maps.extension.compose.style.imports.rememberStyleImportState
import com.mapbox.maps.interactions.standard.generated.StandardPlaceLabelsFeature
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.getValue
import com.mapbox.maps.interactions.FeatureState
import com.mapbox.maps.interactions.FeaturesetFeature
import com.mapbox.maps.extension.compose.annotation.ViewAnnotation
import com.mapbox.maps.viewannotation.viewAnnotationOptions
import androidx.compose.foundation.layout.Box
import com.mapbox.maps.viewannotation.geometry
import androidx.compose.ui.draw.shadow
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val selectedPlaces = remember {
                mutableStateListOf<StandardPlaceLabelsFeature>()
            }

            var selectedPriceLabel by remember {
                mutableStateOf<FeaturesetFeature<FeatureState>?>(null)
            }

            MapboxMap(
                Modifier.fillMaxSize().padding(top = 20.dp),
                mapViewportState = rememberMapViewportState {
                    setCameraOptions(
                        cameraOptions {
                            center(Point.fromLngLat(-73.99, 40.72))
                            zoom(11.0)
                            pitch(45.0)
                        }
                    )
                },
                style = {
                    MapboxStandardStyle(
                        standardStyleState = rememberStandardStyleState {
                            configurationsState.apply {
                                lightPreset = LightPresetValue.DAWN
                            }
                            interactionsState.onPlaceLabelsClicked { placeLabel, _ ->
                                placeLabel.setStandardPlaceLabelsState {
                                    select(select = true)
                                }
                                selectedPlaces.add(placeLabel)
                                return@onPlaceLabelsClicked true
                            }
                            interactionsState.onMapLongClicked { _ ->
                                selectedPlaces.forEach {
                                    it.removeFeatureState()
                                }
                                return@onMapLongClicked true
                            }
                        },
                        styleImportsContent = {
                            StyleImport(
                                importId = "new-york-hotels",
                                style = "asset://new-york-hotels.json",
                                styleImportState = rememberStyleImportState {
                                    interactionsState.onFeaturesetClicked("hotels-price") { priceLabel, _ ->
                                        if (selectedPriceLabel?.id != priceLabel.id) {
                                            selectedPriceLabel = priceLabel
                                            selectedPriceLabel?.setFeatureState(
                                                FeatureState {
                                                    addBooleanState("hidden", true)
                                                }
                                            )
                                        }
                                        return@onFeaturesetClicked true
                                    }
                                }
                            )
                        }
                    )
                }
            ) {
                selectedPriceLabel?.let {
                    ViewAnnotation(
                        options = viewAnnotationOptions {
                            // Fallback to the center of the map if the geometry is null
                            geometry(selectedPriceLabel?.geometry ?: Point.fromLngLat(-73.99, 40.72))
                        }
                    ) {
                        Box(
                            modifier = Modifier
                                .shadow(
                                    elevation = 8.dp,
                                )
                                .background(MaterialTheme.colorScheme.primary)
                        ) {
                            Column(
                                modifier = Modifier
                                    .align(Alignment.Center)
                                    .padding(20.dp)
                            ) {
                                Text(
                                    text = "${selectedPriceLabel?.properties?.getString("name")}",
                                    fontSize = 20.sp,
                                    color = Color.White
                                )
                                Text(
                                    text = "$${selectedPriceLabel?.properties?.getString("price")}",
                                    fontSize = 15.sp,
                                    color = Color.White
                                )
                            }
                        }
                    }
                }
            }
        }
    }
}
```

![Screenshot of an Android app showing a map of New York City with a price listing popup.](https://docs.mapbox.com/help/assets/ideal-img/tutorials--android-interactions-4.97e7d10.480.png)

## Finished product

Your app should now be complete! You can select place labels to change their color to red, and you can select hotel listings to show a custom callout with the price of the listing. You can also long press on the map to remove the selected place labels.

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/help/help/assets/medias/tutorials--android-interactions-complete-da91a9ae6108d09f362d96ebd35e8082.webm).

Your full `MainActivity` class should look like this:

```kotlin
package com.example.interactions // Your package name here

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.mapbox.geojson.Point
import com.mapbox.maps.extension.compose.MapboxMap
import com.mapbox.maps.extension.compose.animation.viewport.rememberMapViewportState
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.unit.dp
import com.mapbox.maps.dsl.cameraOptions
import com.mapbox.maps.extension.compose.style.standard.LightPresetValue
import com.mapbox.maps.extension.compose.style.standard.MapboxStandardStyle
import com.mapbox.maps.extension.compose.style.standard.rememberStandardStyleState
import android.util.Log
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import com.mapbox.maps.extension.compose.style.imports.rememberStyleImportState
import com.mapbox.maps.interactions.standard.generated.StandardPlaceLabelsFeature
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.getValue
import com.mapbox.maps.interactions.FeatureState
import com.mapbox.maps.interactions.FeaturesetFeature
import com.mapbox.maps.extension.compose.annotation.ViewAnnotation
import com.mapbox.maps.viewannotation.viewAnnotationOptions
import androidx.compose.foundation.layout.Box
import com.mapbox.maps.viewannotation.geometry
import androidx.compose.ui.draw.shadow
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val selectedPlaces = remember {
                mutableStateListOf<StandardPlaceLabelsFeature>()
            }

            var selectedPriceLabel by remember {
                mutableStateOf<FeaturesetFeature<FeatureState>?>(null)
            }

            MapboxMap(
                Modifier.fillMaxSize().padding(top = 20.dp),
                mapViewportState = rememberMapViewportState {
                    setCameraOptions(
                        cameraOptions {
                            center(Point.fromLngLat(-73.99, 40.72))
                            zoom(11.0)
                            pitch(45.0)
                        }
                    )
                },
                style = {
                    MapboxStandardStyle(
                        standardStyleState = rememberStandardStyleState {
                            configurationsState.apply {
                                lightPreset = LightPresetValue.DAWN
                            }
                            interactionsState.onPlaceLabelsClicked { placeLabel, _ ->
                                placeLabel.setStandardPlaceLabelsState {
                                    select(select = true)
                                }
                                selectedPlaces.add(placeLabel)
                                return@onPlaceLabelsClicked true
                            }
                            interactionsState.onMapLongClicked { _ ->
                                selectedPlaces.forEach {
                                    it.removeFeatureState()
                                }
                                return@onMapLongClicked true
                            }
                        },
                        styleImportsContent = {
                            StyleImport(
                                importId = "new-york-hotels",
                                style = "asset://new-york-hotels.json",
                                styleImportState = rememberStyleImportState {
                                    interactionsState.onFeaturesetClicked("hotels-price") { priceLabel, _ ->
                                        if (selectedPriceLabel?.id != priceLabel.id) {
                                            selectedPriceLabel = priceLabel
                                            selectedPriceLabel?.setFeatureState(
                                                FeatureState {
                                                    addBooleanState("hidden", true)
                                                }
                                            )
                                        }
                                        return@onFeaturesetClicked true
                                    }
                                }
                            )
                        }
                    )
                }
            ) {
                selectedPriceLabel?.let {
                    ViewAnnotation(
                        options = viewAnnotationOptions {
                            // Fallback to the center of the map if the geometry is null
                            geometry(selectedPriceLabel?.geometry ?: Point.fromLngLat(-73.99, 40.72))
                        }
                    ) {
                        Box(
                            modifier = Modifier
                                .shadow(
                                    elevation = 8.dp,
                                )
                                .background(MaterialTheme.colorScheme.primary)
                        ) {
                            Column(
                                modifier = Modifier
                                    .align(Alignment.Center)
                                    .padding(20.dp)
                            ) {
                                Text(
                                    text = "${selectedPriceLabel?.properties?.getString("name")}",
                                    fontSize = 20.sp,
                                    color = Color.White
                                )
                                Text(
                                    text = "$${selectedPriceLabel?.properties?.getString("price")}",
                                    fontSize = 15.sp,
                                    color = Color.White
                                )
                            }
                        }
                    }
                }
            }
        }
    }
}
```

## Next steps

Congratulations! You have successfully added interactions to your map using the Mapbox Maps SDK for Android. You can now add custom styles and interactions to your map, allowing you to create a more engaging user experience.

### What we covered

-   Add a `onPlaceLabelsClicked` to the `StandardPlaceLabels` featureset
-   Add a `onMapLongClicked` to remove selected place labels
-   Import a custom style to your map, and add an `onFeaturesetClicked` to the `hotels-price` featureset
-   Create a custom `ViewAnnotation` to display the price of a hotel listing

### Learn more

If you'd like an additional challenge try implementing the following features:

-   Add an interaction to the subway lines to show the name of the subway line when tapped.
-   Adjust the styling of the `ViewAnnotation`.
-   Instead of one selected price label, allow multiple price labels to be selected at once.

> **Related content (guide): [Learn about the Mapbox Standard Style](https://docs.mapbox.com/map-styles/standard/guides/)**
> 
> Learn more about the [Mapbox Standard Style](https://docs.mapbox.com/map-styles/standard/guides/) and how to use it in your Android app.

> **Related content (guide): [Learn about the Interactions API](https://docs.mapbox.com/android/maps/guides/user-interaction/interactions/)**
> 
> Learn more about the [Interactions API](https://docs.mapbox.com/android/maps/guides/user-interaction/interactions/) and how to use it in your Android app.

> **Related content (example): [Add interactions to with the Standard style](https://docs.mapbox.com/android/maps/examples/compose/add-interaction-to-featuresets/)**
> 
> Learn how to add interactions to predefined featuresets in the Standard Style using the Mapbox Maps SDK for Android.