> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Filter Map

> Applies a selected filter from a predefined map.

```kotlin Signature theme={"system"}
FilterMapConnector(
    filters: Map<Int, Filter>,
    filterState: FilterState,
    selected: Int?,
    groupID: FilterGroupID
)
```

<Card title="Explore example code" icon="github" href="https://github.com/algolia/instantsearch-android/tree/master/examples/android">
  Browse the Filter Map example code on GitHub.
</Card>

## About this widget

Components holding a map of filters, and that can apply a single filter at a time.

## Examples

```kotlin Kotlin icon=code theme={"system"}
import com.algolia.instantsearch.filter.Filter

class MyActivity : AppCompatActivity() {
    val searcher = HitsSearcher(
        applicationID = "YourApplicationID",
        apiKey = "YourSearchOnlyAPIKey",
        indexName = "YourIndexName"
    )
    val filterState = FilterState()
    val gender = "gender"
    val groupGender = groupAnd(gender)
    val filters = mapOf(
        R.id.male to Filter.Facet(gender, "male"),
        R.id.female to Filter.Facet(gender, "female")
    )
    val filterMap = FilterMapConnector(
        filters = filters,
        filterState = filterState,
        groupID = groupGender
    )
    val connection = ConnectionHandler(filterMap, searcher.connectFilterState(filterState))

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val viewGender = FilterMapViewRadioGroup(radioGroupGender)
        connection += filterMap.connectView(viewGender)
        searcher.searchAsync()
    }

    override fun onDestroy() {
        super.onDestroy()
        searcher.cancel()
        connection.disconnect()
    }
}
```

### Low-level API

If you want to fully control the Filter Map components and connect them manually, use the following components:

* `Searcher`. The [`Searcher`](/doc/api-reference/widgets/instantsearch/android) that handles searches.
* `FilterState`. The current state of the filters.
* `FilterMapViewModel`. The logic applied to the filter map.
* `FilterMapView`. The view that renders the filter map.

```kotlin Kotlin icon=code theme={"system"}
import com.algolia.instantsearch.filter.Filter

class MyActivity : AppCompatActivity() {
    val gender = "gender"
    val filterState = FilterState()
    val searcher = HitsSearcher(
        applicationID = "YourApplicationID",
        apiKey = "YourSearchOnlyAPIKey",
        indexName = "YourIndexName"
    )
    val filters = mapOf(
        0 to Filter.Facet(gender, "male"),
        1 to Filter.Facet(gender, "female")
    )
    val viewModel = FilterMapViewModel(filters)
    val connection = ConnectionHandler()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val view =  FilterMapViewRadioGroup(radioGroupGender)
        connection += viewModel.connectFilterState(filterState)
        connection += viewModel.connectView(view)
        connection += viewModel.connectFilterState(filterState)

        searcher.searchAsync()
    }

    override fun onDestroy() {
        super.onDestroy()
        searcher.cancel()
        connection.disconnect()
    }
}
```

### Compose UI

InstantSearch provides the `FilterMapState` as a state model,
which is an implementation of the `FilterMapView` interface.
`FilterMapState` must be connected to the `FilterMapConnector` or `FilterMapViewModel` like any other `FilterMapView` implementation.

```kotlin Kotlin icon=code theme={"system"}
import com.algolia.instantsearch.filter.Filter

class MyActivity : AppCompatActivity() {
    val searcher = HitsSearcher(
        applicationID = "YourApplicationID",
        apiKey = "YourSearchOnlyAPIKey",
        indexName = "YourIndexName"
    )
    val filterState = FilterState()
    val gender = "gender"
    val groupGender = groupAnd(gender)
    val filters = mapOf(
        0 to Filter.Facet(gender, "male"),
        1 to Filter.Facet(gender, "female")
    )
    val filterMapState = FilterMapState()
    val filterMap = FilterMapConnector(
        filters = filters,
        filterState = filterState,
        groupID = groupGender
    )
    val connections = ConnectionHandler(filterMap)

    init {
        connections += searcher.connectFilterState(filterState)
        connections += filterMap.connectView(filterMapState)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyFilterMap(filterMapState) // your own UI composable to display filter map options
        }
        searcher.searchAsync()
    }

    override fun onDestroy() {
        super.onDestroy()
        searcher.cancel()
        connections.disconnect()
    }
}
```

## Parameters

<ParamField body="filters" type="Map<Int, Filter>" required>
  The map of filters to be held.
  The key is an unique identifier for the filter value.

  ```kotlin Kotlin icon=code theme={"system"}
  import com.algolia.instantsearch.filter.Filter

  val gender = "gender"
  val filters = mapOf(
      0 to Filter.Facet(gender, "male"),
      1 to Filter.Facet(gender, "female")
  )
  ```
</ParamField>

<ParamField body="filterState" type="FilterState" required>
  The [`FilterState`](/doc/api-reference/widgets/filter-state/android) that holds filters.
</ParamField>

<ParamField body="selected" type="Int?" default="null">
  The key of the filter selected by default.
</ParamField>

<ParamField body="groupID" type="FilterGroupID" default="FilterGroupID(FilterOperator.And)">
  Groups all created filters under an ID.
</ParamField>

## View

<ParamField body="view" type="FilterMapView" required>
  The view that renders the filter map.
</ParamField>

<ParamField body="presenter" default="FilterPresenterImpl()">
  How to display filters.

  ```kotlin Kotlin icon=code theme={"system"}
  val view = FilterMapViewRadioGroup(radioGroupGender)
  val presenter = FilterPresenterImpl()
  filterMap.connectView(view, presenter)
  ```
</ParamField>
