Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ private fun GoogleMapView(modifier: Modifier, onMapLoaded: () -> Unit) {
var shouldAnimateZoom by remember { mutableStateOf(true) }
var ticker by remember { mutableStateOf(0) }

// Observing and controlling the info window visibility can be done with a MarkerInfoWindowState
val markerInfoWindowState = rememberMarkerInfoWindowState(initialValue = InfoWindowState.SHOWN)

GoogleMap(
modifier = modifier,
cameraPositionState = cameraPositionState,
Expand All @@ -130,6 +133,7 @@ private fun GoogleMapView(modifier: Modifier, onMapLoaded: () -> Unit) {
position = singapore,
title = "Zoom in has been tapped $ticker times.",
onClick = markerClick,
infoWindowState = markerInfoWindowState,
) {
Text(it.title ?: "Title", color = Color.Red)
}
Expand Down Expand Up @@ -158,6 +162,7 @@ private fun GoogleMapView(modifier: Modifier, onMapLoaded: () -> Unit) {
ZoomControls(
shouldAnimateZoom,
uiSettings.zoomControlsEnabled,
isInfoWindowShowingChecked = markerInfoWindowState.state == InfoWindowState.SHOWN,
onZoomOut = {
if (shouldAnimateZoom) {
coroutineScope.launch {
Expand All @@ -182,6 +187,14 @@ private fun GoogleMapView(modifier: Modifier, onMapLoaded: () -> Unit) {
},
onZoomControlsCheckedChange = {
uiSettings = uiSettings.copy(zoomControlsEnabled = it)
},
onInfoWindowShowingChange = { show ->
if (show) {
markerInfoWindowState.show()
}
else {
markerInfoWindowState.hide()
}
}
)
DebugView(cameraPositionState)
Expand Down Expand Up @@ -222,10 +235,12 @@ private fun MapTypeButton(type: MapType, onClick: () -> Unit) {
private fun ZoomControls(
isCameraAnimationChecked: Boolean,
isZoomControlsEnabledChecked: Boolean,
isInfoWindowShowingChecked: Boolean,
onZoomOut: () -> Unit,
onZoomIn: () -> Unit,
onCameraAnimationCheckedChange: (Boolean) -> Unit,
onZoomControlsCheckedChange: (Boolean) -> Unit,
onInfoWindowShowingChange: (Boolean) -> Unit,
) {
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
MapButton("-", onClick = { onZoomOut() })
Expand All @@ -239,6 +254,10 @@ private fun ZoomControls(
Text(text = "Zoom Controls On?")
Switch(isZoomControlsEnabledChecked, onCheckedChange = onZoomControlsCheckedChange)
}
Row(horizontalArrangement = Arrangement.Center) {
Text(text = "Info Window showing?")
Switch(isInfoWindowShowingChecked, onCheckedChange = onInfoWindowShowingChange)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ internal class MapApplier(

// Marker
map.setOnMarkerClickListener { marker ->
decorations.nodeForMarker(marker)
?.onMarkerClick
val node = decorations.nodeForMarker(marker)
node?.infoWindowState?.state = InfoWindowState.SHOWN
node?.onMarkerClick
?.invoke(marker)
?: false
}
Expand All @@ -102,8 +103,7 @@ internal class MapApplier(
}
map.setOnInfoWindowCloseListener { marker ->
decorations.nodeForMarker(marker)
?.onInfoWindowClose
?.invoke(marker)
?.infoWindowState?.state = InfoWindowState.HIDDEN
}
map.setOnInfoWindowLongClickListener { marker ->
decorations.nodeForMarker(marker)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,68 @@ internal class MarkerNode(
var markerDragState: MarkerDragState?,
var onMarkerClick: (Marker) -> Boolean,
var onInfoWindowClick: (Marker) -> Unit,
var onInfoWindowClose: (Marker) -> Unit,
var onInfoWindowLongClick: (Marker) -> Unit,
var infoWindow: (@Composable (Marker) -> Unit)?,
var infoContent: (@Composable (Marker) -> Unit)?,
var infoWindowState: MarkerInfoWindowState?,
) : MapNode {

init {
infoWindowState?.marker = marker
}

override fun onAttached() {
if (this.infoWindowState?.state == InfoWindowState.SHOWN) {
this.marker.showInfoWindow()
} else {
this.marker.hideInfoWindow()
}
}

override fun onRemoved() {
marker.remove()
}
}

@Immutable
enum class InfoWindowState {
SHOWN, HIDDEN
}

class MarkerInfoWindowState(
initialValue: InfoWindowState = InfoWindowState.HIDDEN
) {
var marker: Marker? = null

private var _state: InfoWindowState by mutableStateOf(initialValue)

var state: InfoWindowState
get() = _state
set(value) {
_state = value
if (value == InfoWindowState.SHOWN) {
this.marker?.showInfoWindow()
} else {
this.marker?.hideInfoWindow()
}
}

fun show() {
this.state = InfoWindowState.SHOWN
}

fun hide() {
this.state = InfoWindowState.HIDDEN
}
}

@Composable
fun rememberMarkerInfoWindowState(
initialValue: InfoWindowState = InfoWindowState.HIDDEN
): MarkerInfoWindowState = remember {
MarkerInfoWindowState(initialValue)
}

@Immutable
enum class DragState {
START, DRAG, END
Expand Down Expand Up @@ -80,6 +132,8 @@ fun rememberMarkerDragState(): MarkerDragState = remember {
* @param flat sets if the marker should be flat against the map
* @param icon sets the icon for the marker
* @param infoWindowAnchor the anchor point of the info window on the marker image
* @param infoWindowState a [MarkerInfoWindowState] to be used for controlling and observing info
* window visibility
* @param rotation the rotation of the marker in degrees clockwise about the marker's anchor point
* @param snippet the snippet for the marker
* @param tag optional tag to associate with the marker
Expand All @@ -89,7 +143,6 @@ fun rememberMarkerDragState(): MarkerDragState = remember {
* @param markerDragState a [MarkerDragState] to be used for observing marker drag events
* @param onClick a lambda invoked when the marker is clicked
* @param onInfoWindowClick a lambda invoked when the marker's info window is clicked
* @param onInfoWindowClose a lambda invoked when the marker's info window is closed
* @param onInfoWindowLongClick a lambda invoked when the marker's info window is long clicked
*/
@Composable
Expand All @@ -101,6 +154,7 @@ fun Marker(
flat: Boolean = false,
icon: BitmapDescriptor? = null,
infoWindowAnchor: Offset = Offset(0.5f, 0.0f),
infoWindowState: MarkerInfoWindowState = rememberMarkerInfoWindowState(),
rotation: Float = 0.0f,
snippet: String? = null,
tag: Any? = null,
Expand All @@ -110,7 +164,6 @@ fun Marker(
markerDragState: MarkerDragState? = null,
onClick: (Marker) -> Boolean = { false },
onInfoWindowClick: (Marker) -> Unit = {},
onInfoWindowClose: (Marker) -> Unit = {},
onInfoWindowLongClick: (Marker) -> Unit = {},
) {
MarkerImpl(
Expand All @@ -130,8 +183,8 @@ fun Marker(
markerDragState = markerDragState,
onClick = onClick,
onInfoWindowClick = onInfoWindowClick,
onInfoWindowClose = onInfoWindowClose,
onInfoWindowLongClick = onInfoWindowLongClick,
infoWindowState = infoWindowState,
)
}

Expand All @@ -147,6 +200,8 @@ fun Marker(
* @param flat sets if the marker should be flat against the map
* @param icon sets the icon for the marker
* @param infoWindowAnchor the anchor point of the info window on the marker image
* @param infoWindowState a [MarkerInfoWindowState] to be used for controlling and observing info
* window visibility
* @param rotation the rotation of the marker in degrees clockwise about the marker's anchor point
* @param snippet the snippet for the marker
* @param tag optional tag to associate with the marker
Expand All @@ -156,7 +211,6 @@ fun Marker(
* @param markerDragState a [MarkerDragState] to be used for observing marker drag events
* @param onClick a lambda invoked when the marker is clicked
* @param onInfoWindowClick a lambda invoked when the marker's info window is clicked
* @param onInfoWindowClose a lambda invoked when the marker's info window is closed
* @param onInfoWindowLongClick a lambda invoked when the marker's info window is long clicked
* @param content optional composable lambda expression for customizing the
* info window's content
Expand All @@ -170,6 +224,7 @@ fun MarkerInfoWindow(
flat: Boolean = false,
icon: BitmapDescriptor? = null,
infoWindowAnchor: Offset = Offset(0.5f, 0.0f),
infoWindowState: MarkerInfoWindowState = rememberMarkerInfoWindowState(),
rotation: Float = 0.0f,
snippet: String? = null,
tag: Any? = null,
Expand All @@ -179,7 +234,6 @@ fun MarkerInfoWindow(
markerDragState: MarkerDragState? = null,
onClick: (Marker) -> Boolean = { false },
onInfoWindowClick: (Marker) -> Unit = {},
onInfoWindowClose: (Marker) -> Unit = {},
onInfoWindowLongClick: (Marker) -> Unit = {},
content: (@Composable (Marker) -> Unit)? = null
) {
Expand All @@ -200,9 +254,9 @@ fun MarkerInfoWindow(
markerDragState = markerDragState,
onClick = onClick,
onInfoWindowClick = onInfoWindowClick,
onInfoWindowClose = onInfoWindowClose,
onInfoWindowLongClick = onInfoWindowLongClick,
infoWindow = content,
infoWindowState = infoWindowState,
)
}

Expand All @@ -218,6 +272,8 @@ fun MarkerInfoWindow(
* @param flat sets if the marker should be flat against the map
* @param icon sets the icon for the marker
* @param infoWindowAnchor the anchor point of the info window on the marker image
* @param infoWindowState a [MarkerInfoWindowState] to be used for controlling and observing info
* window visibility
* @param rotation the rotation of the marker in degrees clockwise about the marker's anchor point
* @param snippet the snippet for the marker
* @param tag optional tag to associate with the marker
Expand All @@ -227,7 +283,6 @@ fun MarkerInfoWindow(
* @param markerDragState a [MarkerDragState] to be used for observing marker drag events
* @param onClick a lambda invoked when the marker is clicked
* @param onInfoWindowClick a lambda invoked when the marker's info window is clicked
* @param onInfoWindowClose a lambda invoked when the marker's info window is closed
* @param onInfoWindowLongClick a lambda invoked when the marker's info window is long clicked
* @param content optional composable lambda expression for customizing the
* info window's content
Expand All @@ -241,6 +296,7 @@ fun MarkerInfoWindowContent(
flat: Boolean = false,
icon: BitmapDescriptor? = null,
infoWindowAnchor: Offset = Offset(0.5f, 0.0f),
infoWindowState: MarkerInfoWindowState = rememberMarkerInfoWindowState(),
rotation: Float = 0.0f,
snippet: String? = null,
tag: Any? = null,
Expand All @@ -250,7 +306,6 @@ fun MarkerInfoWindowContent(
markerDragState: MarkerDragState? = null,
onClick: (Marker) -> Boolean = { false },
onInfoWindowClick: (Marker) -> Unit = {},
onInfoWindowClose: (Marker) -> Unit = {},
onInfoWindowLongClick: (Marker) -> Unit = {},
content: (@Composable (Marker) -> Unit)? = null
) {
Expand All @@ -271,9 +326,9 @@ fun MarkerInfoWindowContent(
markerDragState = markerDragState,
onClick = onClick,
onInfoWindowClick = onInfoWindowClick,
onInfoWindowClose = onInfoWindowClose,
onInfoWindowLongClick = onInfoWindowLongClick,
infoContent = content,
infoWindowState = infoWindowState,
)
}

Expand All @@ -287,6 +342,8 @@ fun MarkerInfoWindowContent(
* @param flat sets if the marker should be flat against the map
* @param icon sets the icon for the marker
* @param infoWindowAnchor the anchor point of the info window on the marker image
* @param infoWindowState a [MarkerInfoWindowState] to be used for controlling and observing info
* window visibility
* @param rotation the rotation of the marker in degrees clockwise about the marker's anchor point
* @param snippet the snippet for the marker
* @param tag optional tag to associate with the marker
Expand All @@ -296,7 +353,6 @@ fun MarkerInfoWindowContent(
* @param markerDragState a [MarkerDragState] to be used for observing marker drag events
* @param onClick a lambda invoked when the marker is clicked
* @param onInfoWindowClick a lambda invoked when the marker's info window is clicked
* @param onInfoWindowClose a lambda invoked when the marker's info window is closed
* @param onInfoWindowLongClick a lambda invoked when the marker's info window is long clicked
* @param infoWindow optional composable lambda expression for customizing
* the entire info window. If this value is non-null, the value in infoContent]
Expand All @@ -313,6 +369,7 @@ private fun MarkerImpl(
flat: Boolean = false,
icon: BitmapDescriptor? = null,
infoWindowAnchor: Offset = Offset(0.5f, 0.0f),
infoWindowState: MarkerInfoWindowState = rememberMarkerInfoWindowState(),
rotation: Float = 0.0f,
snippet: String? = null,
tag: Any? = null,
Expand All @@ -322,7 +379,6 @@ private fun MarkerImpl(
markerDragState: MarkerDragState? = null,
onClick: (Marker) -> Boolean = { false },
onInfoWindowClick: (Marker) -> Unit = {},
onInfoWindowClose: (Marker) -> Unit = {},
onInfoWindowLongClick: (Marker) -> Unit = {},
infoWindow: (@Composable (Marker) -> Unit)? = null,
infoContent: (@Composable (Marker) -> Unit)? = null,
Expand Down Expand Up @@ -352,20 +408,20 @@ private fun MarkerImpl(
markerDragState = markerDragState,
onMarkerClick = onClick,
onInfoWindowClick = onInfoWindowClick,
onInfoWindowClose = onInfoWindowClose,
onInfoWindowLongClick = onInfoWindowLongClick,
infoContent = infoContent,
infoWindow = infoWindow,
infoWindowState = infoWindowState,
)
},
update = {
update(markerDragState) { this.markerDragState = it }
update(onClick) { this.onMarkerClick = it }
update(onInfoWindowClick) { this.onInfoWindowClick = it }
update(onInfoWindowClose) { this.onInfoWindowClose = it }
update(onInfoWindowLongClick) { this.onInfoWindowLongClick = it }
update(infoContent) { this.infoContent = it }
update(infoWindow) { this.infoWindow = it }
update(infoWindowState) { this.infoWindowState = it }

set(alpha) { this.marker.alpha = it }
set(anchor) { this.marker.setAnchor(it.x, it.y) }
Expand Down