Фокус в создании

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

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

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

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

  • Изменить порядок обхода фокуса . Объясняет, как изменить порядок фокуса по умолчанию, добавить фокус-группы и отключить фокус составного объекта.
  • Изменение поведения фокуса : описывает, как запрашивать, захватывать и отпускать фокус, а также как перенаправлять фокус при входе на экран.
  • Реакция на фокус : объясняет, как реагировать на изменения фокуса, добавлять визуальные подсказки к элементам и понимать состояние фокуса элемента.

Порядок обхода фокуса по умолчанию

Прежде чем мы углубимся в поведение по умолчанию при поиске фокуса, важно понять концепцию уровня в иерархии: вообще говоря, мы можем сказать, что два Composables находятся на одном уровне, когда они являются братьями и сестрами, то есть у них одни и те же родители. . Например, элементы внутри Column находятся на одном уровне. Повышение уровня означает переход от дочернего элемента к его Composable родительскому элементу или, сохраняя тот же пример, возврат от элемента к Column , который его содержит. Спуск на уровень происходит наоборот: от родительского Column к содержащимся в нем элементам. Эту концепцию можно применить к каждому Composable , который может содержать другие Composables .

Навигация по пользовательскому интерфейсу может осуществляться несколькими способами, некоторые из которых уже известны большинству пользователей:

  • Вкладки: одномерная навигация вперед или назад . Навигация с помощью TAB переводит фокус на следующий или предыдущий элемент иерархии. По умолчанию Compose следует объявлению Composables . Однонаправленную навигацию можно осуществить с помощью клавиши tab на клавиатуре или вращающегося безеля на часах, и такой вид поиска фокуса будет охватывать каждый элемент на экране.
  • Клавиши со стрелками: двухмерная навигация влево, вправо, вверх или вниз . Двухмерная навигация может быть достигнута с помощью D-Pad на телевизоре или клавиш со стрелками на клавиатуре, а порядок ее обхода касается только элементов на заданном уровне. Вы можете использовать центральную кнопку D-Pad и кнопку «Назад», чтобы перейти вниз и вернуться на другой уровень.

Возьмем в качестве примера снимок экрана ниже, где у вас есть четыре кнопки, одна под другой, и вы хотите просмотреть их все в порядке появления. Jetpack Compose обеспечивает такое поведение «из коробки»: набор инструментов позволяет циклически просматривать каждый компонуемый объект в вертикальном порядке сверху вниз с помощью клавиши tab или перемещать фокус, нажимая стрелку вверх или вниз .

Скриншот списка кнопок, расположенных вертикально одна под другой в небольшом форм-факторе.
Рисунок 1 . Список кнопок, отображаемых в небольшом форм-факторе

Когда вы переключаетесь на другой тип макета, все немного меняется. Если ваш макет содержит более одного столбца, как показано ниже, Jetpack Compose позволяет перемещаться по ним без необходимости добавления какого-либо кода. Если вы нажмете клавишу tab , Jetpack Compose автоматически выделит элементы в порядке объявления, от первого до четвертого. Используя клавиши со стрелками на клавиатуре, выбор будет следовать в желаемом направлении в 2D-пространстве.

Column {
    Row {
        TextButton({ }) { Text("First field") }
        TextButton({ }) { Text("Second field") }
    }
    Row {
        TextButton({ }) { Text("Third field") }
        TextButton({ }) { Text("Fourth field") }
    }
}

Composables объявляются в двух Rows , а элементы фокуса объявляются по порядку, с первого по четвертый. Когда вы нажимаете клавишу tab , это приводит к следующему порядку фокусировки:

Снимок экрана: список кнопок, размещенных в двух столбцах рядом, в увеличенном форм-факторе.
Рисунок 2 . Список кнопок, размещенных в двух столбцах рядом, в более крупном форм-факторе.

В приведенном ниже фрагменте вы объявляете элементы в Columns , а не в Rows :

Row {
    Column {
        TextButton({ }) { Text("First field") }
        TextButton({ }) { Text("Second field") }
    }
    Column {
        TextButton({ }) { Text("Third field") }
        TextButton({ }) { Text("Fourth field") }
    }
}

Этот макет перемещает элементы вертикально сверху вниз, от начала экрана к концу:

Снимок экрана: список кнопок, размещенных в двух столбцах рядом, в увеличенном форм-факторе.
Рисунок 3 . Список кнопок, размещенных в двух столбцах рядом, в более крупном форм-факторе.

Два предыдущих примера, хотя и отличаются однонаправленной навигацией, обеспечивают одинаковые возможности двумерной навигации. Обычно это происходит потому, что в обоих примерах элементы на экране имеют одинаковое географическое расположение. При перемещении вправо от первого Column фокус перемещается ко второму, а при перемещении вниз от первой Row фокус перемещается на строку, расположенную под ней.

{% дословно %} {% дословно %} {% дословно %} {% дословно %}