IllegalStateException:在 Jetpack Compose 测试期间未初始化 FocusRequester

Abh*_*bhi 6 android kotlin android-jetpack-compose android-jetpack-compose-testing

我有一个屏幕,带有TextFields. 我需要第一个TextField在屏幕显示时自动聚焦。

缩小的示例代码

@Composable
fun ScreenView(
    data: ScreenViewData,
) {
    val focusManager = LocalFocusManager.current
    val focusRequester = remember {
        FocusRequester()
    }

    LaunchedEffect(
        key1 = Unit,
    ) {
        focusRequester.requestFocus()
    }

    Scaffold() { innerPadding ->
        Column {
            OutlinedTextField(
                modifier = Modifier.focusRequester(focusRequester),
            )
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该代码可以正常运行,没有任何问题。

但是,在撰写 UI 测试时,我收到以下错误。

java.lang.IllegalStateException:
FocusRequester 未初始化。以下是一些可能的修复方法:

  1. 记住 FocusRequester: val focusRequester = Remember { FocusRequester() }
  2. 您是否忘记添加 Modifier.focusRequester() ?
  3. 您是否试图在构图​​过程中要求焦点?
    应针对某些事件发出焦点请求。例如 Modifier.clickable { focusRequester.requestFocus() }

测试代码

@ExperimentalAnimationApi
class ScreenViewTest {

    @get:Rule
    val composeTestRule = createComposeRule()

    @ExperimentalMaterialApi
    @Test
    fun ScreenViewElementsAreDisplayed() {
        composeTestRule.setContent {
            MyAppTheme {
                ScreenView(
                    data = ScreenViewData(),
                )
            }
        }

        // Test fails before reaching assert statements
    }
}
Run Code Online (Sandbox Code Playgroud)

Eth*_*han 0

我团队中的 SDET 遇到了同样的问题,我们最终通过在 UI 实用程序模块中创建一个函数来解决它。

这就是我们最初的想法

suspend fun CoroutineScope.requestFocus(requester: FocusRequester) {
    try {
        requester.requestFocus()
    } catch (e: Exception) {
        delay(100)
        requester.requestFocus()
    }
}
Run Code Online (Sandbox Code Playgroud)

但事实证明这也有效

fun CoroutineScope.requestFocus(requester: FocusRequester) {
    requester.requestFocus()
}
Run Code Online (Sandbox Code Playgroud)

我确实希望核心问题很快得到解决,但与此同时,也许这可以帮助一些人。