'Android Jetpack Compose AnimatedVisibility innerTextField of BasicTextField
I'm receiving the following errors when tapping to focus on my BasicTextField after an animation has run. Please help.
decorationBox = { innerTextField ->
Box(Modifier.weight(1f)) {
if (addressText.isEmpty()) {
Label3(dynamicId = structure?.placeholder)
}
AnimatedVisibility(
visible = focusAddress
) {
innerTextField()
}
}
},
E/InputConnectionWrapper: InputConnectionWrapper.waitForInputConnectionFutureInternal():1542 Failed to get the input connection call's result.
java.lang.IllegalStateException: LayoutCoordinate operations are only valid when isAttached is true
EDIT:
It can be reproduced if the text field gains, looses and gains focus again. Issue is that coreTextField() is not available. Here is a short example which produces the same error message:
@Composable
fun TextInput(
modifier: Modifier = Modifier,
value: String,
label: String,
onValueChanged: (text: String) -> Unit,
) {
var textFieldValueState by remember { mutableStateOf(TextFieldValue(text = value)) }
val textFieldValue = textFieldValueState.copy(text = value)
val interactionSource = remember { MutableInteractionSource() }
val isFocused = interactionSource.collectIsFocusedAsState().value
BasicTextField(
value = textFieldValue,
modifier = modifier
.defaultMinSize(
minWidth = TextFieldDefaults.MinWidth,
minHeight = TextFieldDefaults.MinHeight,
),
onValueChange = {
textFieldValueState = it
if (value != it.text) {
onValueChanged(it.text)
}
},
interactionSource = interactionSource,
decorationBox = @Composable { coreTextField ->
Surface(
shape = RoundedCornerShape(),
border = BorderStroke(
width = 2.dp,
color = Colors.Black,
)
) {
Column(
modifier = Modifier
.height(52.dp)
.padding(horizontal = 16.dp, vertical = 8.dp),
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.Center,
) {
Text(text = label)
if (isFocused) coreTextField()
}
}
},
)
}
Solution 1:[1]
The problem is that the BasicTextField composable contains the one defined in decorationBox so it cannot just be removed from composition with an AnimatedVisibility or a simple if (if (isFocused) coreTextField() in your example). We need something that works a bit like the old View.GONE - the composable should occupy zero space, but should still be there. And the equivalent is using a layout modifier and not placing the placeable.
I was animating those fields based on my labelProgress variable that goes from 1f to 0f, so I was changing the height of the placeable like this.
Box(modifier = Modifier
.alpha(labelProgress)
.layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
layout(placeable.width, (placeable.height * labelProgress).toInt()) {
placeable.placeRelative(0, 0, 0f)
}
}
) {
innerTextField()
}
A basic visible/hidden version would probably look something like this:
Box(modifier = Modifier
.layout { measurable, constraints ->
if(showInnerTextField){
layout(placeable.width, (placeable.height * labelProgress).toInt()) {
placeable.placeRelative(0, 0, 0f)
}
}
}
) {
innerTextField()
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
