焦点遍历顺序

用户可以使用 Tab 键或方向(箭头 / 方向键)键在界面元素之间移动键盘焦点:

  • 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. 第 1 个按钮(顶部开头)
  2. 第 2 个按钮(顶端)
  3. 第 3 个按钮(底部开始)
  4. 第 4 个按钮(底部末端)

在最后一个元素上按 Tab 键会返回到第一个焦点目标。 按 Shift+Tab 可按相反顺序移动焦点。

二维焦点遍历

按键盘箭头键或使用方向键会触发二维焦点遍历。

在二维遍历中,系统会检查界面元素的几何坐标和空间边界,以确定所请求方向上最近的目标。

二维焦点遍历不会循环。 如果用户在焦点位于最底部元素时按下 Down 键,焦点会保持在该元素上,而不会跳转到屏幕顶部。

通过指针点击重置焦点遍历

在桌面设备或大屏设备上切换实体键盘和鼠标或触控板时:

  • 点按或点击时清除焦点:使用鼠标或触控板点击或点按非互动空间,可从活动元素中释放焦点。
  • 重新开始遍历:清除焦点后,下次按下 Tab 键时,系统会按照视觉外观顺序从第一个焦点目标重新开始一维遍历,而不是从之前处于活动状态的元素继续遍历。 这与二维焦点遍历相同。 方向键会将键盘焦点移动到所请求方向上最近的焦点目标。

如需详细了解如何以编程方式清除焦点,请参阅移动和清除焦点。

自定义焦点遍历顺序

您可以使用 focusProperties 修饰符自定义遍历行为。

自定义一维遍历顺序

如需替换一维遍历,请使用 FocusRequester 指定 next 或 previous 属性:

  1. 使用 remember { FocusRequester() } 创建一个 FocusRequester 对象。
  2. 使用 focusRequester 修饰符将 FocusRequester 附加到目标可组合项。
  3. 将 focusProperties 修饰符应用于源可组合项,并将 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")
    }
}

自定义二维遍历顺序

同样,您也可以在 focusProperties 中将 FocusRequester 实例分配给 up、down、start、end、left 或 right,从而替换二维焦点遍历:

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")
}

如需在特定方向(例如,在布局边界处)屏蔽焦点导航,请为该属性(例如 down = FocusRequester.Cancel)分配 FocusRequester.Cancel。如需为给定方向显式保留系统的默认遍历算法,请分配 FocusRequester.Default。