I am new to Android Compose and am working on a maintenance project.
The following block of code is where the error is occurring:
@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)
}
}
}
}
...
When I run the code, the portion
LaunchedEffect(true) {
focusRequester.requestFocus()
}
throws a runtime exception with the following stack trace:
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 ----------------------------
I don't see BringIntoViewRequester configured in the program, and the exception doesn't point to any specific line of code or section of the program. There's also no designated "caused by" section in this stack trace.
The app is using the following versions:
- Gradle:
gradle-7.5
- Kotlin version:
1.8.21
- Android Gradle plugin:
7.4.2
- Compose version:
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
Does anyone know what "to not be used before parents are placed" means? Has anyone experienced this before. Any idea why focusRequester does this?