Reputation: 2255
The Code A is from the official sample project.
I think I use a function instead of the val background
, but the Code B is wrong.
How can I convert a val
to a fun
when I use Jetpack Compose
in Kotlin?
Code A
@Composable
fun NiaApp(
windowSizeClass: WindowSizeClass,
appState: NiaAppState = rememberNiaAppState(windowSizeClass)
) {
NiaTheme {
val background: @Composable (@Composable () -> Unit) -> Unit =
when (appState.currentDestination?.route) {
ForYouDestination.route -> { content -> NiaGradientBackground(content = content) }
else -> { content -> NiaBackground(content = content) }
}
background {
Scaffold(
...
) { padding ->
Row(
...
) {
...
}
}
}
}
Code B
@Composable
fun NiaApp(
windowSizeClass: WindowSizeClass,
appState: NiaAppState = rememberNiaAppState(windowSizeClass)
) {
NiaTheme {
@Composable
fun background(aa: @Composable () -> Unit){
when (appState.currentDestination?.route) {
ForYouDestination.route -> { content -> NiaGradientBackground(content = content) }
else -> { content -> NiaBackground(content = content) }
}
}
background {
Scaffold(
...
) { padding ->
Row(
...
) {
...
}
}
}
}
Added content:
To Arpit Shukla: Thanks!
The Code C is based Code A val background: @Composable (@Composable () -> Unit) -> Unit...
.
Your Code D is right, but why is Code C wrong ?
Code C
@Composable
fun Background(
appState: NiaAppState,
content: @Composable () -> Unit
) {
when (appState.currentDestination?.route) {
ForYouDestination.route -> { content -> NiaGradientBackground(content = content) }
else -> { content -> NiaBackground(content = content) }
}
}
Code D
@Composable
fun Background(
appState: NiaAppState,
content: @Composable () -> Unit
) {
when (appState.currentDestination?.route) {
ForYouDestination.route -> NiaGradientBackground(content = content)
else -> NiaBackground(content = content)
}
}
Added content again:
To Arpit Shukla: Thanks!
By your way, Code E and Code F can't be compiled.
Code E
@Composable
fun Background(
appState: NiaAppState,
content: @Composable () -> Unit
) {
when (appState.currentDestination?.route) {
ForYouDestination.route -> { content -> NiaGradientBackground(content = content) }
else -> { content -> NiaBackground(content = content) }
}(content) // Call the lambda
}
Code F
@Composable
fun Background(
appState: NiaAppState,
content: @Composable () -> Unit -> NiaGradientBackground(content = content)
) {
when (appState.currentDestination?.route) {
ForYouDestination.route -> { content -> NiaGradientBackground(content = content) }
else -> { content -> NiaBackground(content = content) }
}(content) // Call the lambda
}
New content:
To Arpit Shukla: Thanks!
By your way, Code G can't be compiled yet, I get the following error.
@Composable invocations can only happen from the context of a @Composable function
Code G
@Composable
fun Background(
appState: NiaAppState,
content: @Composable () -> Unit
) {
when (appState.currentDestination?.route) {
ForYouDestination.route -> { content1: @Composable () -> Unit -> NiaGradientBackground(content = content1) }
else -> { content1: @Composable () -> Unit -> NiaBackground(content = content1) }
}(content) // Call the lambda
}
Upvotes: 0
Views: 560
Reputation: 10493
You can try this:
@Composable
fun NiaApp(
windowSizeClass: WindowSizeClass,
appState: NiaAppState = rememberNiaAppState(windowSizeClass)
) {
NiaTheme {
Background(appState) {
Scaffold(
...
) { padding ->
Row(
...
) {
...
}
}
}
}
@Composable
fun Background(
appState: NiaAppState,
content: @Composable () -> Unit
) {
when (appState.currentDestination?.route) {
ForYouDestination.route -> NiaGradientBackground(content = content)
else -> NiaBackground(content = content)
}
}
Edit: Your when
statement in Code C only creates a lambda function which when invoked will call the composables. You need to call that lambda too to see any effect:
@Composable
fun Background(
appState: NiaAppState,
content: @Composable () -> Unit
) {
when (appState.currentDestination?.route) {
ForYouDestination.route -> { content -> NiaGradientBackground(content = content) }
else -> { content -> NiaBackground(content = content) }
}(content) // Call the lambda
}
Note: I haven't run this code but the compiler may give you an error here saying that it is unable to infer type for the content
variable in the lambda. In that case you will have to explicitly provide the type: content: @Composable () -> Unit -> NiaGradientBackground(content = content)
Anyway, this is too much of unnecessary effort here and is only making the code more complex than the original one. Code D is much straightforward.
Edit: In code G, the lambda is by default not a composable function, you can't call composables inside it. Just putting @Composable
in front of the lambda doesn't work, you need to explicitly provide the type for the entire when
expression.
@Composable
fun Background(
appState: NiaAppState,
content: @Composable () -> Unit
) {
val background: @Composable (@Composable () -> Unit) -> Unit =
when (appState.currentDestination?.route) {
ForYouDestination.route -> { content -> NiaGradientBackground(content = content) }
else -> { content -> NiaBackground(content = content) }
}
background(content)
}
We reached to the same code we started with which you wanted to simplify. Code D is the best solution in my opinion.
Upvotes: 4
Reputation: 335
Well, something like this:
@Composable
fun NiaApp(
windowSizeClass: WindowSizeClass,
appState: NiaAppState = rememberNiaAppState(windowSizeClass) ) {
NiaTheme {
background(appState)() {
Scaffold(
...
) { padding ->
}
}
}
}
@Composable
fun background(appState: NiaAppState): @Composable (@Composable () -> Unit) -> Unit =
when (appState.currentDestination?.route) {
ForYouDestination.route -> { content ->
NiaGradientBackground(content = content) }
else -> { content -> NiaBackground(content = content) }
}
Upvotes: 1
Reputation: 1415
just cut your Background
composable function and paste it outside of the NiaApp
composable function
@Composable
fun NiaApp(
windowSizeClass: WindowSizeClass,
appState: NiaAppState = rememberNiaAppState(windowSizeClass)
) {
NiaTheme {
background {
Scaffold(
...
) { padding ->
Row(
...
) {
...
}
}
}
}
@Composable
fun background(aa: @Composable () -> Unit){
when (appState.currentDestination?.route) {
ForYouDestination.route -> { content ->
NiaGradientBackground(content = content) }
else -> { content -> NiaBackground(content = content) }
}
}
Upvotes: 0