Mặc dù nhiều ứng dụng Android TV được xây dựng bằng các thành phần gốc của Android, nhưng Ngoài ra, bạn cũng cần xem xét khả năng truy cập của các ứng dụng khung hoặc thành phần, đặc biệt là khi sử dụng chế độ xem tuỳ chỉnh.
Các thành phần khung hiển thị tuỳ chỉnh giao tiếp trực tiếp với OpenGL hoặc Canvas có thể không hoạt động tốt bằng 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 cân nhắc một số vấn đề sau đây có thể xảy ra khi TalkBack đang chuyển đổi vào:
- 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 đường viền của toàn bộ màn hình.
- Không thể di chuyển tâm điểm hỗ trợ tiếp cận.
- 4 phím 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ế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
ứng dụng hiển thị AccessibilityNodeInfo
cho 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ẽ 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 tính năng hỗ trợ tiếp cận sử dụng các sự kiện chính luôn miễn phí.
Hình 1. Sơ đồ mô tả cách hoạt động của hệ thống khi bật và tắt TalkBack.
Như minh hoạ trong hình 1, khi TalkBack được bật, các sự kiện trên D-pad không được chuyển tới 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 nhận được các sự kiện chính để có thể di chuyển tập trung vào khả năng hỗ trợ tiếp cận. Vì các thành phần Android tuỳ chỉnh không hiển thị theo mặc định 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, 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 dịch vụ đó.
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 trên D-pad cũng có thể bị ảnh hưởng tiêu thụ khi dùng tính năng Tiếp cận bằng công tắc.
Bởi vì các sự kiệ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 khung hiển thị tuỳ chỉnh,
bạn phải triển khai AccessibilityNodeInfo
cho ứng dụng của mình để chuyển tiếp
sự kiện chính một cách chính xác.
Cung cấp thông tin cho 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 đầy đủ thông tin về
vị trí và nội dung mô tả của chế độ xem tuỳ chỉnh, hãy triển khai AccessibilityNodeInfo
để hiển thị thông tin chi tiết về từng thành phần.
Xác định mối quan hệ logic của các khung hiển thị để các dịch vụ hỗ trợ tiếp cận có thể
quản lý tiêu điểm, triển khai ExploreByTouchHelper
và thiết lập bằng
ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat)
cho 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 lớp này:
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 chi tiết, hãy xem Google I/O 2013 - Bật tính năng cho người khiếm thị và thị lực kém Hỗ trợ tiếp cận trên Android hoặc đọc thêm về cách điền 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 phần mô tả nội dung để 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()
, phản ánh hành động bằng cách sử dụngAccessibilityEvent
tương ứng.Để triển khai các loại thao tác khác, chẳng hạn như
ACTION_CLICK
, hãy gọiAccessibilityNodeInfo.addAction(ACTION_CLICK)
bằng cách sử dụng logic tương ứng trongperformAction()
.Khi có thể, hãy phản ánh trạng thái thành phần cho
setFocusable()
,setClickable()
,setScrollable()
, và các phương pháp 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 hiệu quả hơn với thành phần của bạn.
Mẫu
Tham khảo mẫu hỗ trợ tiếp cận khung hiển thị tuỳ chỉnh dành cho Android TV để biết các phương pháp hay nhất về thêm tính năng hỗ trợ tiếp cận vào các ứng dụng bằng khung hiển thị tuỳ chỉnh.