Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

What is the syntax to make a callback function variable mutable in Jetpack Compose?

I’m trying to make the following variable, selectedView, mutable so that I can set the current Composable View dynamically.

var selectedView :@Composable () -> Unit =  { testView() }

I’m passing back the Composable function and the following code works, but I can’t figure out how to make the variable selectedView updateable. This would work if selectedView variable was mutable.

@Composable
fun testView1() {
    Text("It works! 111")
}

...
    
val navBarItems = listOf(
    NavBarItem("Invite", Icons.Outlined.Send) { testView1() },
    NavBarItem("Messages", Icons.Outlined.Menu) { testView2() },
    NavBarItem("Groups", Icons.Outlined.AccountCircle) { testView3() }
)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CurrentView() {
    
    var selectedView :@Composable () -> Unit =  { testView() }

    Scaffold(
        bottomBar = {
            CustomNavBar(navBarItems){
                selectedView  = it
            }
        }
    )
    {
        Box(modifier = Modifier
            .fillMaxSize()
            .padding(it), contentAlignment = Alignment.Center) {
            selectedView?.let { it1 -> it1() }
        }
    }
}

Any assistance would be greatly appreciated.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You can use Compose mutable state to hold it. Something like

import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
...
var selectedView by remember {
    mutableStateOf<@Composable () -> Unit>({ TestView() })
}

(Note – convention is that @Composable functions are named with UpperCamelCase)

I see what you’re trying to do here, but the problem is going to be dealing with configuration changes. Keeping track of that lambda inside CurrentView, it’ll get lost and reinitialized on configuration change, such as a screen rotation.

You’d be better served by keeping track of the current screen as a simple value (String, object, enum, etc) as a screen identifier inside a view model (with a saved state handler) or at least in a rememberSaveable.

You could then define either a when on the screen identifier to select which @Composable to call, or put your lambdas inside a map keyed by the screen identifier.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading