اگرچه بسیاری از برنامههای Android TV با اجزای بومی اندروید ساخته شدهاند، اما در نظر گرفتن دسترسی به چارچوبها یا اجزای شخص ثالث نیز مهم است، به خصوص هنگام استفاده از نماهای سفارشی .
اجزای نمای سفارشی که مستقیماً با OpenGL یا Canvas در ارتباط هستند، ممکن است با سرویسهای دسترسی مانند Talkback و Switch Access به خوبی کار نکنند.
برخی از مشکلات زیر را که ممکن است با روشن بودن Talkback رخ دهد، در نظر بگیرید:
- ممکن است فوکوس دسترسی (مستطیل سبز) در برنامه شما ناپدید شود.
- تمرکز دسترسی ممکن است مرز کل صفحه را انتخاب کند.
- ممکن است فوکوس دسترسیپذیری قابل جابجایی نباشد.
- چهار کلید جهتنما روی D-pad ممکن است هیچ تاثیری نداشته باشند، حتی اگر کد شما آنها را مدیریت کند.
اگر هر یک از این مشکلات را در برنامه خود مشاهده کردید، بررسی کنید که برنامه شما درخت AccessibilityNodeInfo خود را در اختیار سرویسهای دسترسی قرار میدهد.
ادامهی این راهنما، برخی راهکارها و بهترین شیوهها را برای رسیدگی به این مسائل ارائه میدهد.
رویدادهای D-pad توسط سرویسهای دسترسی مصرف میشوند
دلیل اصلی این مشکل این است که رویدادهای کلیدی توسط سرویسهای دسترسی مصرف میشوند.

همانطور که در شکل ۱ نشان داده شده است، وقتی Talkback روشن است، رویدادهای D-pad به کنترلکنندهی D-pad که توسط توسعهدهنده تعریف شده است، منتقل نمیشوند. در عوض، سرویسهای دسترسی، رویدادهای کلیدی را دریافت میکنند تا بتوانند تمرکز دسترسی را جابجا کنند. از آنجا که اجزای سفارشی اندروید به طور پیشفرض اطلاعات مربوط به موقعیت خود روی صفحه را در اختیار سرویسهای دسترسی قرار نمیدهند، سرویسهای دسترسی نمیتوانند تمرکز دسترسی را برای برجسته کردن آنها جابجا کنند.
سایر سرویسهای دسترسی نیز به طور مشابه تحت تأثیر قرار میگیرند: رویدادهای D-pad نیز ممکن است هنگام استفاده از Switch Access مصرف شوند.
از آنجا که رویدادهای 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 - فعالسازی دسترسی برای نابینایان و کمبینایان در اندروید را تماشا کنید یا درباره رویدادهای مربوط به دسترسیپذیری بیشتر بخوانید.
بهترین شیوهها
الزامی:
AccessibilityNodeInfo.getBoundsInScreen()باید موقعیت کامپوننت را تعریف کند.الزامی:
AccessibilityNodeInfo.setVisibleToUser()باید میزان دیده شدن کامپوننت را نشان دهد.الزامی:
AccessibilityNodeInfo.getContentDescription()باید توضیحات محتوایی را که Talkback قرار است اعلام کند، مشخص کند.AccessibilityNodeInfo.setClassName()را مشخص کنید تا سرویسها بتوانند نوع کامپوننت را تشخیص دهند.هنگام پیادهسازی
performAction()، عمل را با استفاده ازAccessibilityEventمربوطه منعکس کنید.برای پیادهسازی انواع اکشنهای بیشتر، مانند
ACTION_CLICK، با استفاده از منطق مربوطه درperformAction()AccessibilityNodeInfo.addAction(ACTION_CLICK)را فراخوانی کنید.در صورت لزوم، وضعیت کامپوننت را برای متدهای
setFocusable()،setClickable()،setScrollable()و متدهای مشابه منعکس کنید.برای شناسایی روشهای دیگری که سرویسهای دسترسی میتوانند از طریق آنها تعامل بهتری با اجزای شما داشته باشند، مستندات
AccessibilityNodeInfoرا مرور کنید.
نمونه
برای مشاهده بهترین شیوهها برای افزودن پشتیبانی از قابلیت دسترسی به برنامهها با استفاده از نماهای سفارشی، به نمونه دسترسیپذیری نمای سفارشی برای Android TV مراجعه کنید.