Skip to content
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(cluster): Support updating existing items #627

Merged
merged 6 commits into from
Feb 20, 2020
Merged

feat(cluster): Support updating existing items #627

merged 6 commits into from
Feb 20, 2020

Conversation

barbeau
Copy link
Collaborator

@barbeau barbeau commented Feb 19, 2020

As discussed in #90, when an item instance is removed, updated, and re-added the ClusterManager, the updated item state wouldn't be reflected on the map.

The reason for this is that DefaultClusterRenderer.CreateMarkerTask.perform() was using a marker from its own mMarkerCache associated with that item to display that item on the map (even if ClusterManager.clearItems() was previously called). This resulted in the updated item contents not being reflected on the map, because the cached marker was not updated.

This PR does the following:

  • Add new protected methods in DefaultClusterRenderer - onClusterItemUpdated() and onClusterUpdated() - which are called when an existing cached marker is found for an item/cluster when that item/cluster is being added back into the ClusterManager. The default implementation of these methods update the marker contents on the map, but then can also be overridden by applications for custom behavior (similar to onBeforeClusterItemRendered() and onBeforeClusterRendered()). Following this change, you can now do ClusterManager.clearItems() and re-add the same list instance (or remove() and then add() the same item) and then call cluster() and the map markers will be updated with the new item model contents.
  • Add a new ClusterManager.updateItem() helper method for updating the ClusterManager and algorithms with an existing item. The current implementation in NonHierarchicalDistanceBasedAlgorithm is a wrapper for remove() and then add().
  • Add more descriptive Javadocs to ClusterManager, DefaultClusterRenderer, and NonHierarchicalDistanceBasedAlgorithm to describe expected behavior, especially that cluster() should be invoked after any changes to ClusterManager to see changes on the map.

One new TODO I added that could potentially be addressed - it seems like the code to set the marker text when creating the item marker should be refactored into onBeforeClusterItemRendered() to match the implementation of clusters (onBeforeClusterRendered()), and to allow applications extending DefaultClusterRenderer to inherit this default behavior via a call to super.onBeforeClusterItemRendered(). However, moving this code would change the behavior of the library for apps already extending DefaultClusterRenderer that aren't calling super.onBeforeClusterItemRendered() - the marker title and snippet would no longer be updated. Thoughts on this are welcome!

Fixes #90

Prior to these changes, when an item instance was removed, updated, and re-added to the ClusterManager, DefaultClusterRenderer.CreateMarkerTask.perform() would use a marker from its own mMarkerCache associated with that item to display that item on the map (even if ClusterManager.clearItems() was previously called). This resulted in the updated item contents not being reflected on the map, because the cached marker was not updated.

This changeset does the following:
* Add new protected methods in DefaultClusterRenderer - onClusterItemUpdated() and onClusterUpdated() - which are called when an existing cached marker is found for an item/cluster when that item/cluster is being added back into the ClusterManager. The default implementation of these methods update the marker contents on the map, but then can also be overridden by applications for custom behavior (similar to onBeforeClusterItemRendered() and onBeforeClusterRendered()).  Following this change, you can now do ClusterManager.clearItems() and re-add the same list instance (or remove() and then add() the same item) and then call cluster() and the map markers will be updated with the new item model contents.
* Add a new ClusterManager.updateItem() helper method for updating the ClusterManager and algorithms with an existing item. The current implementation in NonHierarchicalDistanceBasedAlgorithm is a wrapper for remove() and then add().
* Add more descriptive Javadocs to ClusterManager, DefaultClusterRenderer, and NonHierarchicalDistanceBasedAlgorithm to describe expected behavior, especially that cluster() should be invoked after any changes to ClusterManager to see changes on the map.

One new TODO that could potentially be addressed - it seems like the code to set the marker text when creating the item marker should be refactored into onBeforeClusterItemRendered() to match the implementation of clusters (onBeforeClusterRendered()), and to allow applications extending DefaultClusterRenderer to inherit this default behavior via a call to super.onBeforeClusterItemRendered(). However, moving this code would change the behavior of the library for apps already extending DefaultClusterRenderer that aren't calling super.onBeforeClusterItemRendered() - the marker title and snippet would no longer be updated.
@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Feb 19, 2020
Copy link
Member

@arriolac arriolac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment on the implementation of update and returning a bool.

@codecov
Copy link

codecov bot commented Feb 20, 2020

Codecov Report

Merging #627 into master will increase coverage by 0.55%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #627      +/-   ##
==========================================
+ Coverage   18.44%   19.00%   +0.55%     
==========================================
  Files          71       71              
  Lines        4011     4056      +45     
  Branches      591      610      +19     
==========================================
+ Hits          740      771      +31     
- Misses       3237     3251      +14     
  Partials       34       34              
Impacted Files Coverage Δ
...ng/algo/NonHierarchicalDistanceBasedAlgorithm.java 58.18% <0.00%> (+23.80%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1f8fb34...acfdec0. Read the comment docs.

* Implementation follows the Java Collection definitions of the matching methods
* Synchronize within update() implementations to ensure they are atomic operations
* Add unit tests for all Algorithm operations
@barbeau
Copy link
Collaborator Author

barbeau commented Feb 20, 2020

Merging master branch to see if that enables CodeCov on this PR...

Copy link
Member

@arriolac arriolac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Before we merge, please follow-up on our discussion https://github.com/googlemaps/android-maps-utils/pull/627/files#r382051446 If we refactor, let's file an issue and tackle in a separate PR, otherwise, we can remove the TODO

"finally" clause will always be invoked (even after return), so we can just return the result of mAlgorithm method directly
See discussion at https://github.com/googlemaps/android-maps-utils/pull/627/files#r382258252. We'll open a new issue to discuss this specifically.
@barbeau barbeau merged commit 39f0c22 into googlemaps:master Feb 20, 2020
@barbeau barbeau deleted the update-model-cluster branch February 20, 2020 21:54
@arriolac arriolac added this to the 1.0 milestone Feb 24, 2020
barbeau added a commit that referenced this pull request Apr 2, 2020
See #655 (comment) - we need to update the custom clustering demo for the best practices surrounding marker caching, following the implementation of #627 in v1.

This means overriding onClusterUpdated() and onClusterItemUpdated() with the same implementations as onBeforeClusterRendered() and onBeforeClusterItemRendered(), respectively.
barbeau added a commit that referenced this pull request Apr 8, 2020
See #655 (comment) - we need to update the custom clustering demo for the best practices surrounding marker caching, following the implementation of #627 in v1.

This means overriding onClusterUpdated() and onClusterItemUpdated() with the same implementations as onBeforeClusterRendered() and onBeforeClusterItemRendered(), respectively.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update model and marker in cluster
3 participants