Ошибка компоновки Jetpack - Вы пытаетесь запросить фокус во время компоновки? Запросы на фокус следует делать в ответ на какое-то событие.

У меня есть экран с 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),
            )
        }
    }
}

Код работает без проблем.

Но при тестировании 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
    }
}

2 ответа

SDET в моей команде столкнулись с той же проблемой, и в итоге мы решили ее, создав функцию в нашем модуле утилит пользовательского интерфейса.

это то, что мы изначально имели в виду

      suspend fun CoroutineScope.requestFocus(requester: FocusRequester) {
    try {
        requester.requestFocus()
    } catch (e: Exception) {
        delay(100)
        requester.requestFocus()
    }
}

но оказалось, что это тоже сработало

      fun CoroutineScope.requestFocus(requester: FocusRequester) {
    requester.requestFocus()
}

Я надеюсь, что основная проблема скоро будет решена, а пока, может быть, это может помочь некоторым людям.

Вы пробовали это?:

val focusRequester = запомнить (данные) {...}

Другие вопросы по тегам