Hey! I am trying to update an `AndroidView` based ...
# compose
p
Hey! I am trying to update an
AndroidView
based on my
CustomViewModel
changes.
Copy code
@Composable
fun FilamentViewer(viewModel: CustomViewModel) {
    var modelViewer by remember { mutableStateOf<ModelViewer?>(null) }

    launchInComposition {
        while (true) {
            withFrameNanos { frameTimeNanos ->
                modelViewer?.render(frameTimeNanos)
            }
        }
    }

    AndroidView({ context ->
        LayoutInflater.from(context).inflate(
            R.layout.filament_host, FrameLayout(context), false
        ).apply {
            val (engine) = scenes[product.material]!!
            modelViewer = ModelViewer(engine, this as SurfaceView).also {
                setupModelViewer(it)
            }
        }
    })
}
how can I make it change dynamically? I need to update the modelViewer.scene entity
z
Which version of compose are you using? I thought
launchInComposition
was from over a year ago
AndroidView
takes two function parameters: the first one creates the view, and is only called the first time the call is composed, the second one updates the view and is called on every composition (including the first one).
p
I was using a Filament project as reference
If I remove
Copy code
launchInComposition {
        while (true) {
            withFrameNanos { frameTimeNanos ->
                modelViewer?.render(frameTimeNanos)
            }
        }
    }
it won't render
z
I don’t know what compose version filament uses, but I would recommend upgrading to at least 1.0.2 before trying to go any further.
launchInComposition
is now called
LaunchedEffect
.
p
Updating it
а
Btw, should we wrap creation of our AndroidViews into compose
state { TextView(...) }
? I've seen some example on codelab where it's used.
p
Already upgraded every library and using
LaunchedEffect
. Result is the same. If I delete line
Copy code
modelViewer?.render(frameTimeNanos)
It won't render nothing
z
That makes sense, if your view model requires that method to be called – i never said anything about removing that line. I don't know how Filament expects to get updates, but the general pattern for using
AndroidView
looks something like this:
Copy code
AndroidView(
  // This function is only called once.
  factory = { context ->
    LayoutInflater.from(context)
      .inflate(…)
      .apply {
        // Initialize view.
      }
  },
  // This function is called on every composition.
  update = { view ->
    // Set view properties that can change based on the
    // current composition (e.g. read State values,
    // parameters to your composable, etc.)
  }
)
p
Will update block be executed when my viewModel is updated?
z
If you read the viewModel state in the update function, then yes. See these docs for more info: https://developer.android.com/jetpack/compose/interop/interop-apis
300 Views