Jason Crosby
Jason Crosby

Reputation: 3583

Why am I getting an error using Jetpack Compose TextField?

EDIT
I am still trying to get this to work. I now have and I get an error on the Text for the label. I am inside a function marked with @Composable. And still have a similar issue with the TextField too.

@Composable invocations can only happen from the context of a @Composable function

TextField(
    value = "Text(text = \"\")",
    onValueChange = {  },
    label = { Text("Label") },// copied from android developer website
    Modifier
        .padding(0.dp)
        .padding(end = dimensionResource(id = R.dimen.child_edge_padding))
     )
}

END EDIT
I'm trying to make a login screen for and I'm using TextField to allow the user to enter an email and password. I cant see anything wrong with what I have but I'm getting an error

None of the following functions can be called with the arguments supplied.


Here is part of my code:
Row(Modifier.padding(dimensionResource(id = R.dimen.container_edge_padding))) {
    Text(
        text = "${stringResource(id = R.string.email)}} : ",
        Modifier
            .padding(0.dp) // equivalent to padding inside
            .padding(end = dimensionResource(id = R.dimen.child_edge_padding)) // second padding acts as to margin putting space on the inside of the item
        )
    TextField(
        value = "",
        placeholder = stringResource(id = R.string.login_email_hint),
        Modifier
            .padding(0.dp)
            .padding(end = dimensionResource(id = R.dimen.child_edge_padding))
    )
}

When I hover over it this is what I see.

enter image description here

Using the names of the parameters it shouldnt matter which parameters I use or what position they are relative to the declaration. If I change it like this, because the first 3 parameters are the value, placeholder, modifier it works. But both should work because that is how named parameters works. Providing a default value allows for this. The only way I can get this working is by using the parameters in the order they are declared. Which means if I want to use placeHolder I have to use the name of every parameter before it, in the order its declared, in order to use it. The only ones that must be declared correctly are value and onValueChange because those are the only 2 that dont have a default declared.

TextField(
    value = "",
    onValueChange = {},
    Modifier
        .padding(0.dp)
        .padding(end = dimensionResource(id = R.dimen.child_edge_padding))
)

Upvotes: 1

Views: 4247

Answers (4)

Jason Crosby
Jason Crosby

Reputation: 3583

I finally got it working by doing this like @Dharmender Manral said

TextField(
    value = "",
    onValueChange = {  },
    Modifier
        .padding(0.dp)
        .padding(start = dimensionResource(id = R.dimen.child_edge_padding)),
    enabled = true,
    readOnly = false,
    textStyle = LocalTextStyle.current,
    label = { Text("Label") },
    placeholder = { Text(text = stringResource(id = R.string.login_password_hint)) }
)

Then I was able to do this
TextField(
    value = "",
    onValueChange = {  },
    Modifier
        .padding(0.dp)
        .padding(start = dimensionResource(id = R.dimen.child_edge_padding)),
//  enabled = true,
//  readOnly = false,
//  textStyle = LocalTextStyle.current,
    label = { Text("Label") },
    placeholder = { Text(text = stringResource(id = R.string.login_password_hint)) }
)

The only problem is the `Modifier` has a default parameter so it is optional and should be able to be placed in any order. One I got this working I was able to switch `placeHolder` and `label` around so `placeHolder` was first and it still worked like it should. I have a feeling this was a bug somewhere because as soon as I moved `modifier` to a different position it broke again. But because `modifier` has a default parameter it is option and should be able to be moved to any spot like I was able to do with `placeholder` and `label`.

So the only difference between what worked and what didnt is as long as the first 3 parameters are in the proper spot and in the correct order the other parameters work as you would expect default parameters to work. Having them in any position. Not sure why it doesnt work with modifier.

Upvotes: 0

Richard Onslow Roper
Richard Onslow Roper

Reputation: 6863

There are two variants of the TextField as pointed out by the highlighter. You, since you are providing the first parameter value as a string, are using the second variant. The second variant calls for a (String) -> Unit which is the onValueChange parameter. You are saying it yourself that this must be provided, and you yourself are not providing it in your code (Snippet 1). That it why it didn't match up with the variant

Upvotes: 0

Dharmender Manral
Dharmender Manral

Reputation: 1520

Try with the following code, it will help you.

 TextField(
        value = "ab",
        onValueChange ={},
        modifier = Modifier
            .padding(0.dp)
            .padding(end = dimensionResource(id = R.dimen.child_edge_padding)),
        enabled = true,
        readOnly = false,
        textStyle = TextStyle.Default,
        placeholder = {stringResource(id = R.string.login_email_hint)},
        visualTransformation = VisualTransformation.None,
        keyboardOptions = KeyboardOptions.Default,
        keyboardActions = KeyboardActions(onDone = { }),
        maxLines = 1
    )

Upvotes: 1

Anatolii Chub
Anatolii Chub

Reputation: 1300

placeholder parameter have a little bit another type that you try to use:

 placeholder: @Composable (() -> Unit)? = null,

That the reason: it cannot use String instead of @Composable (() -> Unit)?

Upvotes: 1

Related Questions