Skip to content

Tile overlay state is not provided with new TileOverlay on recomposition #754

@cdelabou

Description

@cdelabou

Environment details

  • Working with google maps tile overlays
  • OS: MacOS 15.5 (24F74)
  • Library version: 6.6.0

Steps to reproduce

  1. Setup a TileOverlay with a TileProvider and a rememberTileOverlayState()
  2. Recompose with a different TileProvider
  3. tileOverlayState.clearTileCache() do not do anything anymore (it's attached to a TileOverlay that was removed)

Code example

@Composable
fun Content() {
    GoogleMap(
        modifier = Modifier.fillMaxSize(),
    ) {
        UpdatedTileOverlay()
    }
}

@Composable
fun UpdatedTileOverlay() {
    var tileProviderIndex by remember { mutableIntStateOf(0) }
    var renderedIndex by remember { mutableIntStateOf(0) }
    val state = rememberTileOverlayState()

    val size = with(LocalDensity.current) { 256.dp.toPx() }.toInt()
    val tileProvider = remember(tileProviderIndex) {
        TileProvider { x, y, zoom ->
            Tile(size, size, renderTiles(renderedIndex, size))
        }
    }

    TileOverlay(tileProvider = tileProvider, state = state, fadeIn = false)

    LaunchedEffect(Unit) {
        repeat(5) {
            delay(1000)
            renderedIndex += 1
            state.clearTileCache()
        }

        // update the tile provider
        tileProviderIndex += 1

        while (true) {
            delay(1000)
            renderedIndex += 1
            state.clearTileCache()
        }
    }
}

fun renderTiles(index: Int, size: Int): ByteArray {
    val bitmap = createBitmap(size, size)

    val canvas = Canvas(bitmap)
    canvas.drawText(index.toString(), (size / 2).toFloat(), (size / 2).toFloat(), Paint().apply {
        color = Color.Black.toArgb()
        textSize = 100f
    })
    val outputStream = ByteArrayOutputStream()
    bitmap.compress(Bitmap.CompressFormat.WEBP_LOSSLESS, 0, outputStream)
    return outputStream.toByteArray()
}

Expected behavior

  • When recomposing a tile overlay, the tile overlay in the remember(ed)TileOverlayState should be updated.
  • With the above sample: the rendered number on the tiles should keep increasing forever (cache clearing would trigger re-rendering with the new number).

Actual behavior

  • When TileProvider is updated on recomposition (not the initial composition), a new tile overlay is created but not linked to the TileOverlayState (only done in onAttached on TileOverlayNode which is not called in that case)

Metadata

Metadata

Assignees

No one assigned

    Labels

    releasedtriage meI really want to be triaged.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions