Skip to content

Commit

Permalink
Merge branch 'main' into feat/added_support_for_advanced_markers
Browse files Browse the repository at this point in the history
  • Loading branch information
wangela authored Oct 28, 2023
2 parents cd73e39 + d299486 commit 9c28192
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 73 deletions.
41 changes: 33 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ You no longer need to specify the Maps SDK for Android or its Utility Library as

```groovy
dependencies {
implementation 'com.google.maps.android:maps-compose:3.1.1'
implementation 'com.google.maps.android:maps-compose:4.0.0'
// Optionally, you can include the Compose utils library for Clustering, etc.
implementation 'com.google.maps.android:maps-compose-utils:3.1.1'
// Optionally, you can include the Compose utils library for Clustering,
// Street View metadata checks, etc.
implementation 'com.google.maps.android:maps-compose-utils:4.0.0'
// Optionally, you can include the widgets library for ScaleBar, etc.
implementation 'com.google.maps.android:maps-compose-widgets:3.1.1'
implementation 'com.google.maps.android:maps-compose-widgets:4.0.0'
}
```

Expand Down Expand Up @@ -236,7 +237,16 @@ MarkerInfoWindow(
### Street View

You can add a Street View given a location using the `StreetView` composable.
To use it, provide a `StreetViewPanoramaOptions` object as follows:

1. Test whether a Street View location is valid with the the
`fetchStreetViewData` utility from the [`maps-compose-utils` library](#maps-compose-utility-library).

```kotlin
streetViewResult =
fetchStreetViewData(singapore, BuildConfig.MAPS_API_KEY)
```

2. Once the location is confirmed valid, add a Street View composable by providing a `StreetViewPanoramaOptions` object.

```kotlin
val singapore = LatLng(1.3588227, 103.8742114)
Expand Down Expand Up @@ -270,9 +280,9 @@ GoogleMap(

</details>

## Utility Library
## Maps Compose Utility Library

This library also provides optional utilities in the `maps-compose-utils` library.
This library provides optional utilities in the `maps-compose-utils` library from the [Maps SDK for Android Utility Library](https://github.com/googlemaps/android-maps-utils).

### Clustering

Expand All @@ -295,7 +305,22 @@ Clustering(
)
```

## Widgets
### Street View metadata utility

The `fetchStreetViewData` method provides functionality to check whether a location is supported in StreetView. You can avoid errors when adding a Street View panorama to an Android app by calling this metadata utility and only adding a Street View panorama if the response is OK.

> [!IMPORTANT]
> Be sure to [enable Street View Static API](https://goo.gle/enable-sv-static-api) on the project associated with your API key.
You can see example usage
in the [`StreetViewActivity`](https://github.com/googlemaps/android-maps-compose/blob/main/app/src/main/java/com/google/maps/android/compose/StreetViewActivity.kt) of the demo app:

```kotlin
streetViewResult =
fetchStreetViewData(singapore, BuildConfig.MAPS_API_KEY)
```

## Maps Compose Widgets

This library also provides optional composable widgets in the `maps-compose-widgets` library that you can use alongside the `GoogleMap` composable.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class GoogleMapViewTests {
initMap()
assertEquals(CameraMoveStartedReason.NO_MOVEMENT_YET, cameraPositionState.cameraMoveStartedReason)
zoom(shouldAnimate = true, zoomIn = true) {
composeTestRule.waitUntil(1000) {
composeTestRule.waitUntil(timeout2) {
cameraPositionState.isMoving
}
assertTrue(cameraPositionState.isMoving)
Expand All @@ -92,10 +92,10 @@ class GoogleMapViewTests {
fun testCameraReportsNotMoving() {
initMap()
zoom(shouldAnimate = true, zoomIn = true) {
composeTestRule.waitUntil(1000) {
composeTestRule.waitUntil(timeout2) {
cameraPositionState.isMoving
}
composeTestRule.waitUntil(5000) {
composeTestRule.waitUntil(timeout5) {
!cameraPositionState.isMoving
}
assertFalse(cameraPositionState.isMoving)
Expand All @@ -106,10 +106,10 @@ class GoogleMapViewTests {
fun testCameraZoomInAnimation() {
initMap()
zoom(shouldAnimate = true, zoomIn = true) {
composeTestRule.waitUntil(1000) {
composeTestRule.waitUntil(timeout2) {
cameraPositionState.isMoving
}
composeTestRule.waitUntil(3000) {
composeTestRule.waitUntil(timeout3) {
!cameraPositionState.isMoving
}
assertEquals(
Expand All @@ -124,10 +124,10 @@ class GoogleMapViewTests {
fun testCameraZoomIn() {
initMap()
zoom(shouldAnimate = false, zoomIn = true) {
composeTestRule.waitUntil(1000) {
composeTestRule.waitUntil(timeout2) {
cameraPositionState.isMoving
}
composeTestRule.waitUntil(3000) {
composeTestRule.waitUntil(timeout3) {
!cameraPositionState.isMoving
}
assertEquals(
Expand All @@ -142,10 +142,10 @@ class GoogleMapViewTests {
fun testCameraZoomOut() {
initMap()
zoom(shouldAnimate = false, zoomIn = false) {
composeTestRule.waitUntil(1000) {
composeTestRule.waitUntil(timeout2) {
cameraPositionState.isMoving
}
composeTestRule.waitUntil(3000) {
composeTestRule.waitUntil(timeout3) {
!cameraPositionState.isMoving
}
assertEquals(
Expand All @@ -160,10 +160,10 @@ class GoogleMapViewTests {
fun testCameraZoomOutAnimation() {
initMap()
zoom(shouldAnimate = true, zoomIn = false) {
composeTestRule.waitUntil(1000) {
composeTestRule.waitUntil(timeout2) {
cameraPositionState.isMoving
}
composeTestRule.waitUntil(3000) {
composeTestRule.waitUntil(timeout3) {
!cameraPositionState.isMoving
}
assertEquals(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class StreetViewTests {
onClick = onClick
)
}
composeTestRule.waitUntil(10000) {
composeTestRule.waitUntil(timeout5) {
cameraPositionState.location.position.latitude != 0.0 &&
cameraPositionState.location.position.longitude != 0.0
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package com.google.maps.android.compose
import com.google.android.gms.maps.model.LatLng
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
const val timeout2 = 2_000L
const val timeout3 = 3_000L
const val timeout5 = 5_000L

val hasValidApiKey: Boolean =
BuildConfig.MAPS_API_KEY.isNotBlank() && BuildConfig.MAPS_API_KEY != "YOUR_API_KEY"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,17 @@ 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)) }
// This needs to be manually deactivated to avoid having a custom and the native
// location button
val uiSettings by remember { mutableStateOf(MapUiSettings(myLocationButtonEnabled = false)) }
// Observing and controlling the camera's state can be done with a CameraPositionState
val cameraPositionState = rememberCameraPositionState {
position = defaultCameraPosition
Expand All @@ -59,17 +62,16 @@ class CustomControlsActivity : ComponentActivity() {
onMapLoaded = {
isMapLoaded = true
},

myLocationButton = {
MapButton(
"This is a custom location button",
onClick = {
Toast.makeText(
this@CustomControlsActivity,
"Click on my location",
Toast.LENGTH_SHORT
).show()
})
uiSettings = uiSettings,
)
MapButton(
"This is a custom location button",
onClick = {
Toast.makeText(
this@CustomControlsActivity,
"Click on my location",
Toast.LENGTH_SHORT
).show()
})

if (!isMapLoaded) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,31 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.google.android.gms.maps.StreetViewPanoramaOptions
import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.Status
import com.google.maps.android.compose.streetview.StreetView
import com.google.maps.android.compose.streetview.rememberStreetViewCameraPositionState
import com.google.maps.android.ktx.MapsExperimentalFeature
import kotlinx.coroutines.launch
import com.google.maps.android.StreetViewUtils.Companion.fetchStreetViewData

class StreetViewActivity : ComponentActivity() {

private val TAG = StreetViewActivity::class.java.simpleName

// This is an invalid location. If you use it instead of Singapore, the StreetViewUtils
// will return NOT_FOUND.
val invalidLocation = LatLng(32.429634, -96.828891)

@OptIn(MapsExperimentalFeature::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
var isPanningEnabled by remember { mutableStateOf(false) }
var isZoomEnabled by remember { mutableStateOf(false) }
var streetViewResult by remember { mutableStateOf(Status.NOT_FOUND) }

val camera = rememberStreetViewCameraPositionState()
LaunchedEffect(camera) {
launch {
Expand All @@ -69,41 +79,52 @@ class StreetViewActivity : ComponentActivity() {
Log.d(TAG, "Location at: $it")
}
}
launch {
// Be sure to enable the Street View Static API on the project associated with
// this API key using the instructions at https://goo.gle/enable-sv-static-api
streetViewResult =
fetchStreetViewData(singapore, BuildConfig.MAPS_API_KEY)
}
}
Box(Modifier.fillMaxSize(), Alignment.BottomStart) {
StreetView(
Modifier.matchParentSize(),
cameraPositionState = camera,
streetViewPanoramaOptionsFactory = {
StreetViewPanoramaOptions().position(singapore)
},
isPanningGesturesEnabled = isPanningEnabled,
isZoomGesturesEnabled = isZoomEnabled,
onClick = {
Log.d(TAG, "Street view clicked")
},
onLongClick = {
Log.d(TAG, "Street view long clicked")
}
)
Column(
Modifier
.fillMaxWidth()
.background(Color.White)
.padding(8.dp)
) {
StreetViewSwitch(title = "Panning", checked = isPanningEnabled) {
isPanningEnabled = it
}
StreetViewSwitch(title = "Zooming", checked = isZoomEnabled) {
isZoomEnabled = it
if (streetViewResult == Status.OK) {
StreetView(
Modifier.matchParentSize(),
cameraPositionState = camera,
streetViewPanoramaOptionsFactory = {
StreetViewPanoramaOptions().position(singapore)
},
isPanningGesturesEnabled = isPanningEnabled,
isZoomGesturesEnabled = isZoomEnabled,
onClick = {
Log.d(TAG, "Street view clicked")
},
onLongClick = {
Log.d(TAG, "Street view long clicked")
}
)
Column(
Modifier
.fillMaxWidth()
.background(Color.White)
.padding(8.dp)
) {
StreetViewSwitch(title = "Panning", checked = isPanningEnabled) {
isPanningEnabled = it
}
StreetViewSwitch(title = "Zooming", checked = isZoomEnabled) {
isZoomEnabled = it
}
}
} else {
Text("Location not available.")
}
}
}
}
}


@Composable
fun StreetViewSwitch(title: String, checked: Boolean, onCheckedChange: (Boolean) -> Unit) {
Row(Modifier.padding(4.dp)) {
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ ext.projectArtifactId = { project ->

allprojects {
group = 'com.google.maps.android'
version = '3.1.1'
version = '4.0.0'
project.ext.artifactId = rootProject.ext.projectArtifactId(project)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ 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
Expand Down Expand Up @@ -88,7 +87,6 @@ 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
Expand Down Expand Up @@ -119,16 +117,11 @@ public fun GoogleMap(
val currentContentPadding by rememberUpdatedState(contentPadding)

// 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 currentUiSettings by rememberUpdatedState(uiSettings)
val currentMapProperties by rememberUpdatedState(properties)

val parentComposition = rememberCompositionContext()
val currentContent by rememberUpdatedState(content)
val currentLocation by rememberUpdatedState(myLocationButton)

LaunchedEffect(Unit) {
disposingComposition {
Expand All @@ -150,10 +143,6 @@ public fun GoogleMap(
}
}
}
Row(modifier = modifier) {
currentLocation?.invoke()
}

}

internal suspend inline fun disposingComposition(factory: () -> Composition) {
Expand Down
Loading

0 comments on commit 9c28192

Please sign in to comment.