Focus traversal order (Thứ tự duyệt qua tiêu điểm)

Người dùng có thể di chuyển tiêu điểm bàn phím qua các phần tử trên giao diện người dùng bằng phím Tab hoặc các phím định hướng (mũi tên / D-pad):

  • Tab / Shift+Tab: Di chuyển tiêu điểm về phía trước hoặc phía sau theo thứ tự xuất hiện một chiều.
  • Phím định hướng: Di chuyển tiêu điểm theo hai chiều (Lên, Xuống, Trái và Phải).

Duyệt qua tiêu điểm theo một chiều

Trong quá trình duyệt qua tiêu điểm theo một chiều, phím Tab sẽ di chuyển tiêu điểm qua giao diện người dùng dựa trên thứ tự xuất hiện trực quan trên màn hình.

Ví dụ: khi 4 nút được sắp xếp thành các hàng:

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

Thao tác nhấn phím Tab sẽ di chuyển tiêu điểm tuần tự qua các nút theo thứ tự sau:

  1. Nút thứ nhất (trên cùng bên trái)
  2. Nút thứ 2 (đầu trên)
  3. Nút thứ 3 (dưới cùng bên trái)
  4. Nút thứ 4 (dưới cùng bên phải)

Khi bạn nhấn phím Tab trên phần tử cuối cùng, tiêu điểm sẽ quay lại mục tiêu lấy tiêu điểm đầu tiên. Nhấn tổ hợp phím Shift+Tab để di chuyển tiêu điểm theo thứ tự ngược lại.

Duyệt qua tiêu điểm theo hai chiều

Thao tác nhấn phím mũi tên trên bàn phím hoặc sử dụng D-pad sẽ kích hoạt quá trình duyệt qua tiêu điểm theo hai chiều.

Trong quá trình duyệt qua hai chiều, hệ thống sẽ kiểm tra toạ độ hình học và ranh giới không gian của các phần tử trên giao diện người dùng để xác định mục tiêu gần nhất theo hướng được yêu cầu.

Quá trình duyệt qua tiêu điểm theo hai chiều không quay vòng. Nếu người dùng nhấn phím Xuống trong khi tập trung vào phần tử dưới cùng, thì tiêu điểm vẫn nằm trên phần tử đó thay vì chuyển lên đầu màn hình.

Đặt lại thứ tự duyệt tiêu điểm bằng các lượt nhấp con trỏ

Khi chuyển đổi giữa bàn phím thực và chuột hoặc bàn di chuột trên máy tính hoặc thiết bị màn hình lớn:

  • Xoá tiêu điểm khi nhấn hoặc nhấp: Nhấp hoặc nhấn vào không gian không tương tác bằng chuột hoặc bàn di chuột sẽ giải phóng tiêu điểm khỏi phần tử đang hoạt động.
  • Khởi động lại quá trình truyền tải: Sau khi tiêu điểm bị xoá, lần nhấn phím Tab tiếp theo sẽ khởi động lại quá trình truyền tải một chiều tại mục tiêu lấy tiêu điểm đầu tiên theo thứ tự xuất hiện trực quan, thay vì tiếp tục từ phần tử đang hoạt động trước đó. Quá trình này giống với quá trình duyệt qua tiêu điểm theo hai chiều. Các phím định hướng sẽ di chuyển tiêu điểm bàn phím đến mục tiêu lấy tiêu điểm gần nhất theo hướng được yêu cầu.

Để biết thông tin chi tiết về cách xoá tiêu điểm theo phương thức lập trình, hãy xem phần Di chuyển và xoá tiêu điểm.

Tuỳ chỉnh thứ tự duyệt qua tiêu điểm

Bạn có thể tuỳ chỉnh hành vi truyền tải bằng đối tượng sửa đổi focusProperties.

Tuỳ chỉnh thứ tự duyệt qua một chiều

Để ghi đè thao tác truyền tải một chiều, hãy chỉ định thuộc tính next hoặc previous bằng FocusRequester:

  1. Tạo đối tượng FocusRequester bằng remember { FocusRequester() }.
  2. Đính kèm FocusRequester vào thành phần kết hợp mục tiêu bằng đối tượng sửa đổi focusRequester.
  3. Áp dụng đối tượng sửa đổi focusProperties cho thành phần kết hợp nguồn và chỉ định FocusRequester cho next (đối với Tab) hoặc previous (đối với 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")
    }
}

Tuỳ chỉnh thứ tự duyệt qua hai chiều

Tương tự, bạn có thể ghi đè thao tác duyệt qua tiêu điểm hai chiều bằng cách chỉ định các thực thể FocusRequester cho up, down, start, end, left hoặc right trong 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")
}

Để chặn thao tác di chuyển tiêu điểm theo một hướng cụ thể (ví dụ: tại ranh giới bố cục), hãy gán FocusRequester.Cancel cho thuộc tính đó (ví dụ: down = FocusRequester.Cancel). Để giữ lại thuật toán truyền tải mặc định của hệ thống cho một hướng nhất định, hãy gán FocusRequester.Default.