Реагировать на фокусировку

Предоставляйте визуальные подсказки для облегчения визуализации фокуса.

Хотя все фокусируемые элементы из Material Theme уже имеют стиль фокуса, соответствующий теме, вам может потребоваться добавить некоторые визуальные элементы, чтобы элемент, находящийся в фокусе, было легче обнаружить. Хорошим решением было бы изменить границу вашего элемента на цвет, который хорошо контрастирует с фоном:

var color by remember { mutableStateOf(Color.White) }
Card(
    modifier = Modifier
        .onFocusChanged {
            color = if (it.isFocused) Red else White
        }
        .border(5.dp, color)
) {}

В этом примере remember используется для хранения цвета границы при рекомпозиции, а контур элемента обновляется каждый раз, когда элемент получает или теряет фокус.

Внедряйте расширенные визуальные подсказки

С помощью Jetpack Compose вы также можете создавать более сложные и продвинутые визуальные подсказки, которые лучше соответствуют вашему пользовательскому интерфейсу.

  1. Сначала создайте IndicationInstance , который визуально рисует нужный вам сигнал в вашем пользовательском интерфейсе:
    private class MyHighlightIndicationInstance(isEnabledState: State<Boolean>) :
        IndicationInstance {
        private val isEnabled by isEnabledState
        override fun ContentDrawScope.drawIndication() {
            drawContent()
            if (isEnabled) {
                drawRect(size = size, color = Color.White, alpha = 0.2f)
            }
        }
    }
  2. Затем создайте Indication и запомните состояние фокусировки:
    class MyHighlightIndication : Indication {
        @Composable
        override fun rememberUpdatedInstance(interactionSource: InteractionSource):
            IndicationInstance {
            val isFocusedState = interactionSource.collectIsFocusedAsState()
            return remember(interactionSource) {
                MyHighlightIndicationInstance(isEnabledState = isFocusedState)
            }
        }
    }
  3. Добавьте в пользовательский интерфейс Indication и InteractionSource с помощью indication() :
    val highlightIndication = remember { MyHighlightIndication() }
    var interactionSource = remember { MutableInteractionSource() }
    
    Card(
        modifier = Modifier
            .clickable(
                interactionSource = interactionSource,
                indication = highlightIndication,
                enabled = true,
                onClick = { }
            )
    ) {}

Понять состояние фокуса

Как правило, каждый раз, когда состояние фокуса изменяется, FocusEvent запускается вверх по дереву, и родители модификатора focusable() могут прослушивать его с помощью модификатора onFocusChanged() .

Если вам нужно узнать состояние фокуса, вы можете использовать эти API в сочетании с модификатором onFocusChanged :

  • isFocused возвращает true , если составной объект, к которому прикреплен модификатор, находится в фокусе.
  • hasFocus работает аналогично isFocused , но с существенным отличием: вместо проверки только текущего элемента он проверяет, сфокусирован ли элемент или один из его дочерних элементов.
  • isCaptured возвращает true всякий раз, когда фокус удерживается. Это происходит, например, когда TextField содержит неправильные данные, поэтому попытка сфокусировать другие элементы не приведет к очистке фокуса.

Эти поля показаны ниже:

Modifier.onFocusChanged {
    val isFocused = it.isFocused
    val hasFocus = it.hasFocus
    val isCaptured= it.isCaptured
}
{% дословно %} {% дословно %} {% дословно %} {% дословно %}