Search code examples
androidkotlinandroid-jetpack-composeandroid-jetpack

Compose's "AndroidView"'s factory method doesn't recall when "remember" value change


I've an AndroidView on my UI and I'm creating a custom view class using factory scope. And I've remember value above my android view which is changing by user actions.

    val isActive = remember { mutableStateOf(true) }

    AndroidView(
        modifier = Modifier
            .align(Alignment.CenterStart)
            .fillMaxWidth()
            .wrapContentHeight(),
        factory = {
            .....
            if (isActive) {
                ...... // DOESN'T RECALL
            }
            .......
            CustomViewClass().rootView
        })

    if (isActive) {
        //WORKS FINE WHEN VALUE CHANGE
    } else {
        //WORKS FINE WHEN VALUE CHANGE
    }

In factory scope, I'm trying to use isActive value for configuring the AndroidView but it doesn't trigger when isActive value changes.

Outside from factory scope, everything works fine.

Is there any way to notify the view or any workaround for this?

compose_version = '1.1.1'

Solution

  • As given in the Docs,
    Use update to handle state changes.

    update = { view ->
            // View's been inflated or state read in this block has been updated
            // Add logic here if necessary
    
            // As selectedItem is read here, AndroidView will recompose
            // whenever the state changes
            // Example of Compose -> View communication
            view.coordinator.selectedItem = selectedItem.value
    }
    

    Complete code

    // Adds view to Compose
    AndroidView(
        modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree
        factory = { context ->
            // Creates custom view
            CustomView(context).apply {
                // Sets up listeners for View -> Compose communication
                myView.setOnClickListener {
                    selectedItem.value = 1
                }
            }
        },
        update = { view ->
            // View's been inflated or state read in this block has been updated
            // Add logic here if necessary
    
            // As selectedItem is read here, AndroidView will recompose
            // whenever the state changes
            // Example of Compose -> View communication
            view.coordinator.selectedItem = selectedItem.value
        }
    )