-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add Clustering composable, maps-compose-utils library #258
Conversation
Open question: Do we still need |
Except if I've missed it, I don't see a way to customize the cluster icons. That's critical for branding and one of the pain points when using maps-compose with the former util library since you need to shape your marker and cluster icons with the View system and turn them into bitmaps (preventing us from using our Composables). |
Correct, that isn't accounted for in this PR. Will explore options. |
Adding "true" clustering support with compose-maps would be great. I don't mind the MapEffect to be honest since it works, but something more "native" is def fine with me. But to @StephenVinouze point of customizing the marker icons and cluster icons would be like a 100% need. Good work getting it this far @DSteve595 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered implementing Clustering
as a ComposeNode<ClusteringNode, MapApplier>
? The advantage of implementing it this way is that you can update underlying state in the same frame that recomposition happens. With LaunchedEffect
, properties won't be updated until the next frame which means you might lose the click events
maps-compose-utils/src/main/java/com/google/maps/android/compose/clustering/Clustering.kt
Show resolved
Hide resolved
@Composable | ||
public fun <T : ClusterItem> Clustering( | ||
items: Collection<T>, | ||
cameraPositionState: CameraPositionState, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion/idea: how about making this a part of the MapApplier
so that you can access it implicitly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was wondering if that'd be prudent. I think I'll go for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaning towards a CompositionLocal (not publicly providable), to avoid giving MapApplier even more responsibilities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, a public Composable property seems better, since then I can annotate it with @GoogleMapComposable
.
maps-compose/src/main/java/com/google/maps/android/compose/MapApplier.kt
Show resolved
Hide resolved
I wanted to directly reference Can you give an example of how a click event might be lost? I'm assuming you're referring to the LaunchedEffect that sets the click listeners. As I understand it, the user would have to click a marker within a single choreographer frame after an |
Ahh, that's right, this is a different module altogether. I was thinking an event can be lost in this scenario:
It's an unlikely edge case I thought worth calling out though it would definitely have to be validated if that's even possible. Using |
I updated the PR with new args to
This lets you render custom cluster icons using composables. |
@arriolac I've been trying to come up with a test case that repros missing click handler events, but I've been coming up dry. I might be missing a case you're envisioning. If you find the time, would you be able to come up with one? |
Agreed that it shouldn't be blocking as the underlying implementation can change. An alternative to using |
971a705
to
27024b4
Compare
Note: Exploring possibilities for removing the no-animation restriction, since that also would break async image loaders |
cae783a
to
af4085d
Compare
With some invalidation hacks, marker/cluster icons are now rendered continuously! This importantly fixes async image loaders (like Glide), and also allows for animations. |
Noting here some decisions we have made in this PR:
|
# [2.11.0](v2.10.0...v2.11.0) (2023-02-16) ### Features * Add Marker Clustering composable, maps-compose-utils library ([#258](#258)) ([7f00a72](7f00a72))
🎉 This PR is included in version 2.11.0 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
Great job @DSteve595 Can't wait to use this! |
This adds a Compose-friendly API for marker clustering. I'd appreciate heavy scrutiny on it, since it's got some hacks and ugly bits!
MapClusteringActivity
has been updated to show an example of how it can be used. Notably, the bug with Marker (and other) click handlers no longer working, as described in #140 (comment), is fixed! It's unfortunately done by working around some unwanted behavior of maps-utils, where it clobbers the click listeners thatMapApplier
previously set. To facilitate that, I made some changes to howMapApplier
dispatches input, namely a newInputHandler
composable that can be added to arbitrarily handle all unhandled input. This solves the problem for clustering since ClusterManager wants to receive input events directly, and the current implementation throws away the marker click events since we haven't added correspondingMarkerNode
s for them.To match the structure of maps-utils (which contains the non-Compose clustering utilities), this also adds a new artifact, maps-compose-utils, in which the Clustering composable lives.
To do before merging:
Clustering
instead ofMapEffect
MapEffect
Fixes #44