https://kotlinlang.org logo
#compose
Title
# compose
a

amar_1995

12/31/2019, 10:03 AM
Is there any difference between
@Composable() () -> Unit
and
() -> Unit
function signature. I am using
AlertDialog
and in documenation (https://developer.android.com/reference/kotlin/androidx/ui/material/package-summary#alertdialog) the function signature is different then in code. In documentation it is:
Copy code
@Composable fun AlertDialog(
    onCloseRequest: () -> Unit, 
    title: () -> Unit = null, 
    text: () -> Unit, 
    confirmButton: () -> Unit, 
    dismissButton: () -> Unit = null, 
    buttonLayout: AlertDialogButtonLayout = AlertDialogButtonLayout.SideBySide): Unit
In dev3 code it is:
Copy code
@Composable
fun AlertDialog(
    onCloseRequest: () -> Unit,
    title: @Composable() (() -> Unit)? = null,
    text: @Composable() () -> Unit,
    confirmButton: @Composable() () -> Unit,
    dismissButton: @Composable() (() -> Unit)? = null,
    buttonLayout: AlertDialogButtonLayout = AlertDialogButtonLayout.SideBySide
) : Unit
I am using
AlertDialog
inside navigation drawer and getting exception
java.lang.IllegalStateException: Composition requires an active composition context
. My code:
Copy code
Clickable(onClick = {
                                    val isOpen = +state { true }
         
                                    if(isOpen.value) {
                                    AlertDialog(onCloseRequest = {isOpen.value = !isOpen.value}, text = {Text("Hello World!!!")}) {
                                        Button(
                                            text = "CLOSE",
                                            style = TextButtonStyle(),
                                            onClick = { isOpen.value = !isOpen.value }
                                        )
                                        }
                                    }
                                }) {.... }
This code is written inside the
ModelDrawerLayout
drawerContent function
c

curioustechizen

12/31/2019, 10:41 AM
I don't know about the specific difference between the docs and code; however ... Adding
@Composable
to a function effectively changes the signature of the function.
@Composable fun Foo()
is not compatible with
fun Foo()
and it is a compile error to pass one where another is expected. It is similar to how adding
suspend
modifier changes the signature of a function
👍 1
1
a

amar_1995

12/31/2019, 10:59 AM
@curioustechizen Yes
@Composable
function cannot be call inside of normal function else it will throw
Composition requires an active composition context
exception. But, I don't know why i am getting that error, when I am using AlertDialog inside ModelDrawerLayout. And why there is difference in function signature in code and docs.
m

msink

12/31/2019, 11:12 AM
I think because this bug was fixed after
dev3
release
m

Marc Knaup

12/31/2019, 12:23 PM
The Android documentation is quite broken here.
Copy code
dismissButton: () -> Unit = null
That isn’t even valid as the type isn’t nullable. And the Android documentation should indeed use
@Composable
here. The
dev3
code that you’ve pasted is correct.
@Composable () -> Unit
makes it clear that another child component is expected (composed) - i.e. it’s not a callback/handler.
a

amar_1995

12/31/2019, 12:28 PM
Okay, But I don't why I am getting exception while using
AlertDialog
inside
ModelDrawerLayout
Copy code
Clickable(onClick = {
	val isOpen = +state { true }
	// todo some alert box with field
	if(isOpen.value) {
	AlertDialog(onCloseRequest = {isOpen.value = !isOpen.value}, text = {Text("Hello World!!!")}) {
		Button(
			text = "CLOSE",
			style = TextButtonStyle(),
			onClick = { isOpen.value = !isOpen.value }
		)
		}
	}
}) {
	Container(width = 20.dp, height = 20.dp) {
		DrawImage(image = +imageResource(R.drawable.image_add))
	} 
}
m

Marc Knaup

12/31/2019, 12:32 PM
Because you’re creating the
AlertDialog
inside an
onClick
listener which is not allowed. You must create the
AlertDialog
in the same context where you create the
Clickable
and all other components, likely in
setContent {}
of your
Activity
or something similar.
I see how this is confusing, because some lambdas are composable while some aren’t, and it’s not immediately obvious in what kind of context you are.
a

amar_1995

12/31/2019, 12:36 PM
Yeah, I got it. But why onClick is not
composable
?
m

Marc Knaup

12/31/2019, 12:38 PM
Composable functions are all called at the same time to compose the complete UI.
onClick
is called much later when the UI was already composed (when the user clicked the button). So you change the state using
isOpen.value = true
which tells Android to compose the whole UI again and the cycle repeats (compose whole UI again - which happens after
onClick
is done already).
a

amar_1995

12/31/2019, 12:52 PM
Got it, Thanks