NavigationImage and padding
This commit is contained in:
@@ -20,12 +20,12 @@ android {
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
getByName("debug") {
|
||||
keyAlias = "alias"
|
||||
keyPassword = "alpha2000"
|
||||
storeFile = file("/home/kouros/work/keystore/keystoreDebug")
|
||||
storePassword = "alpha2000"
|
||||
}
|
||||
// getByName("debug") {
|
||||
// keyAlias = "alias"
|
||||
// keyPassword = "alpha2000"
|
||||
// storeFile = file("/home/kouros/work/keystore/keystoreRelease")
|
||||
// storePassword = "alpha2000"
|
||||
// }
|
||||
create("release") {
|
||||
keyAlias = "release"
|
||||
keyPassword = "zeta67#g"
|
||||
|
||||
@@ -256,6 +256,7 @@ class MainActivity : ComponentActivity() {
|
||||
fun Map() {
|
||||
val step: StepData? by instruction.observeAsState()
|
||||
Column {
|
||||
//SimpleSearchBar()
|
||||
if (step != null) {
|
||||
NavigationInfo(step)
|
||||
}
|
||||
|
||||
79
app/src/main/java/com/kouros/navigation/SearchBar.kt
Normal file
79
app/src/main/java/com/kouros/navigation/SearchBar.kt
Normal file
@@ -0,0 +1,79 @@
|
||||
package com.kouros.navigation
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.input.TextFieldState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.SearchBar
|
||||
import androidx.compose.material3.SearchBarDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.semantics.isTraversalGroup
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.semantics.traversalIndex
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun SimpleSearchBar(
|
||||
textFieldState: TextFieldState,
|
||||
onSearch: (String) -> Unit,
|
||||
searchResults: List<String>,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
// Controls expansion state of the search bar
|
||||
var expanded by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
Box(
|
||||
modifier
|
||||
.fillMaxSize()
|
||||
.semantics { isTraversalGroup = true }
|
||||
) {
|
||||
SearchBar(
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopCenter)
|
||||
.semantics { traversalIndex = 0f },
|
||||
inputField = {
|
||||
SearchBarDefaults.InputField(
|
||||
query = textFieldState.text.toString(),
|
||||
onQueryChange = { textFieldState.edit { replace(0, length, it) } },
|
||||
onSearch = {
|
||||
onSearch(textFieldState.text.toString())
|
||||
expanded = false
|
||||
},
|
||||
expanded = expanded,
|
||||
onExpandedChange = { expanded = it },
|
||||
placeholder = { Text("Search") }
|
||||
)
|
||||
},
|
||||
expanded = expanded,
|
||||
onExpandedChange = { expanded = it },
|
||||
) {
|
||||
// Display search results in a scrollable column
|
||||
Column(Modifier.verticalScroll(rememberScrollState())) {
|
||||
searchResults.forEach { result ->
|
||||
ListItem(
|
||||
headlineContent = { Text(result) },
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
textFieldState.edit { replace(0, length, result) }
|
||||
expanded = false
|
||||
}
|
||||
.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,22 +3,18 @@ package com.kouros.navigation.car
|
||||
import android.location.Location
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Badge
|
||||
import androidx.compose.material3.BadgedBox
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.drawBehind
|
||||
import androidx.compose.ui.draw.drawWithCache
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.Path
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
@@ -54,7 +50,7 @@ fun cameraState(
|
||||
tilt: Double,
|
||||
preview: Boolean
|
||||
): CameraState {
|
||||
val padding = getPaddingValues(width, height, preview)
|
||||
val padding = getPaddingValues(height, preview)
|
||||
return rememberCameraState(
|
||||
firstPosition =
|
||||
CameraPosition(
|
||||
@@ -118,29 +114,46 @@ fun BuildingLayer(tiles: Source) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DrawImage(location: Location) {
|
||||
val textMeasurer = rememberTextMeasurer()
|
||||
fun DrawImage(width: Int, height: Int, location: Location) {
|
||||
NavigationImage(height)
|
||||
Speed(width, height, location)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NavigationImage(height: Int) {
|
||||
val vector = ImageVector.vectorResource(id = R.drawable.assistant_navigation_48px)
|
||||
val painter = rememberVectorPainter(image = vector)
|
||||
val tint = remember { ColorFilter.tint(NavigationColor) }
|
||||
|
||||
Box(
|
||||
val color = remember { NavigationColor }
|
||||
BadgedBox(
|
||||
modifier = Modifier
|
||||
.size(48.dp, 48.dp)
|
||||
.padding(start = 450.dp - 30.dp, top = 350.dp - 30.dp)
|
||||
.drawBehind {
|
||||
with(painter) {
|
||||
draw(
|
||||
size = Size(60F, 60F),
|
||||
colorFilter = tint,
|
||||
)
|
||||
}
|
||||
})
|
||||
.padding(
|
||||
start = 0.dp, top = distanceFromTop(height).dp
|
||||
),
|
||||
badge = {
|
||||
Badge()
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
imageVector = vector,
|
||||
contentDescription = "Navigation",
|
||||
tint = color
|
||||
)
|
||||
}
|
||||
}
|
||||
@Composable
|
||||
private fun Speed(
|
||||
width: Int,
|
||||
height: Int,
|
||||
location: Location
|
||||
) {
|
||||
|
||||
val textMeasurer = rememberTextMeasurer()
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(30.dp, 30.dp)
|
||||
.padding(start = 650.dp, top = 350.dp)
|
||||
.padding(
|
||||
start = width.dp - percent(width, 20).dp,
|
||||
top = height.dp - 60.dp
|
||||
)
|
||||
.drawWithCache {
|
||||
val measuredText =
|
||||
textMeasurer.measure(
|
||||
@@ -157,6 +170,24 @@ fun DrawImage(location: Location) {
|
||||
)
|
||||
}
|
||||
|
||||
fun getPaddingValues(height: Int, preView: Boolean): PaddingValues {
|
||||
val padding = PaddingValues(start = 0.dp, top = distanceFromTop(height).dp)
|
||||
val prePadding = PaddingValues(start = 150.dp, bottom = 0.dp)
|
||||
return if (preView) {
|
||||
prePadding
|
||||
} else {
|
||||
padding
|
||||
}
|
||||
}
|
||||
|
||||
fun distanceFromTop(height: Int): Int {
|
||||
return height - percent(height, 20)
|
||||
}
|
||||
|
||||
fun percent(maxValue: Int, value: Int): Int {
|
||||
return value * maxValue / 100
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Puck(cameraState: CameraState, location: Location) {
|
||||
LocationPuck(
|
||||
@@ -189,12 +220,3 @@ fun PuckState(cameraState: CameraState, userLocationState: UserLocationState) {
|
||||
)
|
||||
}
|
||||
|
||||
fun getPaddingValues(width: Int, height: Int, preView: Boolean): PaddingValues {
|
||||
val padding = PaddingValues(start = 100.dp, top = 300.dp)
|
||||
val prePadding = PaddingValues(start = 150.dp, bottom = 0.dp)
|
||||
return if (preView) {
|
||||
prePadding
|
||||
} else {
|
||||
padding
|
||||
}
|
||||
}
|
||||
@@ -206,7 +206,6 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
||||
if (routeModel.isNavigating()) {
|
||||
val snapedLocation = snapLocation(location, routeModel.route.maneuverLocations())
|
||||
val distance = location.distanceTo(snapedLocation)
|
||||
println(distance)
|
||||
if (distance > MAXIMAL_ROUTE_DEVIATION) {
|
||||
// navigationScreen.calculateNewRoute()
|
||||
//return
|
||||
|
||||
@@ -6,7 +6,9 @@ import android.hardware.display.DisplayManager
|
||||
import android.hardware.display.VirtualDisplay
|
||||
import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.car.app.AppManager
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.SurfaceCallback
|
||||
@@ -25,14 +27,10 @@ import androidx.lifecycle.setViewTreeLifecycleOwner
|
||||
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
|
||||
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||
import com.kouros.navigation.data.Constants
|
||||
import com.kouros.navigation.data.Constants.MAXIMAL_ROUTE_DEVIATION
|
||||
import com.kouros.navigation.data.Constants.NEXT_STEP_THRESHOLD
|
||||
import com.kouros.navigation.data.Constants.SHOW_THREED_BUILDING
|
||||
import com.kouros.navigation.model.RouteModel
|
||||
import com.kouros.navigation.utils.NavigationUtils.getBooleanKeyValue
|
||||
import com.kouros.navigation.utils.NavigationUtils.snapLocation
|
||||
import com.kouros.navigation.utils.calculateZoom
|
||||
import com.kouros.navigation.utils.location
|
||||
import org.maplibre.compose.camera.CameraPosition
|
||||
import org.maplibre.compose.camera.CameraState
|
||||
import org.maplibre.compose.map.MaplibreMap
|
||||
@@ -87,6 +85,7 @@ class SurfaceRenderer(
|
||||
|
||||
lateinit var presentation: Presentation
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
override fun onSurfaceAvailable(surfaceContainer: SurfaceContainer) {
|
||||
synchronized(this@SurfaceRenderer) {
|
||||
Log.i(TAG, "Surface available $surfaceContainer")
|
||||
@@ -136,6 +135,7 @@ class SurfaceRenderer(
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.KITKAT)
|
||||
override fun onSurfaceDestroyed(surfaceContainer: SurfaceContainer) {
|
||||
synchronized(this@SurfaceRenderer) {
|
||||
Log.i(TAG, "SurfaceRenderer destroyed")
|
||||
@@ -168,10 +168,11 @@ class SurfaceRenderer(
|
||||
val route: String? by routeData.observeAsState()
|
||||
val previewRoute: String? by previewRouteData.observeAsState()
|
||||
val cameraState = cameraState(width, height, position, tilt, preview)
|
||||
val baseStyle =
|
||||
if (isSystemInDarkTheme()) BaseStyle.Uri(Constants.STYLE_DARK) else BaseStyle.Uri(
|
||||
Constants.STYLE
|
||||
)
|
||||
|
||||
val baseStyle =BaseStyle.Uri(Constants.STYLE)
|
||||
// if (isSystemInDarkTheme()) BaseStyle.Uri(Constants.STYLE_DARK) else BaseStyle.Uri(
|
||||
// Constants.STYLE
|
||||
// )
|
||||
|
||||
MaplibreMap(
|
||||
cameraState = cameraState,
|
||||
@@ -196,7 +197,7 @@ class SurfaceRenderer(
|
||||
var target = position.target
|
||||
var localTilt = tilt
|
||||
if (!preview) {
|
||||
DrawImage(lastLocation)
|
||||
DrawImage(width, height,lastLocation)
|
||||
} else {
|
||||
bearing = 0.0
|
||||
zoom = previewZoom()
|
||||
@@ -210,7 +211,7 @@ class SurfaceRenderer(
|
||||
zoom = zoom,
|
||||
target = target,
|
||||
tilt = localTilt,
|
||||
padding = getPaddingValues(width, height, preview)
|
||||
padding = getPaddingValues(height, preview)
|
||||
),
|
||||
duration = cameraDuration
|
||||
)
|
||||
@@ -230,7 +231,7 @@ class SurfaceRenderer(
|
||||
val cameraDuration = if ((lastBearing - position!!.bearing).absoluteValue > 20.0) {
|
||||
2.seconds
|
||||
} else {
|
||||
2.seconds
|
||||
1.seconds
|
||||
}
|
||||
return cameraDuration
|
||||
}
|
||||
@@ -286,7 +287,7 @@ class SurfaceRenderer(
|
||||
bearing = bearing,
|
||||
zoom = zoom,
|
||||
tilt = 0.0,
|
||||
padding = getPaddingValues(width, height, preview),
|
||||
padding = getPaddingValues(height, preview),
|
||||
target = target
|
||||
)
|
||||
)
|
||||
|
||||
10
common/car/src/main/res/drawable/navigation_48px.xml
Normal file
10
common/car/src/main/res/drawable/navigation_48px.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M190,840L160,810L480,80L800,810L770,840L480,708L190,840ZM258,742L480,644L702,742L480,228L258,742ZM480,644L480,644L480,644L480,644Z"/>
|
||||
</vector>
|
||||
@@ -17,8 +17,6 @@
|
||||
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="back_caps_action_title" msgid="6392829425035919422">"ZURÜCK"</string>
|
||||
<string name="home_caps_action_title" msgid="4853167242566949502">"STARTSEITE"</string>
|
||||
<string name="exit_action_title" msgid="9086586388884500731">"Beenden"</string>
|
||||
<string name="refresh_action_title" msgid="3674260822403151377">"Aktualisieren"</string>
|
||||
<string name="close_action_title" msgid="2661907510124308560">"Schließen"</string>
|
||||
@@ -28,7 +26,6 @@
|
||||
<string name="stop_action_title" msgid="1187619482795416314">"Stopp"</string>
|
||||
<string name="more_action_title" msgid="1039516575011403837">"Mehr"</string>
|
||||
<string name="call_action_title" msgid="6218977436905001611">"Anrufen"</string>
|
||||
<string name="primary_action_title" msgid="7042003552215710683">"Primär"</string>
|
||||
<string name="options_action_title" msgid="1168121856107932984">"Optionen"</string>
|
||||
<string name="search_action_title" msgid="3483459674263446335">"Suchen"</string>
|
||||
<string name="checked_action_title" msgid="906023941445896399">"Aktiviert"</string>
|
||||
@@ -42,7 +39,6 @@
|
||||
<string name="throw_action_title" msgid="7163710562670220163">"Auslösen"</string>
|
||||
<string name="commute_action_title" msgid="2585755255290185096">"Arbeitsweg"</string>
|
||||
<string name="sign_out_action_title" msgid="1653943000866713010">"Abmelden"</string>
|
||||
<string name="try_anyway_action_title" msgid="7384500054249311718">"Trotzdem versuchen"</string>
|
||||
<string name="yes_action_title" msgid="5507096013762092189">"Ja"</string>
|
||||
<string name="no_action_title" msgid="1452124604210014010">"Nein"</string>
|
||||
<string name="disable_all_rows" msgid="3003225080532928046">"Alle Zeilen deaktivieren"</string>
|
||||
@@ -77,7 +73,6 @@
|
||||
<string name="car_hardware_demo_title" msgid="3679106197233262689">"Demo der Auto-Hardware"</string>
|
||||
<string name="car_hardware_info" msgid="1244783247616395012">"Informationen zur Auto-Hardware"</string>
|
||||
<string name="model_info" msgid="494224423025683030">"Modellinformationen"</string>
|
||||
<string name="no_model_permission" msgid="5333629877014978947">"Keine Berechtigung für Modell"</string>
|
||||
<string name="manufacturer_unavailable" msgid="4978995415869838056">"Hersteller nicht verfügbar"</string>
|
||||
<string name="model_unavailable" msgid="4075463010215406573">"Modell nicht verfügbar"</string>
|
||||
<string name="year_unavailable" msgid="994338773299644607">"Jahr nicht verfügbar"</string>
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
<string name="app_name" translatable="false">Navigation</string>
|
||||
|
||||
<!-- Action Titles -->
|
||||
<string name="back_caps_action_title">BACK</string>
|
||||
<string name="home_caps_action_title">HOME</string>
|
||||
<string name="exit_action_title">Exit</string>
|
||||
<string name="refresh_action_title">Refresh</string>
|
||||
<string name="close_action_title">Close</string>
|
||||
@@ -28,7 +26,6 @@
|
||||
<string name="stop_action_title">Stop</string>
|
||||
<string name="more_action_title">More</string>
|
||||
<string name="call_action_title">Call</string>
|
||||
<string name="primary_action_title">Primary</string>
|
||||
<string name="options_action_title">Options</string>
|
||||
<string name="search_action_title">Search</string>
|
||||
<string name="checked_action_title">Checked</string>
|
||||
@@ -42,7 +39,6 @@
|
||||
<string name="throw_action_title">Throw</string>
|
||||
<string name="commute_action_title">Commute</string>
|
||||
<string name="sign_out_action_title">Sign out</string>
|
||||
<string name="try_anyway_action_title">Try Anyway</string>
|
||||
<string name="yes_action_title">Yes</string>
|
||||
<string name="no_action_title">No</string>
|
||||
<string name="disable_all_rows">Disable All Rows</string>
|
||||
@@ -87,7 +83,6 @@
|
||||
<!-- CarHardwareInfoScreen -->
|
||||
<string name="car_hardware_info">Car Hardware Information</string>
|
||||
<string name="model_info">Model Information</string>
|
||||
<string name="no_model_permission">No Model Permission</string>
|
||||
<string name="manufacturer_unavailable">Manufacturer unavailable</string>
|
||||
<string name="model_unavailable">Model unavailable</string>
|
||||
<string name="year_unavailable">Year unavailable</string>
|
||||
|
||||
@@ -2,6 +2,6 @@ package com.kouros.navigation.data
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
val NavigationColor = Color(0xFF094DB6)
|
||||
val NavigationColor = Color(0xFF052086)
|
||||
|
||||
val RouteColor = Color(0xFF5582D0)
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.kouros.navigation.utils
|
||||
import android.content.Context
|
||||
import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.edit
|
||||
import com.kouros.navigation.data.Constants.MAXIMAL_ROUTE_DEVIATION
|
||||
import com.kouros.navigation.data.Constants.SHARED_PREF_KEY
|
||||
@@ -43,6 +45,7 @@ object NavigationUtils {
|
||||
.getBoolean(key, false)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.GINGERBREAD)
|
||||
fun setBooleanKeyValue(context: Context, `val`: Boolean, key: String) {
|
||||
context
|
||||
.getSharedPreferences(
|
||||
@@ -64,6 +67,11 @@ object NavigationUtils {
|
||||
val point = pointFeature.geometry() as Point
|
||||
newLocation.latitude = point.latitude()
|
||||
newLocation.longitude = point.longitude()
|
||||
newLocation.speed = location.speed
|
||||
newLocation.bearing = location.bearing
|
||||
newLocation.time = location.time
|
||||
newLocation.accuracy = location.accuracy
|
||||
newLocation.altitude = location.altitude
|
||||
}
|
||||
return newLocation
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user