Funky issue I've got. I'm using `AndroidView` wit...
# compose-android
c
Funky issue I've got. I'm using
AndroidView
with a
SurfaceView
If I have an
if
statement to show/hide the AndroidView... it renders the first time, but if the if statement flips to false and true again, the AndroidView won't render. 🧵
Copy code
@Composable
fun MyAndroidView() {
  AndroidView(
      factory = { ctx ->
        SurfaceView(ctx).apply {
          Log.e("TEST", "apply")
          this.holder.addCallback(
              object : SurfaceHolder.Callback {
                override fun surfaceCreated(holder: SurfaceHolder) {
                  Log.e("TEST", "created")
                }

                override fun surfaceChanged(
                    holder: SurfaceHolder,
                    format: Int,
                    width: Int,
                    height: Int
                ) {
                  Log.e("TEST", "changed")
                }

                override fun surfaceDestroyed(holder: SurfaceHolder) {
                  Log.e("TEST", "destroyed")
                }
              })
        }
      })

}
The logs I get initially:
Copy code
apply
created
changed
changed
then when my if statement flips to false
Copy code
destroyed
then when it flips back to true
Copy code
apply
Why doesn't it get created?!?
At that point if I press a button (like press it down and don't release it) it will go ahead and do
Copy code
created
changed
changed
Something just feels wrong here
j
I think you want to move apply block after Surface View to AndroidView setup method. Factory only called once upon creation I think. Setup block called each recomposition.
See sample at https://developer.android.com/jetpack/compose/migrate/interoperability-apis/views-in-compose Argument called update what I referred to as setup.
For callback I also think potentially need rememberupdated and store outside AndroidView to remember it not recreated each time view recomposition or inflates.
c
Interesting point with remember of the callback. I guess I can try that.
j
Its a little complicated how compose evaluates lambda expressions if they refer to stateful compose states. You want updating lambda when that happens but keep lambda itself. Helped me a lot of times but also confusing me. Potentially solves part of your issue. As I dont know rest of code not sure.
c
Yeah. when im back at my desk i will give this a try
j
Also can be bugs under hood. Mixing AndeoidView interop not always play nice, like nested scrolling in Webview. Could be some ui frame updating in SurfaceView behaves different. But I am no expert :) I just avoid AndroidView in compose as much as possible.
c
Yep. I wish I could avoid it here.