Got a weird one with OutlinedTextField: I cant se...
# compose
m
Got a weird one with OutlinedTextField: I cant seem to change the keyboardType, the imeAction or get notified onImeActionPerformed. Also, to get code using onImeActionPerformed to compile I have to do this trick: This compiles:
Copy code
fun onImeActionPerformed(action: ImeAction, keyboard: SoftwareKeyboardController?): Unit {
    Log.v("conditions", "ime pressed $action $keyboard")
}
OutlinedTextField(
    value = searchState.value,
    onValueChange = { it: String ->
        Log.v("conditions", "search bar $it")
        searchState.value = it
    },
    activeColor = primaryColor,
    inactiveColor = primaryColor,
    label = { Text("Search") },
    onFocusChange = { it: Boolean ->
        Log.v("conditions", "focus changed $it")
    },
    imeAction = ImeAction.Search,
    keyboardType = KeyboardType.Ascii,
    onImeActionPerformed = { action, kb -> onImeActionPerformed(action, kb) },
    modifier = Modifier.fillMaxWidth()
)
This does not:
Copy code
fun onImeActionPerformed(action: ImeAction, keyboard: SoftwareKeyboardController?): Unit {
    Log.v("conditions", "ime pressed $action $keyboard")
}
OutlinedTextField(
    value = searchState.value,
    onValueChange = { it: String ->
        Log.v("conditions", "search bar $it")
        searchState.value = it
    },
    activeColor = primaryColor,
    inactiveColor = primaryColor,
    label = { Text("Search") },
    onFocusChange = { it: Boolean ->
        Log.v("conditions", "focus changed $it")
    },
    imeAction = ImeAction.Done,
    keyboardType = KeyboardType.Ascii,
    onImeActionPerformed = onImeActionPerformed,
    modifier = Modifier.fillMaxWidth()
)
Error:
Copy code
None of the following functions can be called with the arguments supplied:
public fun OutlinedTextField(value: TextFieldValue, onValueChange: (TextFieldValue) -> Unit, label: () -> Unit, modifier: Modifier = ..., textStyle: TextStyle = ..., placeholder: (() -> Unit)? = ..., leadingIcon: (() -> Unit)? = ..., trailingIcon: (() -> Unit)? = ..., isErrorValue: Boolean = ..., visualTransformation: VisualTransformation = ..., keyboardType: KeyboardType = ..., imeAction: ImeAction = ..., onImeActionPerformed: (ImeAction, SoftwareKeyboardController?) -> Unit = ..., onFocusChange: (Boolean) -> Unit = ..., onTextInputStarted: (SoftwareKeyboardController) -> Unit = ..., activeColor: Color = ..., inactiveColor: Color = ..., errorColor: Color = ...): Unit defined in androidx.ui.material
public fun OutlinedTextField(value: String, onValueChange: (String) -> Unit, label: () -> Unit, modifier: Modifier = ..., textStyle: TextStyle = ..., placeholder: (() -> Unit)? = ..., leadingIcon: (() -> Unit)? = ..., trailingIcon: (() -> Unit)? = ..., isErrorValue: Boolean = ..., visualTransformation: VisualTransformation = ..., keyboardType: KeyboardType = ..., imeAction: ImeAction = ..., onImeActionPerformed: (ImeAction, SoftwareKeyboardController?) -> Unit = ..., onFocusChange: (Boolean) -> Unit = ..., onTextInputStarted: (SoftwareKeyboardController) -> Unit = ..., activeColor: Color = ..., inactiveColor: Color = ..., errorColor: Color = ...): Unit defined in androidx.ui.material
v
compiler give to you all info
try use value = TextFieldValue("text") andetc on
check red types error in tolltip
m
Is there a working example somewhere?
This doesnt work:
Copy code
var searchState = TextFieldValue()
        Box(paddingTop = 0.dp, paddingBottom = 10.dp) {
            fun onImeActionPerformed(action: ImeAction, keyboard: SoftwareKeyboardController?): Unit {
                Log.v("conditions", "ime pressed $action $keyboard")
            }
            OutlinedTextField(
                value = TextFieldValue(),
                onValueChange = {
                    Log.v("conditions", "search bar $it")
                    searchState = TextFieldValue(text = searchState.text + it.text)
                },
                activeColor = primaryColor,
                inactiveColor = primaryColor,
                label = { Text("Search") },
                onFocusChange = { it: Boolean ->
                    Log.v("conditions", "focus changed $it")
                },
                imeAction = ImeAction.Done,
                keyboardType = KeyboardType.Ascii,
                onImeActionPerformed = { action, kb ->
                    Log.v("conditions", "test got executed")
                    onImeActionPerformed(action, kb)
                },
                modifier = Modifier.fillMaxWidth()
            )
        }
it compiles but I cant find any way to update the searchState
the .text inside is val not var and replacing it wont bind to other functions. Or do i need to wrap the textfieldvalue in a state { }
also none of this fixes the issue above with onImeActionPerformed or inability to change the keyboard type or Ime button
this works:
Copy code
onValueChange = {
    Log.v("conditions", "search bar $it")
    searchState.value = it
},
but as i said no ime or keyboard changes, does anyone know why?
z
Some types have composable factory functions with the same name that both create the instance and remember it for you. I believe
TextFieldValue()
is just a simple constructor call, so yes you'd need to wrap it with
state {}
or you'll be creating a new value on every composition and none of the changes you make to it will be observed or applied (although this might depend on the version of Compose?)
Your second example in your original post doesn't compile because you need to pass a reference to the function, ie
::onImeActionPerformed
👍 1
TextFieldValue
is just a simple Immutable value type, basically. It represents the entire state of the text + selection. The text field will use whatever value you pass in on every composition. So just like any other state that you want to change over time, you need to use
state{}
so that the value will be remembered between compositions. I think there's also an overload that only takes a String, which you can use if you don't need to control the selection/cursor state. In that case, you would need to use
state{}
for the string value.
🎉 1
m
Thanks for the help, I had no idea about :: function references as "closures" in kotlin thats cool and it works! 🙂 I guess the fact that the keyboard and ime buttons arent working is known? Would it be different if I used an AndroidView for my text input fields instead. I want to be able to have an ime "search" button and hide the keyboard on press.
z
Oops, just saw your message now. I think using an Android
EditText
should solve all those problems, yea.
123 Views