پشتیبانی از قابلیت دسترسی سفارشی در Android TV
با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
در حالی که بسیاری از برنامههای Android TV با مؤلفههای اصلی Android ساخته میشوند، مهم است که دسترسی به چارچوبها یا مؤلفههای شخص ثالث را نیز در نظر بگیرید، مخصوصاً هنگام استفاده از نماهای سفارشی .
اجزای نمای سفارشی که مستقیماً با OpenGL یا Canvas واسط میشوند ممکن است با سرویسهای دسترسپذیری مانند Talkback و Switch Access به خوبی کار نکنند.
برخی از مشکلات زیر را که ممکن است با روشن بودن Talkback رخ دهد، در نظر بگیرید:
- فوکوس دسترسی (مستطیل سبز) ممکن است در برنامه شما ناپدید شود.
- فوکوس دسترسپذیری ممکن است مرز کل صفحه را انتخاب کند.
- فوکوس دسترسپذیری ممکن است متحرک نباشد.
- چهار کلید جهت روی D-pad ممکن است هیچ تاثیری نداشته باشند، حتی اگر کد شما آنها را مدیریت کند.
اگر هر یک از این مشکلات را در برنامه خود مشاهده کردید، بررسی کنید که برنامه شما درخت AccessibilityNodeInfo
خود را در معرض خدمات دسترسپذیری قرار دهد.
بقیه این راهنما راه حل ها و بهترین روش ها را برای رسیدگی به این مسائل ارائه می دهد.
رویدادهای D-pad توسط سرویسهای دسترسی مصرف میشوند
علت اصلی این موضوع این است که رویدادهای کلیدی توسط سرویسهای دسترسی مصرف میشوند.
شکل 1. نمودارهایی که نحوه عملکرد سیستم را با روشن و خاموش کردن Talkback نشان می دهد.
همانطور که در شکل 1 نشان داده شده است، وقتی Talkback روشن است، رویدادهای D-pad به کنترل کننده D-pad تعریف شده توسط توسعه دهنده منتقل نمی شوند. در عوض، خدمات دسترسپذیری رویدادهای کلیدی را دریافت میکنند تا بتوانند تمرکز دسترسی را تغییر دهند. از آنجایی که مؤلفههای سفارشی Android بهطور پیشفرض اطلاعاتی را درباره موقعیت خود روی صفحه در اختیار سرویسهای دسترسپذیری قرار نمیدهند، سرویسهای دسترسپذیری نمیتوانند تمرکز دسترسپذیری را برای برجسته کردن آنها تغییر دهند.
سایر خدمات دسترسپذیری نیز به طور مشابه تحت تأثیر قرار میگیرند: رویدادهای D-pad نیز ممکن است هنگام استفاده از «دسترسی سوئیچ» مصرف شوند.
از آنجایی که رویدادهای D-pad به سرویسهای دسترسپذیری ارسال میشوند و آن سرویس نمیداند اجزای رابط کاربری در یک نمای سفارشی کجا هستند، باید AccessibilityNodeInfo
را برای برنامهتان پیادهسازی کنید تا رویدادهای کلیدی را به درستی ارسال کند.
برای ارائه خدمات دسترسپذیری با اطلاعات کافی درباره مکان و شرح نماهای سفارشی، AccessibilityNodeInfo
را پیادهسازی کنید تا جزئیات هر مؤلفه را در معرض دید قرار دهید. برای تعریف رابطه منطقی نماها به طوری که سرویسهای دسترسپذیری بتوانند تمرکز را مدیریت کنند، ExploreByTouchHelper
پیادهسازی کنید و آن را با استفاده از ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat)
برای نماهای سفارشی تنظیم کنید.
هنگام پیاده سازی ExploreByTouchHelper
، چهار روش انتزاعی آن را نادیده بگیرید:
کاتلین
// 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
جاوا
// 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)
برای جزئیات بیشتر، Google I/O 2013 - فعال کردن دسترسی نابینا و کم بینا را در Android تماشا کنید یا درباره پر کردن رویدادهای دسترسی بیشتر بخوانید.
بهترین شیوه ها
نمونه
برای مشاهده بهترین روشها برای افزودن پشتیبانی دسترسپذیری به برنامهها با استفاده از نماهای سفارشی، با نمونه دسترسی سفارشی برای Android TV مشورت کنید.
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی."],[],[],null,["# Custom view accessibility support on Android TV\n\nWhile many Android TV apps are built with native Android components, it's\nalso important to consider the accessibility of third-party\nframeworks or components, especially when using [custom views](https://developer.android.com/guide/topics/ui/custom-components).\n\nCustom view components interfacing directly with OpenGL or Canvas might not work well\nwith accessibility services like Talkback and Switch Access.\n\nConsider some of the following issues that might occur with Talkback switched\non:\n\n- The accessibility focus (a green rectangle) might disappear in your app.\n- The accessibility focus might select the boundary of the whole screen.\n- The accessibility focus might not be movable.\n- The four direction keys on the D-pad might have no effect, even if your code is handling them.\n\n\u003cbr /\u003e\n\nIf you observe any of these issues in your app, check that your\napp exposes its [`AccessibilityNodeInfo`](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo)\ntree to the accessibility services.\n\nThe remainder of this guide provides some solutions and best practices to address these issues.\n\nD-pad events are consumed by accessibility services\n---------------------------------------------------\n\nThe root cause of this issue is that key events are consumed by accessibility\nservices.\n\n\n**Figure 1.** Diagrams depicting how the system functions with Talkback on and off.\n\nAs illustrated in figure 1, when Talkback is switched on, D-pad events\nare not passed to the D-pad handler defined by developer. Instead,\naccessibility services receive the key events so they can move the\naccessibility focus. Because custom Android components don't by default expose\ninformation to accessibility services about their position on the screen,\naccessibility services can't move the accessibility focus to highlight them.\n\nOther accessibility services are similarly affected: D-pad events might also be\nconsumed when using Switch Access.\n\nBecause D-pad events are submitted to accessibility services, and\nthat service doesn't know where UI components are in a custom view,\nyou must implement `AccessibilityNodeInfo` for your app to forward the\nkey events correctly.\n\nExpose information to accessibility services\n--------------------------------------------\n\nTo provide accessibility services with sufficient information about the\nlocation and description of custom views, implement [`AccessibilityNodeInfo`](/reference/android/view/accessibility/AccessibilityNodeInfo)\nto expose details for each component.\nTo define the logical relationship of views so that accessibility services can\nmanage focus, implement [`ExploreByTouchHelper`](https://developer.android.com/reference/androidx/customview/widget/ExploreByTouchHelper)\nand set it using\n[`ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat)`](https://developer.android.com/reference/androidx/core/view/ViewCompat#setAccessibilityDelegate(android.view.View,%20androidx.core.view.AccessibilityDelegateCompat))\nfor custom views.\n\nWhen implementing `ExploreByTouchHelper`, override its four abstract methods: \n\n### Kotlin\n\n```kotlin\n// Return the virtual view ID whose view is covered by the input point (x, y).\nprotected fun getVirtualViewAt(x: Float, y: Float): Int\n\n// Fill the virtual view ID list into the input parameter virtualViewIds.\nprotected fun getVisibleVirtualViews(virtualViewIds: List\u003cInt\u003e)\n\n// For the view whose virtualViewId is the input virtualViewId, populate the\n// accessibility node information into the AccessibilityNodeInfoCompat parameter.\nprotected fun onPopulateNodeForVirtualView(virtualViewId: Int, @NonNull node: AccessibilityNodeInfoCompat)\n\n// Set the accessibility handling when perform action.\nprotected fun onPerformActionForVirtualView(virtualViewId: Int, action: Int, @Nullable arguments: Bundle): Boolean\n```\n\n### Java\n\n```java\n// Return the virtual view ID whose view is covered by the input point (x, y).\nprotected int getVirtualViewAt(float x, float y)\n\n// Fill the virtual view ID list into the input parameter virtualViewIds.\nprotected void getVisibleVirtualViews(List\u003cInteger\u003e virtualViewIds)\n\n// For the view whose virtualViewId is the input virtualViewId, populate the\n// accessibility node information into the AccessibilityNodeInfoCompat parameter.\nprotected void onPopulateNodeForVirtualView(int virtualViewId, @NonNull AccessibilityNodeInfoCompat node)\n\n// Set the accessibility handling when perform action.\nprotected boolean onPerformActionForVirtualView(int virtualViewId, int action, @Nullable Bundle arguments)\n```\n\nFor more details, watch [Google I/O 2013 - Enabling Blind and Low-Vision\nAccessibility on Android](https://www.youtube.com/watch?v=ld7kZRpMGb8&t=1196)\nor read more about [populating accessibility events](https://developer.android.com/guide/topics/ui/accessibility/custom-views#populate-events).\n\nBest practices\n--------------\n\n- **Required:** [`AccessibilityNodeInfo.getBoundsInScreen()`](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#getBoundsInScreen(android.graphics.Rect))\n must define the position of the component.\n\n- **Required:** [`AccessibilityNodeInfo.setVisibleToUser()`](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setVisibleToUser(boolean))\n must reflect the visibility of the component.\n\n- **Required:** [`AccessibilityNodeInfo.getContentDescription()`](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#getContentDescription())\n must specify the content description for Talkback to announce.\n\n- Specify [`AccessibilityNodeInfo.setClassName()`](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setClassName(java.lang.CharSequence))\n so services can distinguish the component type.\n\n- When implementing [`performAction()`](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#performAction(int)),\n reflect the action using a corresponding [`AccessibilityEvent`](https://developer.android.com/reference/android/view/accessibility/AccessibilityEvent).\n\n- To implement more action types, such as `ACTION_CLICK`, invoke\n [`AccessibilityNodeInfo.addAction(ACTION_CLICK)`](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#addAction(android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction))\n using the corresponding logic in `performAction()`.\n\n- When applicable, reflect the component state for [`setFocusable()`](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setFocusable(boolean)),\n [`setClickable()`](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setClickable(boolean)),\n [`setScrollable()`](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setScrollable(boolean)),\n and similar methods.\n\n- Review the documentation for [`AccessibilityNodeInfo`](/reference/android/view/accessibility/AccessibilityNodeInfo)\n to identify other ways in which accessibility services can better interact with\n your components.\n\nSample\n------\n\nConsult the [custom view accessibility sample for Android TV](/training/tv/accessibility/custom-views-sample) to see best practices for\nadding accessibility support to apps using custom views."]]