-
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
fix: Fixed scope cancellation that leads to bug when invalidating composable doesn't invalidate cluster #538
Conversation
… when invalidating composable doesn't invalidate marker/cluster
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Signed CLA |
Is there any movement on this PR? We'd quite like to get this fix in to help images load in more reliably. |
By the way, my case was also image loading :) |
@pioPirrung , this does not seem to fix the Coil related stuff. The image is still not being rendered. |
hey @kikoso, thanks for your quick reply and checking onto this issue. I tested it again locally and for me everything runs fine. The I'm using a |
@pioPirrung, this does not seem to fix the Async loading of a Coil image, see the following code snippet:
Under which circumstances is it fixing it for you? Can you provide an snippet, ideally? |
Thanks for your reply @kikoso. I did not tried it with plain Code Snippet@OptIn(MapsComposeExperimentalApi::class)
@Composable
fun TestMapScreen() {
val cameraPositionState = rememberCameraPositionState {
position = CameraPosition.fromLatLngZoom(LatLng(49.897288, 10.8783964), 7f)
}
Box(
modifier = Modifier.fillMaxSize()
) {
GoogleMap(
modifier = Modifier
.fillMaxSize(),
onMapLoaded = { },
cameraPositionState = cameraPositionState,
uiSettings = MapUiSettings(
myLocationButtonEnabled = false,
mapToolbarEnabled = false,
zoomControlsEnabled = false
)
) {
val configuration = LocalConfiguration.current
val screenHeight = configuration.screenHeightDp.dp
val screenWidth = configuration.screenWidthDp.dp
val clusterManager = rememberClusterManager<MyItem>()
clusterManager?.setAlgorithm(
NonHierarchicalViewBasedAlgorithm(
screenWidth.value.toInt(),
screenHeight.value.toInt()
)
)
val renderer = rememberClusterRenderer(
clusterContent = { cluster ->
MyItemClusterContent(
modifier = Modifier
.size(30.dp, 38.dp)
.clip(MarkerShape())
.background(
Color(
red = 255,
green = 165,
blue = 0
)
),
cluster = cluster
)
},
clusterItemContent = { item ->
MyItemMarker(item)
},
clusterManager = clusterManager,
)
SideEffect {
clusterManager ?: return@SideEffect
clusterManager.setOnClusterItemClickListener {
true
}
}
SideEffect {
if (clusterManager?.renderer != renderer && renderer != null) {
(renderer as DefaultClusterRenderer).minClusterSize = 2
clusterManager?.renderer = renderer
}
}
if (clusterManager != null) {
Clustering(
items = previewData,
clusterManager = clusterManager,
)
}
}
}
}
@Composable
fun MyItemMarker(item: MyItem) {
val context = LocalContext.current
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(
modifier = Modifier
.size(30.dp, 38.dp)
.clip(MarkerShape())
.background(Color.Green),
) {
AsyncImage(
modifier = Modifier
.size(30.dp)
.padding(5.dp),
model = ImageRequest.Builder(context)
.data(item.itemUrl)
.allowHardware(false)
.crossfade(false)
.error(R.drawable.placeholder)
.diskCacheKey(item.id)
.memoryCacheKey(item.id)
.fallback(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.build(),
contentDescription = null
)
}
Column(
modifier = Modifier.width(150.dp),
) {
Text(
modifier = Modifier.fillMaxWidth(),
text = item.itemTitle,
style = MaterialTheme.typography.labelSmall,
textAlign = TextAlign.Center
)
}
}
}
@Composable
fun MyItemClusterContent(
modifier: Modifier = Modifier,
cluster: Cluster<MyItem>
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(
modifier = modifier
) {
Text(
modifier = Modifier
.padding(5.dp)
.fillMaxWidth(),
text = "%,d".format(cluster.size),
fontSize = 16.sp,
fontWeight = FontWeight.Black,
textAlign = TextAlign.Center
)
}
Column(
modifier = Modifier.width(130.dp),
) {
Text(
modifier = Modifier.fillMaxWidth(),
text = cluster.items.stream().findFirst().get().title,
style = MaterialTheme.typography.bodyMedium,
textAlign = TextAlign.Center
)
Text(
modifier = Modifier.fillMaxWidth(),
text = "+${cluster.size - 1} more",
style = MaterialTheme.typography.labelSmall,
textAlign = TextAlign.Center
)
}
}
}
data class MyItem(
val id: String = UUID.randomUUID().toString(),
val itemPosition: LatLng,
val itemTitle: String,
val itemUrl: String = "https://picsum.photos/200/300",
) : ClusterItem {
override fun getPosition(): LatLng =
itemPosition
override fun getTitle(): String =
itemTitle
override fun getSnippet(): String? = null
override fun getZIndex(): Float? = null
}
val markerMain = LatLng(49.89, 10.87)
val previewData = listOf(
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
MyItem(
itemPosition = LatLng(
markerMain.latitude + Random.nextFloat(),
markerMain.longitude + Random.nextFloat(),
),
itemTitle = "Hello"
),
) And here is also a video of proof. Screen_recording_20240417_182257.mp4 |
Hi @pioPirrung . I was a bit confused after reading this comment, since they are specifically targeting The fix does indeed seem to prevent the Coil Coroutine from being canceled and let the image load from either network or cache (you can activate the debugger on Coil and search for Verifying that this does not have any non-intended behaviors. |
Hi @kikoso, thanks again for your really quick reply. Ah now I see, sorry for the confusion. Initially I thought that this PR would fix it for |
Confirming this fix worked for me when trying to load an |
🎉 This PR is included in version 4.4.1 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
This issue is still unfixed when using only MarkerComposable |
Thank you for opening a Pull Request!
Before submitting your PR, there are a few things you can do to make sure it goes smoothly:
Fixes #537 🦕