在Jetpack Compose中使用BasicTextField时出现了IllegalStateException异常。

huangapple go评论62阅读模式
英文:

Getting an IllegalStateException exception with BasicTextField in Jetpack Compose

问题

我有一个带有提示的 BasicTextField。然而,出于某种原因,当我输入一些文本,然后删除一切并尝试重新输入时,应用程序崩溃了。不知道如何修复它,任何帮助都将不胜感激 在Jetpack Compose中使用BasicTextField时出现了IllegalStateException异常。

我使用的是 2023.04.01 的 compose BOM,因此我相信问题不在版本中。

我的 Composable:

@Composable
fun EditableText(
    text: String,
    hint: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier
) {

    BasicTextField(
        modifier = modifier,
        value = text,
        onValueChange = onValueChange,
        textStyle = headline.copy(color = Color.White, textAlign = TextAlign.Start),
        singleLine = true,
        decorationBox = { innerTextField ->
            if (text.isEmpty()) {
                Text(
                    textAlign = TextAlign.Start,
                    text = hint,
                    style = headline.copy(
                        color = Color.White.copy(alpha = 0.75f),
                        textAlign = TextAlign.Start
                    )
                )
            } else {
                innerTextField()
            }
        }
    )
}

错误信息:

FATAL EXCEPTION: main
Process: com.pm.savings, PID: 7045
java.lang.IllegalStateException: LayoutCoordinate operations are only valid when isAttached is true
    at androidx.compose.ui.node.NodeCoordinator.localToRoot-MK-Hz9U(NodeCoordinator.kt:881)
    at androidx.compose.foundation.text.TextFieldDelegate$Companion.notifyFocusedRect$foundation_release(TextFieldDelegate.kt:173)
    at androidx.compose.foundation.text.CoreTextFieldKt.notifyFocusedRect(CoreTextField.kt:1077)
    at androidx.compose.foundation.text.CoreTextFieldKt.access$notifyFocusedRect(CoreTextField.kt:1)
    at androidx.compose.foundation.text.CoreTextFieldKt$CoreTextField$5$1$1$2.measure-3p2s80s(CoreTextField.kt:610)
    at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:103)
    at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1090)
    at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1086)
    at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2200)
    at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:234)
    at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:230)
    at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
    at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
    at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
    at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120)
英文:

I have a BasicTextField with a hint. However, for some reason when I put some text in, then delete everything and try to input again, the app crashes. Have no idea how to fix it, any help would be much appreciated 在Jetpack Compose中使用BasicTextField时出现了IllegalStateException异常。

I use compose BOM of 2023.04.01, so I believe the issue is not in the version.

My Composable:

@Composable
fun EditableText(
    text: String,
    hint: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier
) {

    BasicTextField(
        modifier = modifier,
        value = text,
        onValueChange = onValueChange,
        textStyle = headline.copy(color = Color.White, textAlign = TextAlign.Start),
        singleLine = true,
        decorationBox = { innerTextField ->
            if (text.isEmpty()) {
                Text(
                    textAlign = TextAlign.Start,
                    text = hint,
                    style = headline.copy(
                        color = Color.White.copy(alpha = 0.75f),
                        textAlign = TextAlign.Start
                    )
                )
            } else {
                innerTextField()
            }
        }
    )
}

The error:

FATAL EXCEPTION: main
                                                                                                   Process: com.pm.savings, PID: 7045
                                                                                                    java.lang.IllegalStateException: LayoutCoordinate operations are only valid when isAttached is true
                                                                                                    	at androidx.compose.ui.node.NodeCoordinator.localToRoot-MK-Hz9U(NodeCoordinator.kt:881)
                                                                                                    	at androidx.compose.foundation.text.TextFieldDelegate$Companion.notifyFocusedRect$foundation_release(TextFieldDelegate.kt:173)
                                                                                                    	at androidx.compose.foundation.text.CoreTextFieldKt.notifyFocusedRect(CoreTextField.kt:1077)
                                                                                                    	at androidx.compose.foundation.text.CoreTextFieldKt.access$notifyFocusedRect(CoreTextField.kt:1)
                                                                                                    	at androidx.compose.foundation.text.CoreTextFieldKt$CoreTextField$5$1$1$2.measure-3p2s80s(CoreTextField.kt:610)
                                                                                                    	at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:103)
                                                                                                    	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1090)
                                                                                                    	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1086)
                                                                                                    	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2200)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:234)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:230)
                                                                                                    	at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
                                                                                                    	at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
                                                                                                    	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
                                                                                                    	at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120)

答案1

得分: 0

你应该在text为空时返回innerTextField,因为它用于设置焦点,只需移除else条件,它就能同时适用于两种情况。

decorationBox = { innerTextField ->
    if (text.isEmpty()) {
        Text(
            textAlign = TextAlign.Start,
            text = hint,
            style = headline.copy(
                color = Color.White.copy(alpha = 0.75f),
                textAlign = TextAlign.Start
            )
        )
    } 
    innerTextField()
}
英文:

You should return innerTextField even when the text is empty which uses it to set focus, just remove else condition and it should work for both cases

decorationBox = { innerTextField ->
            if (text.isEmpty()) {
                Text(
                    textAlign = TextAlign.Start,
                    text = hint,
                    style = headline.copy(
                        color = Color.White.copy(alpha = 0.75f),
                        textAlign = TextAlign.Start
                    )
                )
            } 
            innerTextField()
        }

huangapple
  • 本文由 发表于 2023年5月28日 23:54:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76352337.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定