Hi there! I've encountered an unusual issue with `...
# compose-android
s
Hi there! I've encountered an unusual issue with
AndroidExternalSurface
on Android versions lower than API 31. When I add an
AndroidExternalSurface
with a fixed surface size to my layout and draw a small green rectangle on it, everything looks as expected on API 31 and above. I can see my regular composable content, its background, and the green rectangle. However, on APIs 30 and lower, the behavior is different. I only see my composable content that's on top of the
AndroidExternalSurface
and the colored rectangle I drew on the surface. The remaining layout background is not visible, and the rest of the screen area is filled with black. Is this the expected behavior for
AndroidExternalSurface
on older APIs? Changing the
Modifier.size
or the
surfaceSize
attribute doesn't seem to affect the appearance on API 30 and below. Any insights or suggestions would be greatly appreciated. Thanks in advance! 🙂
The code as simple as that:
Copy code
Box(
    modifier = Modifier
        .fillMaxSize()
        .background(Color.Cyan)
        .safeDrawingPadding()
) {
    val intSize = with(LocalDensity.current) { DpSize(100.dp, 100.dp).toSize().toIntSize() }
    AndroidExternalSurface(
        Modifier
            .requiredSize(100.dp)
            .offset(100.dp),
        surfaceSize = intSize,
        isOpaque = false
    ) {
        onSurface { surface, width, height ->
            surface.lockCanvas(Rect(0, 0, width, height)).apply {
                drawColor(Color.Green.toArgb())
                surface.unlockCanvasAndPost(this)
            }
        }
    }
    Text(
        text = "Hello Android!",
        color = Color.Red
    )
}
r
Did you check what size the AndroidExternalSurface actually ends up having?
s
let me check
r
The behavior with black everywhere is what I would expect if the AndroidExternalSurface covers the whole window
s
image.png,image.png
it seems fine
should I file a bug?
Exactly the same behavior can be observed on physical devices as well.
AndroidEmbeddedExternalSurface
seems to work as I expect, and I know it utilizes a
TextureView
under the hood. This should be fine for my use case.
Screen_recording_20240507_004104.mp4
TextureView
seems to be working fine. Thank you so much for your attention 🙂
I discovered a quick fix: wrapping the
SurfaceView
inside a
FrameLayout
makes it work properly.
r
Seems like a clipping issue. Try to enable clipping on the AndroidView, without a FrameLayout
s
You are right. Now it looks fine.
with clipped to bounds
r
I'll add that to the composable then
s
hold on 👀
I encountered a really strange bug when combining AndroidExternalSurface with Modifier.clipToBounds() and Modifier.align from BoxScope. Here's what I observed: AndroidExternalSurface has a slower initialization process, resulting in a black frame. But that's not the only issue. Once it's initialized, it starts randomly flashing black whenever recomposition occurs. It's quite an odd behavior! However, I discovered that as soon as I remove either clipToBounds or the alignment modifier, it starts behaving normally again. The initialization becomes fast, and the flashing stops altogether. I'm not entirely sure what's causing this peculiar behavior, but I wanted to share my findings with you. If you have any insights or have come across a similar issue, I'd be curious to hear your thoughts!
surface_flashing_0.mp4,image.png
And with removed
.clipToBounds
or
.align