Mặc dù nhiều ứng dụng Android TV được tạo bằng các thành phần Android gốc, nhưng bạn cũng cần cân nhắc khả năng tiếp cận của các thành phần hoặc khung bên thứ ba, đặc biệt là khi sử dụng khung hiển thị tuỳ chỉnh.
Các thành phần khung hiển thị tuỳ chỉnh tương tác trực tiếp với OpenGL hoặc Canvas có thể không hoạt động tốt với các dịch vụ hỗ trợ tiếp cận như TalkBack và Tiếp cận bằng công tắc.
Hãy xem xét một số vấn đề sau đây có thể xảy ra khi bạn bật TalkBack:
- Tiêu điểm hỗ trợ tiếp cận (hình chữ nhật màu xanh lục) có thể biến mất trong ứng dụng của bạn.
- Tiêu điểm hỗ trợ tiếp cận có thể chọn ranh giới của toàn bộ màn hình.
- Tiêu điểm hỗ trợ tiếp cận có thể không di chuyển được.
- Bốn phím định hướng trên D-pad có thể không có tác dụng, ngay cả khi mã của bạn đang xử lý các phím này.
Nếu bạn nhận thấy bất kỳ vấn đề nào trong số này trong ứng dụng của mình, hãy kiểm tra để đảm bảo rằng ứng dụng của bạn hiển thị cây AccessibilityNodeInfo cho các dịch vụ hỗ trợ tiếp cận.
Phần còn lại của hướng dẫn này cung cấp một số giải pháp và phương pháp hay nhất để giải quyết những vấn đề này.
Các dịch vụ hỗ trợ tiếp cận sử dụng các sự kiện trên D-pad
Nguyên nhân gốc rễ của vấn đề này là do các dịch vụ hỗ trợ tiếp cận sử dụng các sự kiện chính.
Như minh hoạ trong hình 1, khi Talkback được bật, các sự kiện trên D-pad sẽ không được truyền đến trình xử lý D-pad do nhà phát triển xác định. Thay vào đó, các dịch vụ hỗ trợ tiếp cận sẽ nhận được các sự kiện chính để có thể di chuyển tâm điểm hỗ trợ tiếp cận. Vì theo mặc định, các thành phần Android tuỳ chỉnh không hiển thị thông tin cho các dịch vụ hỗ trợ tiếp cận về vị trí của chúng trên màn hình, nên các dịch vụ hỗ trợ tiếp cận không thể di chuyển tiêu điểm hỗ trợ tiếp cận để làm nổi bật các thành phần đó.
Các dịch vụ hỗ trợ tiếp cận khác cũng bị ảnh hưởng tương tự: Các sự kiện D-pad cũng có thể bị tiêu thụ khi sử dụng tính năng Tiếp cận bằng công tắc.
Vì các sự kiện trên D-pad được gửi đến các dịch vụ hỗ trợ tiếp cận và dịch vụ đó không biết các thành phần giao diện người dùng nằm ở đâu trong một khung hiển thị tuỳ chỉnh, nên bạn phải triển khai AccessibilityNodeInfo để ứng dụng của bạn chuyển tiếp các sự kiện chính một cách chính xác.
Đưa thông tin vào các dịch vụ hỗ trợ tiếp cận
Để cung cấp cho các dịch vụ hỗ trợ tiếp cận thông tin đầy đủ về vị trí và nội dung mô tả của các thành phần hiển thị tuỳ chỉnh, hãy triển khai AccessibilityNodeInfo để hiển thị thông tin chi tiết cho từng thành phần. Để xác định mối quan hệ logic của các khung hiển thị để dịch vụ hỗ trợ tiếp cận có thể quản lý tâm điểm, hãy triển khai ExploreByTouchHelper và đặt tâm điểm bằng ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat) cho các khung hiển thị tuỳ chỉnh.
Khi triển khai ExploreByTouchHelper, hãy ghi đè 4 phương thức trừu tượng của nó:
Kotlin
// Return the virtual view ID whose view is covered by the input point (x, y).
protected fun getVirtualViewAt(x: Float, y: Float): Int
// Fill the virtual view ID list into the input parameter virtualViewIds.
protected fun getVisibleVirtualViews(virtualViewIds: List<Int>)
// For the view whose virtualViewId is the input virtualViewId, populate the
// accessibility node information into the AccessibilityNodeInfoCompat parameter.
protected fun onPopulateNodeForVirtualView(virtualViewId: Int, @NonNull node: AccessibilityNodeInfoCompat)
// Set the accessibility handling when perform action.
protected fun onPerformActionForVirtualView(virtualViewId: Int, action: Int, @Nullable arguments: Bundle): Boolean
Java
// Return the virtual view ID whose view is covered by the input point (x, y).
protected int getVirtualViewAt(float x, float y)
// Fill the virtual view ID list into the input parameter virtualViewIds.
protected void getVisibleVirtualViews(List<Integer> virtualViewIds)
// For the view whose virtualViewId is the input virtualViewId, populate the
// accessibility node information into the AccessibilityNodeInfoCompat parameter.
protected void onPopulateNodeForVirtualView(int virtualViewId, @NonNull AccessibilityNodeInfoCompat node)
// Set the accessibility handling when perform action.
protected boolean onPerformActionForVirtualView(int virtualViewId, int action, @Nullable Bundle arguments)
Để biết thêm thông tin chi tiết, hãy xem video Google I/O 2013 – Bật tính năng hỗ trợ tiếp cận cho người khiếm thị và người có thị lực kém trên Android hoặc đọc thêm về cách điền sẵn các sự kiện hỗ trợ tiếp cận.
Các phương pháp hay nhất
Bắt buộc:
AccessibilityNodeInfo.getBoundsInScreen()phải xác định vị trí của thành phần.Bắt buộc:
AccessibilityNodeInfo.setVisibleToUser()phải phản ánh chế độ hiển thị của thành phần.Bắt buộc:
AccessibilityNodeInfo.getContentDescription()phải chỉ định nội dung mô tả để TalkBack thông báo.Chỉ định
AccessibilityNodeInfo.setClassName()để các dịch vụ có thể phân biệt loại thành phần.Khi triển khai
performAction(), hãy phản ánh thao tác bằngAccessibilityEventtương ứng.Để triển khai nhiều loại thao tác hơn, chẳng hạn như
ACTION_CLICK, hãy gọiAccessibilityNodeInfo.addAction(ACTION_CLICK)bằng logic tương ứng trongperformAction().Khi có thể, hãy phản ánh trạng thái của thành phần cho
setFocusable(),setClickable(),setScrollable()và các phương thức tương tự.Xem tài liệu về
AccessibilityNodeInfođể xác định những cách khác mà các dịch vụ hỗ trợ tiếp cận có thể tương tác tốt hơn với các thành phần của bạn.
Mẫu
Hãy tham khảo mẫu hỗ trợ tiếp cận khung hiển thị tuỳ chỉnh cho Android TV để xem các phương pháp hay nhất để thêm tính năng hỗ trợ tiếp cận vào các ứng dụng sử dụng khung hiển thị tuỳ chỉnh.