How to pass conditional parameter in Jetpack Compose?

8.7k views Asked by At

I want to hide the navigationIcon but when I pass null or Unit the icon space remains visible, as can be seen in the image below.

Menu preview

@Composable
fun DefaultScaffold(
    title: String? = null,
    icon: ImageVector? = null,
    content: @Composable() () -> Unit
) {
    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    if (title != null) {
                        Text(text = "My Title")
                    }
                },
                navigationIcon = {
                    if (icon != null) {
                        IconButton(
                            onClick = {}
                        ) {
                            Icon(imageVector = Icons.Filled.Close, contentDescription = null)
                        }
                    } else Unit
                }
            )
        }
    ) {
        content()
    }
}
3

There are 3 answers

0
Dan Artillaga On

Remove the parentheses that surround your conditional statement, then return null instead of Unit when you don't want to show the icon space.

So, it will become

navigationIcon = if (icon != null) {
    {
        IconButton(
            onClick = {}
        ) {
            Icon(imageVector = Icons.Filled.Close, contentDescription = null)
        }
    }
} else null
2
Gabriele Mariotti On

You can use something like

navigationIcon = if (icon != null) {
    { /*... your code ..*/ }
} else null

but the constructor of TopAppBar with title and navigationIcon parameters preserves the slots for a title and the navigation icon. If you check the source code you can find:

if (navigationIcon == null) {
            Spacer(TitleInsetWithoutIcon)
        } else {

You should use the constructor with the content parameter, that has no restriction on content.
Then you can use something like:

    TopAppBar(
        content = {
            Row(Modifier.fillMaxHeight(), verticalAlignment = Alignment.CenterVertically){
                if (icon != null) {
                    IconButton(
                        onClick = {},
                    ) {
                        Icon(imageVector = icon, contentDescription = null)
                    }
                }
                if (title != null) {
                    ProvideTextStyle(value = MaterialTheme.typography.h6) {
                        CompositionLocalProvider(
                            LocalContentAlpha provides ContentAlpha.high,
                        ){
                            Text(text = title)
                        }
                    }
                }
            }
        }
    )

enter image description here enter image description here

0
Richard Onslow Roper On
@Composable
fun DefaultScaffold(
    title: String? = null,
    icon: ImageVector? = null,
    content: @Composable() () -> Unit
) {
    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    if (title != null) {
                        Text(text = "My Title")
                    }
                },
                navigationIcon = {
                    if (icon != null) {
                        IconButton(
                            onClick = {}
                        ) {
                            Icon(imageVector = Icons.Filled.Close, contentDescription = null)
                        }
                    } else Icon(modifier = Modifier.width(0), imageVector = Icons.Filled.Close, contentDescription = null) // Add a Modifier
                }
            )
        }
    ) {
        content()
    }
}