Порядок перехода фокуса

Пользователи могут перемещать фокус клавиатуры между элементами интерфейса с помощью клавиши Tab или клавиш со стрелками (D-pad):

  • Tab / Shift+Tab – переход к следующему или предыдущему элементу в порядке появления на экране.
  • Клавиши со стрелками: перемещение фокуса в двух измерениях (вверх, вниз, влево и вправо).

Переход фокуса в одном измерении

При одномерном перемещении фокуса клавиша Tab переводит фокус на следующий элемент интерфейса в соответствии с порядком их визуального расположения на экране.

Например, если четыре кнопки расположены в два ряда:

Column {
    Row {
        Button(onClick = { /* ... */ }) { Text("1st") }
        Button(onClick = { /* ... */ }) { Text("2nd") }
    }
    Row {
        Button(onClick = { /* ... */ }) { Text("3rd") }
        Button(onClick = { /* ... */ }) { Text("4th") }
    }
}

Нажимая клавишу Tab, вы можете последовательно перемещать фокус между кнопками в следующем порядке:

  1. Первая кнопка (вверху слева)
  2. Вторая кнопка (сверху)
  3. Третья кнопка (снизу)
  4. Четвертая кнопка (в самом низу)

Если нажать клавишу Tab, когда фокус установлен на последнем элементе, он вернется к первому. Нажатие Shift + Tab перемещает фокус в обратном порядке.

Двумерный переход фокуса

При нажатии клавиш со стрелками или использовании D-pad фокус перемещается в двух измерениях.

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

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

Сброс перехода фокуса при нажатии указателем

При переключении между физической клавиатурой и мышью или сенсорной панелью на устройствах с большим экраном:

  • Снять фокус при нажатии или клике. Если нажать или кликнуть мышью или сенсорной панелью на неинтерактивном элементе, фокус будет снят с активного элемента.
  • Перезапуск перехода. После того как фокус будет снят, следующее нажатие клавиши Tab перезапустит одномерный переход с первого элемента в порядке визуального отображения, а не продолжит с ранее активного элемента. Это то же самое, что и двумерный переход фокуса. Клавиши со стрелками перемещают фокус клавиатуры на ближайший целевой объект в указанном направлении.

Подробнее о том, как программно очистить фокус…

Как настроить порядок перехода фокуса

Вы можете настроить поведение при переходе с помощью модификатора focusProperties.

Как настроить порядок перехода по элементам в одномерном пространстве

Чтобы переопределить однонаправленный переход, укажите свойство next или previous со значением FocusRequester:

  1. Создайте объект FocusRequester с remember { FocusRequester() }.
  2. Прикрепите FocusRequester к целевой composable-функции с помощью модификатора focusRequester.
  3. Примените модификатор focusProperties к исходной composable-функции и назначьте FocusRequester значение next (для Tab) или previous (для Shift + Tab).

val (first, second, third) = remember { FocusRequester.createRefs() }

Column {
    Button(
        onClick = { /* ... */ },
        modifier = Modifier
            .focusRequester(first)
            .focusProperties { next = third }
    ) {
        Text("First (Tab jumps to Third)")
    }
    Button(
        onClick = { /* ... */ },
        modifier = Modifier.focusRequester(second)
    ) {
        Text("Second")
    }
    Button(
        onClick = { /* ... */ },
        modifier = Modifier.focusRequester(third)
    ) {
        Text("Third")
    }
}

Как настроить порядок перехода по двумерной структуре

Аналогичным образом можно переопределить двумерный переход фокуса, назначив экземпляры FocusRequester элементам up, down, start, end, left или right в элементе focusProperties:

val (topButton, bottomButton) = remember { FocusRequester.createRefs() }

Button(
    onClick = { /* ... */ },
    modifier = Modifier
        .focusRequester(topButton)
        .focusProperties {
            down = bottomButton
            right = bottomButton
        }
) {
    Text("Top button")
}
Button(
    onClick = { /* ... */ },
    modifier = Modifier.focusRequester(bottomButton)
) {
    Text("Bottom button")
}

Чтобы заблокировать навигацию с помощью фокуса в определенном направлении (например, на границах макета), присвойте этому свойству значение FocusRequester.Cancel (например, down = FocusRequester.Cancel). Чтобы явно сохранить алгоритм перехода по умолчанию для определенного направления, присвойте значение FocusRequester.Default.