Stopover and Legs
This commit is contained in:
@@ -5,7 +5,6 @@ import android.location.LocationManager
|
||||
import androidx.car.app.navigation.model.Maneuver
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.data.Constants.homeHohenwaldeck
|
||||
import com.kouros.navigation.data.RouteEngine
|
||||
import com.kouros.navigation.data.tomtom.TomTomRepository
|
||||
|
||||
@@ -182,6 +182,7 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb
|
||||
init {
|
||||
lifecycle.addObserver(lifecycleObserver)
|
||||
repository.routingEngineFlow.asLiveData().observe(this, Observer {
|
||||
onRoutingEngineStateUpdated(it)
|
||||
routingEngine = it
|
||||
})
|
||||
|
||||
@@ -199,13 +200,15 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb
|
||||
* Creates appropriate repository based on user selection.
|
||||
*/
|
||||
fun onRoutingEngineStateUpdated(routeEngine: Int) {
|
||||
navigationViewModel = when (routeEngine) {
|
||||
RouteEngine.VALHALLA.ordinal -> NavigationViewModel(ValhallaRepository())
|
||||
RouteEngine.OSRM.ordinal -> NavigationViewModel(OsrmRepository())
|
||||
else -> NavigationViewModel(TomTomRepository())
|
||||
if (!::navigationViewModel.isInitialized || routeEngine != routingEngine) {
|
||||
navigationViewModel = when (routeEngine) {
|
||||
RouteEngine.VALHALLA.ordinal -> NavigationViewModel(ValhallaRepository())
|
||||
RouteEngine.OSRM.ordinal -> NavigationViewModel(OsrmRepository())
|
||||
else -> NavigationViewModel(TomTomRepository())
|
||||
}
|
||||
observerManager = NavigationObserverManager(navigationViewModel, this)
|
||||
observerManager.attachAllObservers(this)
|
||||
}
|
||||
observerManager = NavigationObserverManager(navigationViewModel, this)
|
||||
observerManager.attachAllObservers(this)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -578,6 +581,8 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb
|
||||
* Called when user starts navigation
|
||||
*/
|
||||
override fun startNavigation() {
|
||||
Log.d(TAG, "startNavigation")
|
||||
surfaceRenderer.navigation = true
|
||||
surfaceRenderer.viewStyle = ViewStyle.VIEW
|
||||
navigationManager.navigationStarted()
|
||||
navigationManagerStarted = true
|
||||
@@ -597,6 +602,8 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb
|
||||
* Called when user exits navigation or arrives at destination.
|
||||
*/
|
||||
override fun stopNavigation() {
|
||||
Log.d(TAG, "stopNavigation")
|
||||
surfaceRenderer.navigation = false
|
||||
routeModel.stopNavigation()
|
||||
navigationManager.navigationEnded()
|
||||
if (autoDriveEnabled) {
|
||||
@@ -609,6 +616,7 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb
|
||||
navigationScreen.navigationType = NavigationType.VIEW
|
||||
if (notificationActive)
|
||||
notificationManager.stopNotificationService()
|
||||
Log.d(TAG, "end stopNavigation")
|
||||
}
|
||||
|
||||
override fun updateTrip(trip: Trip) {
|
||||
@@ -723,9 +731,20 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb
|
||||
* Loads a route to the specified place and sets it as the destination.
|
||||
*/
|
||||
override fun navigateToPlace(place: Place) {
|
||||
Log.d(TAG, "navigateToPlace ${place.street}")
|
||||
var prevDestination = Place()
|
||||
if (surfaceRenderer.navigation) {
|
||||
prevDestination = routeModel.navState.destination
|
||||
stopNavigation()
|
||||
}
|
||||
val preview = place.route
|
||||
navigationViewModel.previewRoute.value = ""
|
||||
val location = location(place.longitude, place.latitude)
|
||||
val location = if (place.stopOver && prevDestination.latitude != 0.0) {
|
||||
listOf(location(place.longitude, place.latitude), location(prevDestination.longitude, prevDestination.latitude))
|
||||
} else {
|
||||
listOf(location(place.longitude, place.latitude))
|
||||
}
|
||||
|
||||
navigationViewModel.saveRecent(carContext, place)
|
||||
routeModel.navState = routeModel.navState.copy(destination = place)
|
||||
if (preview.isEmpty()) {
|
||||
@@ -813,7 +832,7 @@ class NavigationSession : Session(), NavigationListener, NavigationObserverCallb
|
||||
navigationViewModel.loadRoute(
|
||||
carContext,
|
||||
location,
|
||||
destination,
|
||||
listOf(destination),
|
||||
surfaceRenderer.carOrientation
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,17 +10,12 @@ import androidx.car.app.AppManager
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.SurfaceCallback
|
||||
import androidx.car.app.SurfaceContainer
|
||||
import androidx.compose.animation.core.LinearOutSlowInEasing
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.Lifecycle
|
||||
@@ -54,7 +49,6 @@ import org.maplibre.compose.camera.CameraPosition
|
||||
import org.maplibre.compose.camera.CameraState
|
||||
import org.maplibre.compose.style.BaseStyle
|
||||
import org.maplibre.spatialk.geojson.Position
|
||||
import java.time.Duration
|
||||
import java.time.LocalDateTime
|
||||
|
||||
|
||||
@@ -123,6 +117,9 @@ class SurfaceRenderer(
|
||||
// Current view mode (navigation, preview, etc.)
|
||||
var viewStyle = ViewStyle.VIEW
|
||||
|
||||
// Flag to indicate if in navigation mode
|
||||
var navigation = false
|
||||
|
||||
// Center location for route preview
|
||||
lateinit var centerLocation: Location
|
||||
|
||||
@@ -457,7 +454,7 @@ class SurfaceRenderer(
|
||||
with(routeModel) {
|
||||
routeData.value = curRoute.routeGeoJson
|
||||
centerLocation = curRoute.centerLocation
|
||||
previewDistance = curRoute.summary.distance
|
||||
previewDistance = curLeg.summary.distance
|
||||
}
|
||||
tilt = 0.0
|
||||
updateCameraPosition(
|
||||
@@ -473,8 +470,10 @@ class SurfaceRenderer(
|
||||
* Calculates appropriate zoom
|
||||
*/
|
||||
fun setStandardView() {
|
||||
if (!navigation) {
|
||||
setRouteData("")
|
||||
}
|
||||
viewStyle = ViewStyle.VIEW
|
||||
setRouteData("")
|
||||
val zoom = calculateZoom(0.0)
|
||||
tilt = calculateTilt(zoom, tilt)
|
||||
updateCameraPosition(
|
||||
|
||||
@@ -367,7 +367,7 @@ fun NavigationImage(
|
||||
x = topLeftX ,
|
||||
y = topLeftY,
|
||||
),
|
||||
color = if (darkMode) navigationColor else Color.White,
|
||||
color = if (darkMode) NavigationColorLight else Color.White,
|
||||
cornerRadius = CornerRadius(x = 10f, y = 10f),
|
||||
)
|
||||
drawText(
|
||||
|
||||
@@ -20,14 +20,13 @@ import androidx.car.app.model.ForegroundCarColorSpan
|
||||
import androidx.car.app.navigation.model.Lane
|
||||
import androidx.car.app.navigation.model.LaneDirection
|
||||
import androidx.car.app.navigation.model.Maneuver
|
||||
import androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW
|
||||
import androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW
|
||||
import androidx.car.app.navigation.model.Step
|
||||
import androidx.car.app.navigation.model.TravelEstimate
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.car.screen.createCarIcon
|
||||
import com.kouros.navigation.data.StepData
|
||||
import com.kouros.navigation.data.route.ManeuverType
|
||||
import com.kouros.navigation.model.RouteModel
|
||||
import com.kouros.navigation.utils.formattedDistance
|
||||
import java.time.Duration
|
||||
@@ -47,17 +46,15 @@ class RouteCarModel : RouteModel() {
|
||||
|
||||
val maneuver = Maneuver.Builder(stepData.currentManeuverType)
|
||||
.setIcon(createCarIcon(carContext, stepData.icon))
|
||||
if (stepData.currentManeuverType == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW
|
||||
|| stepData.currentManeuverType == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW
|
||||
if (stepData.currentManeuverType == ManeuverType.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW.ordinal
|
||||
|| stepData.currentManeuverType == ManeuverType.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW.ordinal
|
||||
) {
|
||||
maneuver.setRoundaboutExitNumber(stepData.exitNumber)
|
||||
}
|
||||
val step =
|
||||
Step.Builder(currentStepCueWithImage)
|
||||
|
||||
if (navState.destination.street != null) {
|
||||
step.setRoad(navState.destination.street!!)
|
||||
}
|
||||
step.setRoad(navState.destination.street!!)
|
||||
if (stepData.lane.isNotEmpty()) {
|
||||
val lanesAdded = addLanes(carContext, step, stepData)
|
||||
if (lanesAdded) {
|
||||
@@ -77,8 +74,8 @@ class RouteCarModel : RouteModel() {
|
||||
createString(stepData.instruction)
|
||||
val maneuver = Maneuver.Builder(stepData.currentManeuverType)
|
||||
.setIcon(createCarIcon(carContext, stepData.icon))
|
||||
if (stepData.currentManeuverType == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW
|
||||
|| stepData.currentManeuverType == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW
|
||||
if (stepData.currentManeuverType == ManeuverType.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW.ordinal
|
||||
|| stepData.currentManeuverType == ManeuverType.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW.ordinal
|
||||
) {
|
||||
maneuver.setRoundaboutExitNumber(stepData.exitNumber)
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ class Simulation {
|
||||
) {
|
||||
if (routeModel.navState.route.isRouteValid()) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
gpxSimulation(routeModel, lifecycleScope, updateLocation)
|
||||
//currentSimulation(routeModel, lifecycleScope, updateLocation)
|
||||
//gpxSimulation(routeModel, lifecycleScope, updateLocation)
|
||||
currentSimulation(routeModel, lifecycleScope, updateLocation)
|
||||
} else {
|
||||
currentSimulation(routeModel, lifecycleScope, updateLocation)
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ class CategoryScreen(
|
||||
navigationViewModel.loadRoute(
|
||||
carContext,
|
||||
currentLocation = surfaceRenderer.lastLocation,
|
||||
location(it.lon, it.lat),
|
||||
listOf(location(it.lon, it.lat)),
|
||||
surfaceRenderer.carOrientation
|
||||
)
|
||||
setResult(
|
||||
@@ -197,7 +197,7 @@ class CategoryScreen(
|
||||
@DrawableRes iconRes: Int,
|
||||
scale: Int
|
||||
): Action {
|
||||
return createAction(carContext, iconRes, FLAG_IS_PERSISTENT, {
|
||||
return createAction(carContext, iconRes, FLAG_IS_PERSISTENT, {
|
||||
surfaceRenderer.handleScale(scale)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -117,18 +117,18 @@ open class NavigationScreen(
|
||||
)
|
||||
}, { settingsAction() })
|
||||
return when (navigationType) {
|
||||
NavigationType.NAVIGATION -> navigationTemplate(actionStripBuilder)
|
||||
NavigationType.RECENT -> navigationRecentPlacesTemplate()
|
||||
NavigationType.REROUTE -> navigationRerouteTemplate(actionStripBuilder)
|
||||
NavigationType.ARRIVAL -> navigationEndTemplate(actionStripBuilder)
|
||||
else -> navigationViewTemplate(actionStripBuilder)
|
||||
NavigationType.NAVIGATION -> navigation(actionStripBuilder)
|
||||
NavigationType.RECENT -> navigationRecentPlaces()
|
||||
NavigationType.REROUTE -> navigationReroute(actionStripBuilder)
|
||||
NavigationType.ARRIVAL -> navigationEnd(actionStripBuilder)
|
||||
else -> navigationView(actionStripBuilder)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a NavigationTemplate for the active navigation state.
|
||||
*/
|
||||
private fun navigationTemplate(actionStripBuilder: ActionStrip.Builder): Template {
|
||||
private fun navigation(actionStripBuilder: ActionStrip.Builder): Template {
|
||||
actionStripBuilder.addAction(
|
||||
createAction(
|
||||
carContext,
|
||||
@@ -150,7 +150,7 @@ open class NavigationScreen(
|
||||
carContext = carContext, R.drawable.ic_pan_24,
|
||||
0,
|
||||
onClickAction = {
|
||||
surfaceRenderer.viewStyle = ViewStyle.VIEW
|
||||
surfaceRenderer.setStandardView()
|
||||
invalidate()
|
||||
}
|
||||
)
|
||||
@@ -163,7 +163,7 @@ open class NavigationScreen(
|
||||
/**
|
||||
* Creates and returns a template for the default view state.
|
||||
*/
|
||||
private fun navigationViewTemplate(actionStripBuilder: ActionStrip.Builder): Template {
|
||||
private fun navigationView(actionStripBuilder: ActionStrip.Builder): Template {
|
||||
return NavigationTemplate.Builder()
|
||||
.setBackgroundColor(backGroundColor)
|
||||
.setActionStrip(actionStripBuilder.build())
|
||||
@@ -187,24 +187,24 @@ open class NavigationScreen(
|
||||
/**
|
||||
* Creates and returns a template for the arrival.
|
||||
*/
|
||||
private fun navigationEndTemplate(actionStripBuilder: ActionStrip.Builder): Template {
|
||||
private fun navigationEnd(actionStripBuilder: ActionStrip.Builder): Template {
|
||||
arrivalTimer?.cancel()
|
||||
arrivalTimer = object : CountDownTimer(8000, 1000) {
|
||||
override fun onTick(millisUntilFinished: Long) {}
|
||||
override fun onFinish() {
|
||||
// routeModel.navState = routeModel.navState.copy(arrived = false)
|
||||
// routeModel.navState = routeModel.navState.copy(arrived = false)
|
||||
navigationType = NavigationType.VIEW
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
arrivalTimer?.start()
|
||||
return navigationArrivedTemplate(actionStripBuilder)
|
||||
return navigationArrived(actionStripBuilder)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a NavigationTemplate specifically for when the destination is reached.
|
||||
*/
|
||||
fun navigationArrivedTemplate(actionStripBuilder: ActionStrip.Builder): NavigationTemplate {
|
||||
fun navigationArrived(actionStripBuilder: ActionStrip.Builder): NavigationTemplate {
|
||||
var street = ""
|
||||
if (destinations.first().address != null) {
|
||||
street = destinations.first().address.toString()
|
||||
@@ -226,7 +226,7 @@ open class NavigationScreen(
|
||||
)
|
||||
.build()
|
||||
)
|
||||
// .setBackgroundColor(routeModel.backGroundColor())
|
||||
.setBackgroundColor(backGroundColor)
|
||||
.setActionStrip(actionStripBuilder.build())
|
||||
.setMapActionStrip(
|
||||
mapActionStrip(
|
||||
@@ -247,10 +247,10 @@ open class NavigationScreen(
|
||||
/**
|
||||
* Creates and returns a template showing recent places or destinations.
|
||||
*/
|
||||
fun navigationRecentPlacesTemplate(): Template {
|
||||
fun navigationRecentPlaces(): Template {
|
||||
if (!tripSuggestion || recentPlaces.isEmpty()) {
|
||||
navigationType = NavigationType.VIEW
|
||||
return navigationViewTemplate(
|
||||
return navigationView(
|
||||
createActionStripBuilder(
|
||||
{
|
||||
createAction(
|
||||
@@ -263,7 +263,7 @@ open class NavigationScreen(
|
||||
)
|
||||
}
|
||||
val listBuilder = ItemList.Builder()
|
||||
recentPlaces.filter { it.category == Constants.RECENT && it.distance > 300F }.forEach {
|
||||
recentPlaces.filter { it.category == Constants.RECENT && it.distance > 300F }.forEach {
|
||||
val row = Row.Builder()
|
||||
.setTitle(it.name)
|
||||
.addAction(
|
||||
@@ -316,7 +316,7 @@ open class NavigationScreen(
|
||||
/**
|
||||
* Creates and returns a template for when the route is being recalculated.
|
||||
*/
|
||||
fun navigationRerouteTemplate(actionStripBuilder: ActionStrip.Builder): Template {
|
||||
fun navigationReroute(actionStripBuilder: ActionStrip.Builder): Template {
|
||||
return NavigationTemplate.Builder()
|
||||
.setNavigationInfo(RoutingInfo.Builder().setLoading(true).build())
|
||||
.setActionStrip(actionStripBuilder.build())
|
||||
@@ -486,7 +486,7 @@ open class NavigationScreen(
|
||||
navigationViewModel.loadRoute(
|
||||
carContext,
|
||||
surfaceRenderer.lastLocation,
|
||||
destination,
|
||||
listOf(destination),
|
||||
surfaceRenderer.carOrientation
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.OnScreenResultListener
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.CarIcon
|
||||
@@ -28,7 +27,6 @@ import com.kouros.navigation.data.Constants.CONTACTS
|
||||
import com.kouros.navigation.data.Constants.FAVORITES
|
||||
import com.kouros.navigation.data.Constants.RECENT
|
||||
import com.kouros.navigation.data.Place
|
||||
import com.kouros.navigation.data.ViewStyle
|
||||
import com.kouros.navigation.model.NavigationViewModel
|
||||
import com.kouros.navigation.utils.getSettingsRepository
|
||||
|
||||
@@ -66,41 +64,12 @@ class PlaceListScreen(
|
||||
val itemListBuilder = ItemList.Builder()
|
||||
.setNoItemsMessage(carContext.getString(R.string.no_places))
|
||||
recentPlaces.filter { it.category == category }.forEach {
|
||||
val street = if (it.street != null) {
|
||||
it.street
|
||||
} else {
|
||||
""
|
||||
}
|
||||
val street = it.street
|
||||
val row = Row.Builder()
|
||||
.setImage(contactIcon(null, it.category))
|
||||
.setTitle("$street ${it.city}")
|
||||
.setOnClickListener {
|
||||
place = Place(
|
||||
0,
|
||||
it.name,
|
||||
it.category,
|
||||
it.latitude,
|
||||
it.longitude,
|
||||
it.postalCode,
|
||||
it.city,
|
||||
it.street,
|
||||
// avatar = null
|
||||
)
|
||||
screenManager
|
||||
.pushForResult(
|
||||
RoutePreviewScreen(
|
||||
carContext,
|
||||
RoutePreviewType.MULTI_ROUTE,
|
||||
surfaceRenderer,
|
||||
place,
|
||||
navigationViewModel,
|
||||
)
|
||||
) { obj: Any? ->
|
||||
if (obj != null) {
|
||||
setResult(obj)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
clickOnPlace(it)
|
||||
}
|
||||
if (category != CONTACTS) {
|
||||
row.addText(SpannableString(" ").apply {
|
||||
@@ -138,6 +107,69 @@ class PlaceListScreen(
|
||||
.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Action to navigate to a specific place.
|
||||
*/
|
||||
private fun clickOnPlace(it: Place) {
|
||||
place = Place(
|
||||
0,
|
||||
it.name,
|
||||
it.category,
|
||||
it.latitude,
|
||||
it.longitude,
|
||||
it.postalCode,
|
||||
it.city,
|
||||
it.street,
|
||||
// avatar = null
|
||||
)
|
||||
if (surfaceRenderer.navigation) {
|
||||
startStopOverScreen(place)
|
||||
} else {
|
||||
starPreviewScreen(place)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts preview screen for a specific place.
|
||||
*/
|
||||
private fun starPreviewScreen(place: Place) {
|
||||
screenManager
|
||||
.pushForResult(
|
||||
RoutePreviewScreen(
|
||||
carContext,
|
||||
RoutePreviewType.MULTI_ROUTE,
|
||||
surfaceRenderer,
|
||||
place,
|
||||
navigationViewModel,
|
||||
)
|
||||
) { obj: Any? ->
|
||||
if (obj != null) {
|
||||
setResult(obj)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts preview screen for a specific place.
|
||||
*/
|
||||
private fun startStopOverScreen(place: Place) {
|
||||
screenManager
|
||||
.pushForResult(
|
||||
StopOverScreen(
|
||||
carContext,
|
||||
surfaceRenderer,
|
||||
navigationViewModel,
|
||||
place,
|
||||
)
|
||||
) { obj: Any? ->
|
||||
if (obj != null) {
|
||||
setResult(obj)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Action to delete a place.
|
||||
*/
|
||||
|
||||
@@ -71,6 +71,8 @@ class RoutePreviewScreen(
|
||||
|
||||
var loading = true
|
||||
|
||||
var showAlternativeRoute = true
|
||||
|
||||
private val backPressedCallback = object : OnBackPressedCallback(false) {
|
||||
override fun handleOnBackPressed() {
|
||||
}
|
||||
@@ -82,6 +84,10 @@ class RoutePreviewScreen(
|
||||
routeModel.startNavigation(route)
|
||||
surfaceRenderer.setPreviewRouteData(routeModel)
|
||||
loading = false
|
||||
if (routeModel.route.routes.size == 1) {
|
||||
routeType = RoutePreviewType.SINGLE_ROUTE
|
||||
showAlternativeRoute = false
|
||||
}
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
@@ -139,15 +145,12 @@ class RoutePreviewScreen(
|
||||
}
|
||||
}
|
||||
|
||||
val street = if (destination.street.isEmpty()) {
|
||||
val street = destination.street.ifEmpty {
|
||||
carContext.getString((R.string.route_preview))
|
||||
} else {
|
||||
destination.street
|
||||
}
|
||||
val header = Header.Builder()
|
||||
.setStartHeaderAction(Action.BACK)
|
||||
.setTitle(street)
|
||||
|
||||
if (routeType == RoutePreviewType.SINGLE_ROUTE) {
|
||||
header.addEndHeaderAction(
|
||||
favoriteAction()
|
||||
@@ -174,16 +177,6 @@ class RoutePreviewScreen(
|
||||
.build()
|
||||
listContent.build()
|
||||
} else {
|
||||
val navigateActionIcon: CarIcon = CarIcon.Builder(
|
||||
IconCompat.createWithResource(
|
||||
carContext, R.drawable.navigation_48px
|
||||
)
|
||||
).build()
|
||||
val selectRouteIcon: CarIcon = CarIcon.Builder(
|
||||
IconCompat.createWithResource(
|
||||
carContext, R.drawable.alt_route_48px
|
||||
)
|
||||
).build()
|
||||
val navigateAction =
|
||||
createAction(carContext, R.drawable.navigation_48px, FLAG_DEFAULT,{
|
||||
onNavigate(routeModel.navState.currentRouteIndex)
|
||||
@@ -195,7 +188,10 @@ class RoutePreviewScreen(
|
||||
val listContent = MessageTemplate.Builder(message)
|
||||
.setHeader(header.build())
|
||||
.addAction(navigateAction)
|
||||
.addAction(selectRouteAction)
|
||||
|
||||
if (showAlternativeRoute) {
|
||||
listContent.addAction(selectRouteAction)
|
||||
}
|
||||
if (loading) {
|
||||
listContent.setLoading(true)
|
||||
}
|
||||
@@ -211,7 +207,7 @@ class RoutePreviewScreen(
|
||||
} )).build()
|
||||
|
||||
)
|
||||
if (routeType == RoutePreviewType.MULTI_ROUTE && !routeSelected) {
|
||||
if (routeModel.route.routes.size > 1 && routeType == RoutePreviewType.MULTI_ROUTE && !routeSelected) {
|
||||
template.setActionStrip(createActionStrip {
|
||||
createAction(
|
||||
carContext, R.drawable.navigation_48px,
|
||||
@@ -301,7 +297,7 @@ class RoutePreviewScreen(
|
||||
}
|
||||
|
||||
private fun createRow(route: Routes, index: Int): Row {
|
||||
val navigateAction = createAction(carContext, R.drawable.navigation_48px ) {
|
||||
val navigateAction = createAction(carContext, R.drawable.navigation_48px, FLAG_DEFAULT ) {
|
||||
this.onNavigate(index)
|
||||
}
|
||||
val routeText = createRouteText(route)
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.kouros.navigation.car.screen
|
||||
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.Action.FLAG_DEFAULT
|
||||
import androidx.car.app.model.Action.FLAG_IS_PERSISTENT
|
||||
import androidx.car.app.model.CarText
|
||||
import androidx.car.app.model.Header
|
||||
import androidx.car.app.model.MessageTemplate
|
||||
import androidx.car.app.model.Template
|
||||
import androidx.car.app.navigation.model.MapController
|
||||
import androidx.car.app.navigation.model.MapWithContentTemplate
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.car.SurfaceRenderer
|
||||
import com.kouros.navigation.data.Place
|
||||
import com.kouros.navigation.data.ViewStyle
|
||||
import com.kouros.navigation.model.NavigationViewModel
|
||||
|
||||
class StopOverScreen(
|
||||
private val carContext: CarContext,
|
||||
private val surfaceRenderer: SurfaceRenderer,
|
||||
private val navigationViewModel: NavigationViewModel,
|
||||
private val place: Place,
|
||||
) : Screen(carContext) {
|
||||
override fun onGetTemplate(): MapWithContentTemplate {
|
||||
val cancelAction =
|
||||
createAction(carContext, R.drawable.ic_close_white_24dp, FLAG_IS_PERSISTENT,{
|
||||
finish()
|
||||
})
|
||||
val header = Header.Builder()
|
||||
.setStartHeaderAction(Action.BACK)
|
||||
.addEndHeaderAction(cancelAction)
|
||||
.setTitle(place.street)
|
||||
|
||||
val message = CarText.Builder("Neue Fahrt oder Zwischenstopp einfügen")
|
||||
.build()
|
||||
|
||||
val navigateAction = Action.Builder()
|
||||
.setIcon(createCarIcon(carContext, R.drawable.navigation_48px))
|
||||
.setFlags(FLAG_DEFAULT)
|
||||
.setOnClickListener {
|
||||
setResult(place)
|
||||
finish()
|
||||
}
|
||||
.build()
|
||||
|
||||
val selectRouteAction = Action.Builder()
|
||||
.setIcon(createCarIcon(carContext, R.drawable.alt_route_48px))
|
||||
.setFlags(FLAG_IS_PERSISTENT)
|
||||
.setOnClickListener {
|
||||
place.stopOver = true
|
||||
setResult(place)
|
||||
finish()
|
||||
}
|
||||
.build()
|
||||
|
||||
val listContent = MessageTemplate.Builder(message)
|
||||
.setHeader(header.build())
|
||||
.addAction(navigateAction)
|
||||
.addAction(selectRouteAction)
|
||||
|
||||
val template = MapWithContentTemplate.Builder()
|
||||
.setContentTemplate(listContent.build())
|
||||
|
||||
return template.build()
|
||||
}
|
||||
}
|
||||
+21
@@ -33,6 +33,8 @@ class NavigationSettings(
|
||||
|
||||
private var carLocationToggleState = false
|
||||
|
||||
private var alternativeRoutesToggleState = false
|
||||
|
||||
val settingsViewModel = getSettingsViewModel(carContext)
|
||||
|
||||
init {
|
||||
@@ -41,6 +43,7 @@ class NavigationSettings(
|
||||
settingsViewModel.avoidMotorway.first()
|
||||
settingsViewModel.avoidFerry.first()
|
||||
settingsViewModel.carLocation.first()
|
||||
settingsViewModel.alternativeRoutes.first()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +52,7 @@ class NavigationSettings(
|
||||
tollWayToggleState = settingsViewModel.avoidTollway.value
|
||||
ferryToggleState = settingsViewModel.avoidFerry.value
|
||||
carLocationToggleState = settingsViewModel.carLocation.value
|
||||
alternativeRoutesToggleState = settingsViewModel.alternativeRoutes.value
|
||||
|
||||
val listBuilder = ItemList.Builder()
|
||||
|
||||
@@ -89,6 +93,14 @@ class NavigationSettings(
|
||||
carLocationToggleState = !carLocationToggleState
|
||||
}.setChecked(carLocationToggleState).build()
|
||||
|
||||
// Alternative routes
|
||||
val alternativeRoutesToggle: Toggle =
|
||||
Toggle.Builder { checked: Boolean ->
|
||||
settingsViewModel.onAlternativeRoutes(checked)
|
||||
alternativeRoutesToggleState = !alternativeRoutesToggleState
|
||||
}.setChecked(alternativeRoutesToggleState).build()
|
||||
|
||||
|
||||
listBuilder.addItem(
|
||||
buildRowForTemplate(
|
||||
R.string.use_car_location,
|
||||
@@ -97,6 +109,14 @@ class NavigationSettings(
|
||||
)
|
||||
)
|
||||
|
||||
listBuilder.addItem(
|
||||
buildRowForTemplate(
|
||||
R.string.alternative_routes,
|
||||
alternativeRoutesToggle,
|
||||
createCarIcon(carContext,R.drawable.alt_route_48px)
|
||||
)
|
||||
)
|
||||
|
||||
listBuilder.addItem(
|
||||
buildRowForScreenTemplate(
|
||||
RoutingSettings(carContext, navigationViewModel),
|
||||
@@ -109,6 +129,7 @@ class NavigationSettings(
|
||||
R.string.tomtom_api_key
|
||||
)
|
||||
)
|
||||
|
||||
return ListTemplate.Builder()
|
||||
.setSingleList(listBuilder.build())
|
||||
.setHeader(
|
||||
|
||||
Reference in New Issue
Block a user