---
title: "SurfaceScope"
description: "[SurfaceScope] is a scoped environment provided by [AndroidExternalSurface] and
[AndroidEmbeddedExternalSurface] to handle [Surface] lifecycle events."
type: "interface"
---

<div class='type'>Interface</div>


<a id='references'></a>

<div class='sourceset sourceset-android'>Android</div>



```kotlin
interface SurfaceScope
```


`SurfaceScope` is a scoped environment provided by `AndroidExternalSurface` and
`AndroidEmbeddedExternalSurface` to handle `Surface` lifecycle events.


## Functions

```kotlin
fun Surface.onChanged(onChanged: Surface.(width: Int, height: Int) -> Unit)
```


Invokes `onChanged` when the surface's geometry (width and height) changes. Always invoked on
the main thread.


```kotlin
fun Surface.onDestroyed(onDestroyed: Surface.() -> Unit)
```


Invokes `onDestroyed` when the surface is destroyed. All rendering into the surface should
stop immediately after `onDestroyed` is invoked. Always invoked on the main thread.



## Code Examples

### AndroidExternalSurfaceColors
```kotlin
@Composable
fun AndroidExternalSurfaceColors() {
    AndroidExternalSurface(modifier = Modifier.fillMaxWidth().height(400.dp)) {
        // Resources can be initialized/cached here
        // A surface is available, we can start rendering
        onSurface { surface, width, height ->
            var w = width
            var h = height
            // Initial draw to avoid a black frame
            surface.lockCanvas(Rect(0, 0, w, h)).apply {
                drawColor(Color.Blue.toArgb())
                surface.unlockCanvasAndPost(this)
            }
            // React to surface dimension changes
            surface.onChanged { newWidth, newHeight ->
                w = newWidth
                h = newHeight
            }
            // Cleanup if needed
            surface.onDestroyed {}
            // Render loop, automatically cancelled on surface destruction
            while (true) {
                withFrameNanos { time ->
                    surface.lockCanvas(Rect(0, 0, w, h)).apply {
                        val timeMs = time / 1_000_000L
                        val t = 0.5f + 0.5f * sin(timeMs / 1_000.0f)
                        drawColor(lerp(Color.Blue, Color.Green, t).toArgb())
                        surface.unlockCanvasAndPost(this)
                    }
                }
            }
        }
    }
}
```

