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 best solutions below

0
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
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
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()
    }
}