Android Compose,focusRequester.requestFocus()导致Fatal Exception:在放置父项之前,应不使用BringIntoViewRequester

zzzyeukh  于 2023-06-20  发布在  Android
关注(0)|答案(1)|浏览(123)

我是Android Compose的新手,正在进行一个维护项目。
以下代码块是发生错误的地方:

@ExperimentalMaterialNavigationApi
@ExperimentalAnimationApi
@ExperimentalMaterialApi
@ExperimentalComposeUiApi
@Composable
fun BottomSheetContent() {
    BaseBottomSheetComposable(showBar = true) {
        Column {
            val otpCtaEnabled = remember { mViewModel.enabledOtpCtaState }
            Text(
                text = stringResource(id = R.string.text_login_otp_title)
                    .plus(" ")
                    .plus(mViewModel.getMobileNumber()),
                style = typography.body1.copy(fontSize = 14.sp, color = angrezi),
                modifier = Modifier.padding(top = 24.dp, start = 16.dp, end = 16.dp)
            )
            val focusRequester = remember { FocusRequester() }
            val editValue = remember { mViewModel.loginOtp }
            val keyboard = LocalSoftwareKeyboardController.current
            TextField(
                value = editValue.value,
                onValueChange = {
                    if (it.length <= OTP_LENGTH) {
                        editValue.value = it
                        mViewModel.onOtpTextChanged(it)
                    }
                    if (it.length == OTP_LENGTH) {
                        keyboard?.hide()
                    }
                },
                modifier = Modifier
                    .size(0.dp)
                    .focusRequester(focusRequester),
                keyboardOptions = KeyboardOptions.Default.copy(
                    keyboardType = KeyboardType.Number
                )
            )
            LaunchedEffect(true) {
                focusRequester.requestFocus()
            }
            Row(
                modifier = Modifier.padding(start = 12.dp, end = 12.dp, top = 8.dp),
                horizontalArrangement = Arrangement.Center
            ) {
                (0 until OTP_LENGTH).map { index ->
                    OtpCell(
                        modifier = Modifier
                            .width(56.dp)
                            .height(56.dp)
                            .padding(horizontal = 4.dp)
                            .clip(RoundedCornerShape(12.dp))
                            .background(MonetGray0)
                            .focusRequester(focusRequester)
                            .clickable {
                                focusRequester.requestFocus()
                                keyboard?.show()
                            },

                        value = editValue.value.getOrNull(index)?.toString() ?: "",
                        isCursorVisible = editValue.value.length == index
                    )
                }
            }
            ButtonPrimary(text = stringResource(id = R.string.text_otp_cta), state = otpCtaEnabled,
                onCtaClick = {
                    mViewModel.onOtpCtaClicked()
                })
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.Center
            ) {
                OtpRetryText()
                CircularProgressTimer(percentage = 100f, animDuration = COUNT_DOWN_TIME_IN_MILLIS)
            }
        }
    }
}

...

当我运行代码时

LaunchedEffect(true) {
                focusRequester.requestFocus()
}

抛出一个运行时异常,堆栈跟踪如下:

AndroidRuntime   E  FATAL EXCEPTION: main
Process: in.myapp.crew, PID: 32709
java.lang.IllegalStateException: Expected BringIntoViewRequester to not be used before parents are placed.
    at androidx.compose.foundation.gestures.ContentInViewModifier.calculateRectForParent(ContentInViewModifier.kt:117)
    at androidx.compose.foundation.relocation.BringIntoViewResponderNode$bringChildIntoView$parentRect$1.invoke(BringIntoViewResponder.kt:160)
    at androidx.compose.foundation.relocation.BringIntoViewResponderNode$bringChildIntoView$parentRect$1.invoke(BringIntoViewResponder.kt:160)
    at androidx.compose.foundation.relocation.BringIntoViewResponder_androidKt$defaultBringIntoViewParent$1.bringChildIntoView(BringIntoViewResponder.android.kt:31)
    at androidx.compose.foundation.relocation.BringIntoViewResponderNode$bringChildIntoView$2$2.invokeSuspend(BringIntoViewResponder.kt:179)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
    at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
    at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run(AndroidUiDispatcher.android.kt:57)
    at android.os.Handler.handleCallback(Handler.java:942)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7872)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
    Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [androidx.compose.ui.platform.MotionDurationScaleImpl@86a65ab, androidx.compose.runtime.BroadcastFrameClock@d899408, StandaloneCoroutine{Cancelling}@4dea7a1, AndroidUiDispatcher@1669dc6]
Process   I  Sending signal. PID: 32709 SIG: 9
---------------------------- PROCESS ENDED (32709) for package in.myapp.crew ----------------------------
---------------------------- PROCESS STARTED (1138) for package in.myapp.crew ----------------------------
---------------------------- PROCESS STARTED (1390) for package in.myapp.crew ----------------------------
---------------------------- PROCESS ENDED (1390) for package in.myapp.crew ----------------------------

我没有看到程序中配置了BringIntoViewRequester,并且异常没有指向任何特定的代码行或程序的任何部分。在这个堆栈跟踪中也没有指定的“caused by”部分。
该应用程序使用以下版本:

  • Gradle:gradle-7.5
  • Kotlin版本:1.8.21
  • Android Gradle插件:7.4.2
  • 编写版本:
  • androidx.constraintlayout:constraintlayout-compose:1.0.0-rc1
  • androidx.activity:activity-compose:1.3.1
  • androidx.compose.runtime:runtime:1.4.3
  • androidx.compose.ui:ui:1.4.3
  • androidx.compose.foundation:foundation:1.4.3
  • androidx.compose.foundation:foundation-layout:1.4.3
  • androidx.compose.material:material:1.4.3
  • androidx.compose.runtime:runtime-livedata:1.4.3
  • androidx.compose.ui:ui-tooling:1.4.3
  • androidx.compose.ui:ui-viewbinding:1.4.3

有谁知道“父母安置前不得使用”是什么意思?以前有没有人经历过。你知道focusRequester为什么要这么做吗?

6ojccjat

6ojccjat1#

移除

LaunchedEffect(true) {
  focusRequester.requestFocus()
}

并添加

modifier = Modifier
            ...
            .clickable {
              focusRequester.requestFocus()
              keyboard?.show()
            }
            .onGloballyPositioned { focusRequester.requestFocus() }

它应该工作!

相关问题