diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8e938ca4..69d8deea 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -57,6 +57,9 @@
+
diff --git a/app/src/main/java/com/google/maps/android/compose/BasicMapActivity.kt b/app/src/main/java/com/google/maps/android/compose/BasicMapActivity.kt
index 0fd27819..78be4448 100644
--- a/app/src/main/java/com/google/maps/android/compose/BasicMapActivity.kt
+++ b/app/src/main/java/com/google/maps/android/compose/BasicMapActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/app/src/main/java/com/google/maps/android/compose/CustomControlsActivity.kt b/app/src/main/java/com/google/maps/android/compose/CustomControlsActivity.kt
new file mode 100644
index 00000000..1efae7d7
--- /dev/null
+++ b/app/src/main/java/com/google/maps/android/compose/CustomControlsActivity.kt
@@ -0,0 +1,109 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.maps.android.compose
+
+import android.os.Bundle
+import android.widget.Toast
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.EnterTransition
+import androidx.compose.animation.fadeOut
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.material.Button
+import androidx.compose.material.ButtonDefaults
+import androidx.compose.material.CircularProgressIndicator
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+
+class CustomControlsActivity : ComponentActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ setContent {
+ var isMapLoaded by remember { mutableStateOf(false) }
+ val mapProperties by remember { mutableStateOf(MapProperties(isMyLocationEnabled = true)) }
+ // Observing and controlling the camera's state can be done with a CameraPositionState
+ val cameraPositionState = rememberCameraPositionState {
+ position = defaultCameraPosition
+ }
+
+ Box(Modifier.fillMaxSize()) {
+ GoogleMap(
+ modifier = Modifier.matchParentSize(),
+ cameraPositionState = cameraPositionState,
+ onMapLoaded = {
+ isMapLoaded = true
+ },
+
+ myLocationButton = {
+ MapButton(
+ "This is a custom location button",
+ onClick = {
+ Toast.makeText(
+ this@CustomControlsActivity,
+ "Click on my location",
+ Toast.LENGTH_SHORT
+ ).show()
+ })
+ })
+
+ if (!isMapLoaded) {
+ AnimatedVisibility(
+ modifier = Modifier
+ .matchParentSize(),
+ visible = !isMapLoaded,
+ enter = EnterTransition.None,
+ exit = fadeOut()
+ ) {
+ CircularProgressIndicator(
+ modifier = Modifier
+ .background(MaterialTheme.colors.background)
+ .wrapContentSize()
+ )
+ }
+ }
+ }
+ }
+ }
+
+ @Composable
+ private fun MapButton(text: String, onClick: () -> Unit, modifier: Modifier = Modifier) {
+ Button(
+ modifier = modifier.padding(4.dp),
+ colors = ButtonDefaults.buttonColors(
+ backgroundColor = MaterialTheme.colors.onPrimary,
+ contentColor = MaterialTheme.colors.primary
+ ),
+ onClick = onClick
+ ) {
+ Text(text = text, style = MaterialTheme.typography.body1)
+ }
+ }
+
+
+}
diff --git a/app/src/main/java/com/google/maps/android/compose/LocationTrackingActivity.kt b/app/src/main/java/com/google/maps/android/compose/LocationTrackingActivity.kt
index 86462124..3eed60a0 100644
--- a/app/src/main/java/com/google/maps/android/compose/LocationTrackingActivity.kt
+++ b/app/src/main/java/com/google/maps/android/compose/LocationTrackingActivity.kt
@@ -1,3 +1,18 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
package com.google.maps.android.compose
import android.location.Location
@@ -100,6 +115,9 @@ class LocationTrackingActivity : AppCompatActivity() {
onMapLoaded = {
isMapLoaded = true
},
+ // This listener overrides the behavior for the location button. It is intended to be used when a
+ // custom behavior is needed.
+ onMyLocationButtonClick = { Log.d(TAG,"Overriding the onMyLocationButtonClick with this Log"); true },
locationSource = locationSource,
properties = mapProperties
)
diff --git a/app/src/main/java/com/google/maps/android/compose/MainActivity.kt b/app/src/main/java/com/google/maps/android/compose/MainActivity.kt
index b452868a..ff8e0bdc 100644
--- a/app/src/main/java/com/google/maps/android/compose/MainActivity.kt
+++ b/app/src/main/java/com/google/maps/android/compose/MainActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -112,6 +112,13 @@ class MainActivity : ComponentActivity() {
}) {
Text(getString(R.string.street_view))
}
+ Spacer(modifier = Modifier.padding(5.dp))
+ Button(
+ onClick = {
+ context.startActivity(Intent(context, CustomControlsActivity::class.java))
+ }) {
+ Text(getString(R.string.custom_location_button))
+ }
}
}
}
diff --git a/app/src/main/java/com/google/maps/android/compose/StreetViewActivity.kt b/app/src/main/java/com/google/maps/android/compose/StreetViewActivity.kt
index e7d4d6be..d344318e 100644
--- a/app/src/main/java/com/google/maps/android/compose/StreetViewActivity.kt
+++ b/app/src/main/java/com/google/maps/android/compose/StreetViewActivity.kt
@@ -1,3 +1,17 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
package com.google.maps.android.compose
import android.os.Bundle
@@ -12,12 +26,8 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.LazyRow
-import androidx.compose.material.Button
import androidx.compose.material.Switch
import androidx.compose.material.Text
-import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -28,7 +38,6 @@ import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.text.style.LineHeightStyle
import androidx.compose.ui.unit.dp
import com.google.android.gms.maps.StreetViewPanoramaOptions
import com.google.maps.android.compose.streetview.StreetView
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5e7a0bc2..dd10f260 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -23,4 +23,5 @@
Location Tracking
Scale Bar
Street View
+ Custom Location Button
\ No newline at end of file
diff --git a/maps-compose/src/main/java/com/google/maps/android/compose/GoogleMap.kt b/maps-compose/src/main/java/com/google/maps/android/compose/GoogleMap.kt
index dff08bb0..da27b122 100644
--- a/maps-compose/src/main/java/com/google/maps/android/compose/GoogleMap.kt
+++ b/maps-compose/src/main/java/com/google/maps/android/compose/GoogleMap.kt
@@ -20,6 +20,7 @@ import android.location.Location
import android.os.Bundle
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composition
import androidx.compose.runtime.CompositionContext
@@ -87,6 +88,7 @@ public fun GoogleMap(
onMyLocationClick: ((Location) -> Unit)? = null,
onPOIClick: ((PointOfInterest) -> Unit)? = null,
contentPadding: PaddingValues = NoPadding,
+ myLocationButton: (@Composable @GoogleMapComposable () -> Unit)? = null,
content: (@Composable @GoogleMapComposable () -> Unit)? = null,
) {
// When in preview, early return a Box with the received modifier preserving layout
@@ -115,11 +117,18 @@ public fun GoogleMap(
val currentLocationSource by rememberUpdatedState(locationSource)
val currentCameraPositionState by rememberUpdatedState(cameraPositionState)
val currentContentPadding by rememberUpdatedState(contentPadding)
- val currentUiSettings by rememberUpdatedState(uiSettings)
+
+ // If we pass a custom location button, the native one is deactivated.
+ val currentUiSettings by rememberUpdatedState(if (myLocationButton != null) {
+ uiSettings.copy(myLocationButtonEnabled = false)
+ } else {
+ uiSettings
+ })
val currentMapProperties by rememberUpdatedState(properties)
val parentComposition = rememberCompositionContext()
val currentContent by rememberUpdatedState(content)
+ val currentLocation by rememberUpdatedState(myLocationButton)
LaunchedEffect(Unit) {
disposingComposition {
@@ -141,6 +150,10 @@ public fun GoogleMap(
}
}
}
+ Row(modifier = modifier) {
+ currentLocation?.invoke()
+ }
+
}
internal suspend inline fun disposingComposition(factory: () -> Composition) {
diff --git a/maps-compose/src/main/java/com/google/maps/android/compose/MapClickListeners.kt b/maps-compose/src/main/java/com/google/maps/android/compose/MapClickListeners.kt
index a09af9cc..15b5a124 100644
--- a/maps-compose/src/main/java/com/google/maps/android/compose/MapClickListeners.kt
+++ b/maps-compose/src/main/java/com/google/maps/android/compose/MapClickListeners.kt
@@ -1,4 +1,4 @@
-// Copyright 2022 Google LLC
+// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/maps-compose/src/main/java/com/google/maps/android/compose/MapUpdater.kt b/maps-compose/src/main/java/com/google/maps/android/compose/MapUpdater.kt
index 634591b0..34d63b74 100644
--- a/maps-compose/src/main/java/com/google/maps/android/compose/MapUpdater.kt
+++ b/maps-compose/src/main/java/com/google/maps/android/compose/MapUpdater.kt
@@ -1,4 +1,4 @@
-// Copyright 2022 Google LLC
+// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -75,12 +75,14 @@ internal class MapPropertiesNode(
map.setOnCameraMoveListener {
cameraPositionState.rawPosition = map.cameraPosition
}
+
map.setOnMapClickListener(clickListeners.onMapClick)
map.setOnMapLongClickListener(clickListeners.onMapLongClick)
map.setOnMapLoadedCallback(clickListeners.onMapLoaded)
- map.setOnMyLocationButtonClickListener(clickListeners.onMyLocationButtonClick)
+ map.setOnMyLocationButtonClickListener { clickListeners.onMyLocationButtonClick?.invoke() == true }
map.setOnMyLocationClickListener(clickListeners.onMyLocationClick)
map.setOnPoiClickListener(clickListeners.onPOIClick)
+
map.setOnIndoorStateChangeListener(object : GoogleMap.OnIndoorStateChangeListener {
override fun onIndoorBuildingFocused() {
clickListeners.indoorStateChangeListener.onIndoorBuildingFocused()