Skip to content

Commit 9aef581

Browse files
committed
Remove mapbox navigation from PlaceListOnMapScreen
1 parent 0b00489 commit 9aef581

File tree

5 files changed

+157
-137
lines changed

5 files changed

+157
-137
lines changed

libnavui-androidauto/src/main/java/com/mapbox/androidauto/car/MainActionStrip.kt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import androidx.core.graphics.drawable.IconCompat
99
import com.mapbox.androidauto.R
1010
import com.mapbox.androidauto.car.feedback.core.CarFeedbackSender
1111
import com.mapbox.androidauto.car.feedback.ui.CarFeedbackAction
12-
import com.mapbox.androidauto.car.placeslistonmap.PlaceMarkerRenderer
13-
import com.mapbox.androidauto.car.placeslistonmap.PlacesListItemMapper
1412
import com.mapbox.androidauto.car.placeslistonmap.PlacesListOnMapScreen
1513
import com.mapbox.androidauto.car.search.FavoritesApi
1614
import com.mapbox.androidauto.car.search.PlaceSearchScreen
@@ -94,14 +92,6 @@ class MainActionStrip(
9492
return PlacesListOnMapScreen(
9593
mainCarContext,
9694
placesProvider,
97-
PlacesListItemMapper(
98-
PlaceMarkerRenderer(mainCarContext.carContext),
99-
mainCarContext
100-
.mapboxNavigation
101-
.navigationOptions
102-
.distanceFormatterOptions
103-
.unitType
104-
),
10595
listOf(
10696
CarFeedbackAction(
10797
mainCarContext.mapboxCarMap,
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package com.mapbox.androidauto.car.placeslistonmap
2+
3+
import androidx.car.app.model.ItemList
4+
import com.mapbox.androidauto.MapboxCarApp
5+
import com.mapbox.androidauto.car.MainCarContext
6+
import com.mapbox.androidauto.car.preview.CarRouteRequest
7+
import com.mapbox.androidauto.car.preview.CarRouteRequestCallback
8+
import com.mapbox.androidauto.car.search.PlaceRecord
9+
import com.mapbox.androidauto.internal.car.extensions.getStyle
10+
import com.mapbox.androidauto.internal.car.extensions.handleStyleOnAttached
11+
import com.mapbox.androidauto.internal.car.extensions.handleStyleOnDetached
12+
import com.mapbox.androidauto.internal.car.extensions.mapboxNavigationForward
13+
import com.mapbox.androidauto.internal.logAndroidAuto
14+
import com.mapbox.androidauto.navigation.location.CarAppLocation
15+
import com.mapbox.geojson.Feature
16+
import com.mapbox.geojson.FeatureCollection
17+
import com.mapbox.geojson.Point
18+
import com.mapbox.maps.MapboxExperimental
19+
import com.mapbox.maps.extension.androidauto.MapboxCarMapObserver
20+
import com.mapbox.maps.extension.androidauto.MapboxCarMapSurface
21+
import com.mapbox.maps.plugin.delegates.listeners.OnStyleLoadedListener
22+
import com.mapbox.navigation.core.MapboxNavigation
23+
import com.mapbox.navigation.core.lifecycle.MapboxNavigationApp
24+
import kotlinx.coroutines.CoroutineScope
25+
import kotlinx.coroutines.Dispatchers
26+
import kotlinx.coroutines.MainScope
27+
import kotlinx.coroutines.cancel
28+
import kotlinx.coroutines.flow.MutableStateFlow
29+
import kotlinx.coroutines.flow.StateFlow
30+
import kotlinx.coroutines.flow.asStateFlow
31+
import kotlinx.coroutines.launch
32+
import kotlinx.coroutines.withContext
33+
34+
@OptIn(MapboxExperimental::class)
35+
class PlacesListOnMapManager(
36+
private val mainCarContext: MainCarContext,
37+
private val placesListOnMapProvider: PlacesListOnMapProvider,
38+
private val carRouteRequestCallback: CarRouteRequestCallback,
39+
private val placesLayerUtil: PlacesListOnMapLayerUtil = PlacesListOnMapLayerUtil(),
40+
) : MapboxCarMapObserver {
41+
42+
private var coroutineScope: CoroutineScope? = null
43+
private var styleLoadedListener: OnStyleLoadedListener? = null
44+
private var placesListItemMapper: PlacesListItemMapper? = null
45+
private var carRouteRequest: CarRouteRequest? = null
46+
private val navigationObserver = mapboxNavigationForward(this::onAttached) { onDetached() }
47+
private val placeClickListener = object : PlacesListItemClickListener {
48+
override fun onItemClick(placeRecord: PlaceRecord) {
49+
logAndroidAuto("PlacesListOnMapScreen request $placeRecord")
50+
carRouteRequest?.request(placeRecord, carRouteRequestCallback)
51+
}
52+
}
53+
private val _placeRecords = MutableStateFlow(listOf<PlaceRecord>())
54+
55+
val placeRecords: StateFlow<List<PlaceRecord>> = _placeRecords.asStateFlow()
56+
57+
fun currentItemList(): ItemList? {
58+
val carAppLocation = MapboxNavigationApp.getObserver(CarAppLocation::class)
59+
val currentLocation = carAppLocation.navigationLocationProvider.lastLocation
60+
?: return null
61+
return placesListItemMapper?.mapToItemList(
62+
currentLocation, placeRecords.value, placeClickListener
63+
)
64+
}
65+
66+
override fun onAttached(mapboxCarMapSurface: MapboxCarMapSurface) {
67+
super.onAttached(mapboxCarMapSurface)
68+
coroutineScope = MainScope()
69+
MapboxNavigationApp.registerObserver(navigationObserver)
70+
71+
styleLoadedListener = mapboxCarMapSurface.handleStyleOnAttached {
72+
placesLayerUtil.initializePlacesListOnMapLayer(
73+
it,
74+
mapboxCarMapSurface.carContext.resources
75+
)
76+
loadPlaceRecords()
77+
}
78+
}
79+
80+
override fun onDetached(mapboxCarMapSurface: MapboxCarMapSurface) {
81+
super.onDetached(mapboxCarMapSurface)
82+
mapboxCarMapSurface.handleStyleOnDetached(styleLoadedListener)?.let {
83+
placesLayerUtil.removePlacesListOnMapLayer(it)
84+
}
85+
styleLoadedListener = null
86+
MapboxNavigationApp.unregisterObserver(navigationObserver)
87+
}
88+
89+
private fun onAttached(mapboxNavigation: MapboxNavigation) {
90+
placesListItemMapper = PlacesListItemMapper(
91+
PlaceMarkerRenderer(mainCarContext.carContext),
92+
mapboxNavigation
93+
.navigationOptions
94+
.distanceFormatterOptions
95+
.unitType
96+
)
97+
carRouteRequest = CarRouteRequest(
98+
mapboxNavigation,
99+
mainCarContext.routeOptionsInterceptor,
100+
MapboxCarApp.carAppLocationService().navigationLocationProvider
101+
)
102+
}
103+
104+
private fun onDetached() {
105+
placesListItemMapper = null
106+
coroutineScope?.cancel()
107+
coroutineScope = null
108+
}
109+
110+
private fun loadPlaceRecords() {
111+
coroutineScope?.launch {
112+
val expectedPlaceRecords = withContext(Dispatchers.IO) {
113+
placesListOnMapProvider.getPlaces()
114+
}
115+
_placeRecords.value = emptyList()
116+
expectedPlaceRecords.fold(
117+
{
118+
logAndroidAuto(
119+
"PlacesListOnMapScreen ${it.errorMessage}, ${it.throwable?.stackTrace}"
120+
)
121+
},
122+
{
123+
_placeRecords.value = it
124+
addPlaceIconsToMap(it)
125+
}
126+
)
127+
}
128+
}
129+
130+
private fun addPlaceIconsToMap(places: List<PlaceRecord>) {
131+
logAndroidAuto("PlacesListOnMapScreen addPlaceIconsToMap with ${places.size} places.")
132+
mainCarContext.mapboxCarMap.carMapSurface?.let { carMapSurface ->
133+
val features = places.filter { it.coordinate != null }.map {
134+
Feature.fromGeometry(
135+
Point.fromLngLat(it.coordinate!!.longitude(), it.coordinate.latitude())
136+
)
137+
}
138+
val featureCollection = FeatureCollection.fromFeatures(features)
139+
carMapSurface.getStyle()?.let {
140+
placesLayerUtil.updatePlacesListOnMapLayer(it, featureCollection)
141+
}
142+
}
143+
}
144+
}

libnavui-androidauto/src/main/java/com/mapbox/androidauto/car/placeslistonmap/PlacesListOnMapScreen.kt

Lines changed: 13 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import androidx.car.app.model.Template
1010
import androidx.car.app.navigation.model.PlaceListNavigationTemplate
1111
import androidx.lifecycle.DefaultLifecycleObserver
1212
import androidx.lifecycle.LifecycleOwner
13-
import com.mapbox.androidauto.MapboxCarApp
1413
import com.mapbox.androidauto.R
1514
import com.mapbox.androidauto.car.MainCarContext
1615
import com.mapbox.androidauto.car.action.MapboxActionProvider
@@ -21,76 +20,24 @@ import com.mapbox.androidauto.car.preview.CarRouteRequestCallback
2120
import com.mapbox.androidauto.car.preview.RoutePreviewCarContext
2221
import com.mapbox.androidauto.car.search.PlaceRecord
2322
import com.mapbox.androidauto.car.search.SearchCarContext
24-
import com.mapbox.androidauto.internal.car.extensions.getStyle
25-
import com.mapbox.androidauto.internal.car.extensions.handleStyleOnAttached
26-
import com.mapbox.androidauto.internal.car.extensions.handleStyleOnDetached
2723
import com.mapbox.androidauto.internal.logAndroidAuto
28-
import com.mapbox.geojson.Feature
29-
import com.mapbox.geojson.FeatureCollection
30-
import com.mapbox.geojson.Point
3124
import com.mapbox.maps.MapboxExperimental
32-
import com.mapbox.maps.extension.androidauto.MapboxCarMapObserver
33-
import com.mapbox.maps.extension.androidauto.MapboxCarMapSurface
34-
import com.mapbox.maps.plugin.delegates.listeners.OnStyleLoadedListener
3525
import com.mapbox.navigation.base.route.NavigationRoute
36-
import kotlinx.coroutines.Dispatchers
37-
import kotlinx.coroutines.cancelChildren
38-
import kotlinx.coroutines.launch
39-
import kotlinx.coroutines.withContext
40-
import java.util.concurrent.CopyOnWriteArrayList
4126

4227
@MapboxExperimental
43-
class PlacesListOnMapScreen(
28+
class PlacesListOnMapScreen constructor(
4429
private val mainCarContext: MainCarContext,
4530
private val placesProvider: PlacesListOnMapProvider,
46-
private val placesListItemMapper: PlacesListItemMapper,
4731
private val actionProviders: List<MapboxActionProvider>,
4832
private val searchCarContext: SearchCarContext = SearchCarContext(mainCarContext),
49-
private val placesLayerUtil: PlacesListOnMapLayerUtil = PlacesListOnMapLayerUtil()
5033
) : Screen(mainCarContext.carContext) {
5134

5235
@VisibleForTesting
5336
var itemList = buildErrorItemList(R.string.car_search_no_results)
5437

55-
private val placeRecords by lazy { CopyOnWriteArrayList<PlaceRecord>() }
56-
private val jobControl by lazy { mainCarContext.getJobControl() }
5738
private val carNavigationCamera = CarLocationsOverviewCamera()
5839
private val locationRenderer = CarLocationRenderer(mainCarContext)
59-
private var styleLoadedListener: OnStyleLoadedListener? = null
60-
61-
private val surfaceListener = object : MapboxCarMapObserver {
62-
63-
override fun onAttached(mapboxCarMapSurface: MapboxCarMapSurface) {
64-
super.onAttached(mapboxCarMapSurface)
65-
logAndroidAuto("PlacesListOnMapScreen loaded")
66-
styleLoadedListener = mapboxCarMapSurface.handleStyleOnAttached {
67-
placesLayerUtil.initializePlacesListOnMapLayer(
68-
it,
69-
carContext.resources
70-
)
71-
loadPlaceRecords()
72-
}
73-
}
74-
75-
override fun onDetached(mapboxCarMapSurface: MapboxCarMapSurface) {
76-
super.onDetached(mapboxCarMapSurface)
77-
logAndroidAuto("PlacesListOnMapScreen detached")
78-
mapboxCarMapSurface.handleStyleOnDetached(styleLoadedListener)?.let {
79-
placesLayerUtil.removePlacesListOnMapLayer(it)
80-
}
81-
}
82-
}
83-
84-
private val placeClickListener = object : PlacesListItemClickListener {
85-
86-
override fun onItemClick(placeRecord: PlaceRecord) {
87-
logAndroidAuto("PlacesListOnMapScreen request $placeRecord")
88-
searchCarContext.carRouteRequest.request(placeRecord, carRouteRequestCallback)
89-
}
90-
}
91-
9240
private val carRouteRequestCallback = object : CarRouteRequestCallback {
93-
9441
override fun onRoutesReady(placeRecord: PlaceRecord, routes: List<NavigationRoute>) {
9542
val routePreviewCarContext = RoutePreviewCarContext(searchCarContext.mainCarContext)
9643
logAndroidAuto("PlacesListOnMapScreen go to CarRoutePreviewScreen ${routes.size}")
@@ -109,49 +56,37 @@ class PlacesListOnMapScreen(
10956
onErrorItemList(R.string.car_search_no_results)
11057
}
11158
}
59+
private val placesListOnMapManager = PlacesListOnMapManager(
60+
mainCarContext,
61+
placesProvider,
62+
carRouteRequestCallback
63+
)
11264

11365
init {
11466
lifecycle.addObserver(object : DefaultLifecycleObserver {
115-
override fun onCreate(owner: LifecycleOwner) {
116-
logAndroidAuto("PlacesListOnMapScreen onCreate")
117-
}
118-
119-
override fun onStart(owner: LifecycleOwner) {
120-
logAndroidAuto("PlacesListOnMapScreen onStart")
121-
}
122-
12367
override fun onResume(owner: LifecycleOwner) {
12468
logAndroidAuto("PlacesListOnMapScreen onResume")
125-
mainCarContext.mapboxCarMap.registerObserver(surfaceListener)
69+
mainCarContext.mapboxCarMap.registerObserver(placesListOnMapManager)
12670
mainCarContext.mapboxCarMap.registerObserver(carNavigationCamera)
12771
mainCarContext.mapboxCarMap.registerObserver(locationRenderer)
12872
}
12973

13074
override fun onPause(owner: LifecycleOwner) {
13175
logAndroidAuto("PlacesListOnMapScreen onPause")
13276
placesProvider.cancel()
133-
jobControl.job.cancelChildren()
13477
mainCarContext.mapboxCarMap.unregisterObserver(locationRenderer)
13578
mainCarContext.mapboxCarMap.unregisterObserver(carNavigationCamera)
136-
mainCarContext.mapboxCarMap.unregisterObserver(surfaceListener)
137-
}
138-
139-
override fun onStop(owner: LifecycleOwner) {
140-
logAndroidAuto("PlacesListOnMapScreen onStop")
141-
}
142-
143-
override fun onDestroy(owner: LifecycleOwner) {
144-
logAndroidAuto("PlacesListOnMapScreen onDestroy")
79+
mainCarContext.mapboxCarMap.unregisterObserver(placesListOnMapManager)
14580
}
14681
})
14782
}
14883

14984
override fun onGetTemplate(): Template {
150-
addPlaceIconsToMap(placeRecords)
151-
val locationProvider = MapboxCarApp.carAppLocationService().navigationLocationProvider
152-
val placesItemList = locationProvider.lastLocation?.run {
153-
placesListItemMapper.mapToItemList(this, placeRecords, placeClickListener)
154-
} ?: ItemList.Builder().build()
85+
val coordinates = placesListOnMapManager.placeRecords.value.mapNotNull { it.coordinate }
86+
carNavigationCamera.updateWithLocations(coordinates)
87+
val placesItemList = placesListOnMapManager.currentItemList()
88+
?: ItemList.Builder().build()
89+
15590
val actionStrip = ActionStrip.Builder().apply {
15691
actionProviders.forEach {
15792
when (it) {
@@ -172,43 +107,6 @@ class PlacesListOnMapScreen(
172107
.build()
173108
}
174109

175-
private fun addPlaceIconsToMap(places: List<PlaceRecord>) {
176-
logAndroidAuto("PlacesListOnMapScreen addPlaceIconsToMap with ${places.size} places.")
177-
mainCarContext.mapboxCarMap.carMapSurface?.let { carMapSurface ->
178-
val features = places.filter { it.coordinate != null }.map {
179-
Feature.fromGeometry(
180-
Point.fromLngLat(it.coordinate!!.longitude(), it.coordinate.latitude())
181-
)
182-
}
183-
val featureCollection = FeatureCollection.fromFeatures(features)
184-
carMapSurface.getStyle()?.let {
185-
placesLayerUtil.updatePlacesListOnMapLayer(it, featureCollection)
186-
}
187-
}
188-
val placesWithCoordinates = places.mapNotNull { it.coordinate }
189-
carNavigationCamera.updateWithLocations(placesWithCoordinates)
190-
}
191-
192-
private fun loadPlaceRecords() {
193-
jobControl.scope.launch {
194-
val expectedPlaceRecords = withContext(Dispatchers.IO) {
195-
placesProvider.getPlaces()
196-
}
197-
placeRecords.clear()
198-
expectedPlaceRecords.fold(
199-
{
200-
logAndroidAuto(
201-
"PlacesListOnMapScreen ${it.errorMessage}, ${it.throwable?.stackTrace}"
202-
)
203-
},
204-
{
205-
placeRecords.addAll(it)
206-
invalidate()
207-
}
208-
)
209-
}
210-
}
211-
212110
private fun onErrorItemList(@StringRes stringRes: Int) {
213111
itemList = buildErrorItemList(stringRes)
214112
invalidate()

libnavui-androidauto/src/main/java/com/mapbox/androidauto/car/search/SearchCarContext.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,4 @@ class SearchCarContext(
2323
mainCarContext.carPlaceSearchOptions,
2424
CarSearchLocationProvider()
2525
)
26-
val carRouteRequest = CarRouteRequest(
27-
mainCarContext.mapboxNavigation,
28-
mainCarContext.routeOptionsInterceptor,
29-
MapboxCarApp.carAppLocationService().navigationLocationProvider
30-
)
3126
}

libnavui-androidauto/src/main/java/com/mapbox/androidauto/deeplink/GeoDeeplinkNavigateAction.kt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,6 @@ class GeoDeeplinkNavigateAction(
4545
return PlacesListOnMapScreen(
4646
mainCarContext,
4747
placesProvider,
48-
PlacesListItemMapper(
49-
PlaceMarkerRenderer(mainCarContext.carContext),
50-
mapboxNavigation
51-
.navigationOptions
52-
.distanceFormatterOptions
53-
.unitType
54-
),
5548
listOf(
5649
CarFeedbackAction(
5750
mainCarContext.mapboxCarMap,

0 commit comments

Comments
 (0)