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

# RecyclerView

![MapView integration inside a RecyclerView.](https://docs.mapbox.com/android/assets/ideal-img/maps-examples-recyclerview.43da957.480.png)

This example illustrates how to host multiple maps and allow users to cycle through them with the **Mapbox Maps SDK for Android**.

The code below integration attaches and detaches each different [`MapView`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps/-map-view/-map-view.html?query=fun%20MapView(context:%20Context,%20attrs:%20AttributeSet?)) to the android class [`RecyclerView`](https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView) by starting and stopping the `MapView` and changing out the assigned map to cycle through them.

Map items are stored in the `MapItem` data class and binds the data to the corresponding [`ViewHolder`](https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.ViewHolder).

> **Note: Android Examples App Available**
> 
> This example code is part of the **Maps SDK for Android Examples App**, a working Android project [available on GitHub](https://github.com/mapbox/mapbox-maps-android/tree/v11.29.0/). Android developers are encouraged to run the examples app locally to interact with this example in an emulator and explore other features of the Maps SDK.
> 
> See our [Run the Maps SDK for Android Examples App](https://docs.mapbox.com/help/tutorials/maps-sdk-android-examples-app/) tutorial for step-by-step instructions.

**Kotlin**

Title: `SurfaceRecyclerViewActivity.kt`

[View on GitHub](https://github.com/mapbox/mapbox-maps-android/blob/v11.29.0/app/src/main/java/com/mapbox/maps/testapp/examples/SurfaceRecyclerViewActivity.kt)

```kt
package com.mapbox.maps.testapp.examples

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.mapbox.maps.MapView
import com.mapbox.maps.Style
import com.mapbox.maps.plugin.gestures.gestures
import com.mapbox.maps.testapp.R
import com.mapbox.maps.testapp.databinding.ActivityRecyclerBinding

/**
 * Test activity showcasing how to integrate multiple SurfaceView MapViews in a RecyclerView.
 *
 * It requires calling the correct lifecycle methods when detaching and attaching the View to
 * the RecyclerView with onViewAttachedToWindow and onViewDetachedFromWindow.
 *
 */
@SuppressLint("ClickableViewAccessibility")
class SurfaceRecyclerViewActivity : AppCompatActivity() {

  private lateinit var mapView: MapView

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val binding = ActivityRecyclerBinding.inflate(layoutInflater)
    setContentView(binding.root)
    binding.recyclerView.layoutManager = LinearLayoutManager(this)
    binding.recyclerView.adapter = ItemAdapter(this, LayoutInflater.from(this))
  }

  fun getMapItemLayoutId(): Int {
    return R.layout.item_map
  }

  class ItemAdapter(
    private val activity: SurfaceRecyclerViewActivity,
    private val inflater: LayoutInflater
  ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    private val items = List(75) {
      if (it == 4)
        MapItem(Style.STANDARD)
      else
        "Row $it"
    }

    private var mapHolders: MutableList<MapHolder> = mutableListOf()

    companion object {
      const val TYPE_MAP = 0
      const val TYPE_TEXT = 1
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
      return if (viewType == TYPE_MAP) {
        activity.mapView = inflater.inflate(activity.getMapItemLayoutId(), parent, false) as MapView
        val mapHolder = MapHolder(activity.mapView)
        mapHolders.add(mapHolder)
        return mapHolder
      } else {
        TextHolder(inflater.inflate(android.R.layout.simple_list_item_1, parent, false) as TextView)
      }
    }

    override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
      super.onViewAttachedToWindow(holder)
      if (holder is MapHolder) {
        val mapView = holder.mapView
        mapView.onStart()
      }
    }

    override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
      super.onViewDetachedFromWindow(holder)
      if (holder is MapHolder) {
        val mapView = holder.mapView
        mapView.onStop()
      }
    }

    override fun getItemCount(): Int {
      return items.count()
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
      if (holder is TextHolder) {
        holder.bind(items[position] as String)
      } else if (holder is MapHolder) {
        holder.bind(items[position] as MapItem)
      }
    }

    override fun getItemViewType(position: Int): Int {
      return if (items[position] is MapItem) {
        TYPE_MAP
      } else {
        TYPE_TEXT
      }
    }

    data class MapItem(val style: String)
    class MapHolder(val mapView: MapView) : RecyclerView.ViewHolder(mapView) {

      init {
        // unfortunately, if there are multiple maps hosted in one activity, state saving is not possible
        mapView.setOnTouchListener { view, motionEvent ->
          // Disallow the touch request for recyclerView scroll
          view.parent.requestDisallowInterceptTouchEvent(true)
          mapView.onTouchEvent(motionEvent)
          true
        }
      }

      fun bind(mapItem: MapItem) {
        mapView.gestures.scrollEnabled = false
        mapView.mapboxMap.loadStyle(mapItem.style)
      }
    }
  }

  class TextHolder(private val textView: TextView) : RecyclerView.ViewHolder(textView) {
    fun bind(item: String) {
      this.textView.text = item
    }
  }
}
```