summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/RecyclerViewActivity.kt
blob: 9989d1b1376d8fbeb6a69f1871406208b47ca993 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package com.mapbox.mapboxsdk.testapp.activity.maplayout

import android.annotation.SuppressLint
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import com.mapbox.mapboxsdk.maps.MapView
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
import com.mapbox.mapboxsdk.maps.Style
import com.mapbox.mapboxsdk.testapp.R
import kotlinx.android.synthetic.main.activity_recyclerview.*

/**
 * TestActivity showcasing how to integrate a MapView in a RecyclerView.
 * <p>
 * It requires calling the correct lifecycle methods when detaching and attaching the View to
 * the RecyclerView with onViewAttachedToWindow and onViewDetachedFromWindow.
 * </p>
 */
@SuppressLint("ClickableViewAccessibility")
class RecyclerViewActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_recyclerview)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = ItemAdapter(LayoutInflater.from(this), savedInstanceState)
    }

    override fun onSaveInstanceState(outState: Bundle?) {
        super.onSaveInstanceState(outState)
        // to save state, we need to call MapView#onSaveInstanceState
        (recyclerView.adapter as ItemAdapter).onSaveInstanceState(outState)
    }

    override fun onLowMemory() {
        super.onLowMemory()
        // to release memory, we need to call MapView#onLowMemory
        (recyclerView.adapter as ItemAdapter).onLowMemory()
    }

    override fun onDestroy() {
        super.onDestroy()
        // to perform cleanup, we need to call MapView#onDestroy
        (recyclerView.adapter as ItemAdapter).onDestroy()
    }

    class ItemAdapter(private val inflater: LayoutInflater, val savedInstanceState: Bundle?) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

        private val items = listOf(
                "one", "two", "three", MapItem(), "four", "five", "six", "seven", "eight", "nine", "ten",
                "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
                "nineteen", "twenty", "twenty-one"
        )

        private var mapHolder: MapHolder? = null

        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) {
                val mapView = inflater.inflate(R.layout.item_map, parent, false) as MapView
                mapView.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.MAPBOX_STREETS) }
                mapHolder = MapHolder(mapView, savedInstanceState)
                return mapHolder as 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()
                mapView.onResume()
            }
        }

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

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

        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
            if (holder.itemViewType == TYPE_TEXT) {
                val textHolder = holder as TextHolder
                textHolder.bind(items[position] as String)
            }
        }

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

        fun onSaveInstanceState(savedInstanceState: Bundle?){
            savedInstanceState?.let {
                mapHolder?.mapView?.onSaveInstanceState(it)
            }
        }

        fun onLowMemory() {
            mapHolder?.mapView?.onLowMemory()
        }

        fun onDestroy() {
            mapHolder?.mapView?.let {
                it.onPause()
                it.onStop()
                it.onDestroy()
            }
        }

        class MapItem
        class MapHolder(val mapView: MapView, bundle: Bundle?) : RecyclerView.ViewHolder(mapView) {
            init {
                mapView.onCreate(bundle)
                mapView.setOnTouchListener { view, motionEvent ->
                    // Disallow the touch request for recyclerView scroll
                    view.parent.requestDisallowInterceptTouchEvent(true)
                    mapView.onTouchEvent(motionEvent)
                    true
                }
            }
        }
        class TextHolder(val textView: TextView) : RecyclerView.ViewHolder(textView) {
            fun bind(item: String) {
                textView.text = item
            }
        }
    }
}