إذا كان الطلب يتطلب مكون العرض المخصص، ينبغي أن تجعل العرض أكثر سهولة. يمكن أن تؤدي الخطوات التالية إلى تحسين طرق العرض المخصصة إمكانية الوصول، كما هو موضح في هذه الصفحة:
- التعامل مع النقرات على وحدة التحكّم الاتجاهات
- تنفيذ طرق واجهة برمجة التطبيقات Accessibility API
- إرسال
AccessibilityEvent
الكائنات الخاصة بطريقة العرض المخصصة. - تعبئة
AccessibilityEvent
وAccessibilityNodeInfo
لعرضك
التعامل مع النقرات على وحدة التحكّم الاتجاهات
في معظم الأجهزة، يؤدي النقر على عرض باستخدام وحدة تحكم الاتجاهات إلى إرسال
KeyEvent
باستخدام
KEYCODE_DPAD_CENTER
بطريقة العرض محل التركيز حاليًا. الاسم المعرِّف العادي لكل طرق العرض على Android
KEYCODE_DPAD_CENTER
بشكل ملائم عند إنشاء تخصيص
View
تأكد من أن هذا الحدث له نفس تأثير النقر على طريقة العرض على الشاشة التي تعمل باللمس.
يجب أن يتعامل عنصر التحكّم المخصّص مع
KEYCODE_ENTER
الحدث نفسه مثل KEYCODE_DPAD_CENTER
. يؤدي هذا الإجراء إلى التفاعل مع لوحة مفاتيح كاملة
أسهل للمستخدمين.
تنفيذ طرق واجهة برمجة التطبيقات Accessibility API
أحداث إمكانية الوصول هي رسائل حول التفاعلات مع الواجهة المرئية لتطبيقك
والمكونات. يتم التعامل مع هذه الرسائل بواسطة خدمات إمكانية الوصول، التي
استخدام المعلومات الواردة في هذه الأحداث لتقديم ملاحظات ومطالبات تكميلية. سهولة الوصول
هما جزء من View
View.AccessibilityDelegate
الصفوف. في ما يلي الطريقتان:
dispatchPopulateAccessibilityEvent()
onPopulateAccessibilityEvent()
لهذا الملف الشخصي
ثم الطريقة dispatchPopulateAccessibilityEvent()
لكل فرع من هذه القيم
مشاهدة. onInitializeAccessibilityEvent()
TextView
أو
Button
، إلغاء هذه الطريقة
وضبط المعلومات الإضافية حول طريقة العرض، مثل نوع حقل كلمة المرور ومربّع الاختيار
أو حالات تقدم تفاعل المستخدم أو ملاحظات حول الحدث — باستخدام
. في حال تجاوز هذه الطريقة، يجب استدعاء تنفيذها المميّز وتعديل المواقع فقط
التي لا تحددها الفئة الفائقة.onInitializeAccessibilityNodeInfo()
View
التلقائية تتضمّن مجموعة عادية من خصائص الملف الشخصي، ولكن إذا كان
توفر طريقة العرض المخصصة تحكمًا تفاعليًا خارج نطاق TextView
أو
Button
، يمكنك إلغاء هذه الطريقة وضبط المعلومات الإضافية حول طريقة العرض
مع الكائن AccessibilityNodeInfo
الذي تتم معالجته بهذه الطريقة.onPopulateAccessibilityEvent()
AccessibilityEvent
في
مشاهدة. ويُطلق عليها أيضًا اسم طريقة العرض إذا كانت طريقة العرض تابعة لطريقة العرض التي تنشئ إمكانية وصول.
فعالية.
onRequestSendAccessibilityEvent()
AccessibilityEvent
تتيح هذه الخطوة لطريقة العرض الرئيسية تعديل إعدادات تسهيل الاستخدام.
الحدث مع معلومات إضافية. لا يتم تنفيذ هذه الطريقة إلا إذا كان من الممكن أن تشتمل طريقة العرض المخصّصة على
ما إذا كانت طريقة العرض تتيح للوالدَين توفير معلومات حول السياق
وهو حدث مفيد لخدمات إمكانية الوصول.sendAccessibilityEvent()
- يستدعي النظام هذه الطريقة عندما يتخذ أحد المستخدمين إجراءً بشأن إحدى المشاهدات. تم تصنيف الحدث كما يلي:
نوع إجراء المستخدم، مثل
TYPE_VIEW_CLICKED
. بوجه عام، يجب إرسالAccessibilityEvent
كلما تغيّر محتوى طريقة العرض المخصّصة. sendAccessibilityEventUnchecked()
- تُستخدم هذه الطريقة عندما يحتاج رمز الاتصال إلى التحكم مباشرةً في عملية التحقق من
تفعيل إمكانية الوصول على الجهاز
(
AccessibilityManager.isEnabled()
). إذا نفذت هذه الطريقة، فأجرِ الاتصال كما لو كانت إمكانية الوصول مُفعَّلة، بغض النظر عن إعداد النظام الأساسي. لا تحتاج عادةً إلى تنفيذ هذه الطريقة لطريقة عرض مخصّصة. dispatchPopulateAccessibilityEvent()
onInitializeAccessibilityEvent()
onInitializeAccessibilityNodeInfo()
onPopulateAccessibilityEvent()
TYPE_VIEW_CLICKED
TYPE_VIEW_FOCUSED
TYPE_VIEW_HOVER_ENTER
TYPE_VIEW_HOVER_EXIT
TYPE_VIEW_LONG_CLICKED
TYPE_VIEW_SCROLLED
- أنشئ قيمة
AccessibilityEvent
مناسبة لإجراء النقرة المفسَّر. - تفعيل خدمات تسهيل الاستخدام من أجل تنفيذ إجراء النقر المخصّص للمستخدمين غير القادرين على استخدام شاشة تعمل باللمس.
لدعم إمكانية الوصول، يجب إلغاء طرق الوصول السابقة وتنفيذها مباشرةً في فئة طريقة العرض المخصصة.
على الأقل، نفِّذ طرق تسهيل الاستخدام التالية لفئة طريقة العرض المخصّصة:
لمزيد من المعلومات حول تطبيق هذه الطرق، راجع القسم المتعلق تعبئة أحداث إمكانية الوصول.
إرسال أحداث تسهيل الاستخدام
بناءً على تفاصيل طريقة العرض المخصّصة، قد تحتاج إلى إرسال
AccessibilityEvent
عناصر في أوقات مختلفة أو للأحداث التي لا يتم التعامل معها تلقائيًا
التنفيذ. توفّر الفئة View
طريقة تنفيذ تلقائية لهذه الأحداث.
الأنواع:
بشكل عام، يجب إرسال AccessibilityEvent
عند توفر محتوى المساحة المخصصة
عرض التغييرات. على سبيل المثال، إذا كنت تنفذ شريط تمرير مخصصًا يتيح للمستخدم تحديد
قيمة رقمية عن طريق الضغط على مفتاح السهم المتّجه لليسار أو لليمين، فيجب أن تنبعث من طريقة العرض المخصّصة
TYPE_VIEW_TEXT_CHANGED
كلما تغيرت قيمة شريط التمرير. يوضح نموذج التعليمات البرمجية التالي استخدام
طريقة واحدة (sendAccessibilityEvent()
) للإبلاغ عن هذا الحدث.
Kotlin
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return when(keyCode) { KeyEvent.KEYCODE_DPAD_LEFT -> { currentValue-- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) true } ... } }
Java
@Override public boolean onKeyUp (int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { currentValue--; sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED); return true; } ... }
تعبئة أحداث تسهيل الاستخدام
ولكل AccessibilityEvent
مجموعة من السمات المطلوبة التي تصف السمة الحالية.
وضع العرض. وتشمل هذه الخصائص عناصر مثل اسم فئة العرض والمحتوى
والوصف والحالة المحددة. يتم توضيح السمات المحدّدة المطلوبة لكل نوع من الأحداث
في
AccessibilityEvent
الوثائق المرجعية.
توفّر عملية تنفيذ View
قيمًا تلقائية لهذه القيم
الخصائص المطلوبة. وتتوفر العديد من هذه القيم، بما في ذلك اسم الفئة والطابع الزمني للحدث،
يتم تقديمها تلقائيًا. إذا كنت تنشئ مكون عرض مخصص، فيجب تقديم معلومات
محتوى العرض وخصائصه. يمكن أن تكون هذه المعلومات بسيطة مثل زر
ويمكن أن يتضمن معلومات إضافية عن الحالة تريد إضافتها إلى الحدث.
يمكنك استخدام
onPopulateAccessibilityEvent()
أو
onInitializeAccessibilityEvent()
لملء المعلومات أو تعديلها في AccessibilityEvent
. يمكنك استخدام
طريقة onPopulateAccessibilityEvent()
خصيصًا لإضافة النص أو تعديله
محتوى الحدث، الذي يتحوّل إلى طلبات مسموعة من خلال خدمات تسهيل الاستخدام، مثل
TalkBack استخدام طريقة onInitializeAccessibilityEvent()
لتعبئة المزيد
معلومات عن الحدث، مثل حالة اختيار طريقة العرض.
بالإضافة إلى ذلك، نفِّذ
onInitializeAccessibilityNodeInfo()
. تستخدم خدمات تسهيل الاستخدام العناصر AccessibilityNodeInfo
التي تمت تعبئتها من خلال هذا العنصر
للتحقق من التسلسل الهرمي طرق العرض الذي ينشئ حدث إمكانية الوصول بعد تلقيه
وتقديم الملاحظات المناسبة للمستخدمين.
يوضح مثال الرمز التالي كيفية تجاوز هذه الطرق الثلاث في طريقة العرض:
Kotlin
override fun onPopulateAccessibilityEvent(event: AccessibilityEvent?) { super.onPopulateAccessibilityEvent(event) // Call the super implementation to populate its text for the // event. Then, add text not present in a super class. // You typically only need to add the text for the custom view. if (text?.isNotEmpty() == true) { event?.text?.add(text) } } override fun onInitializeAccessibilityEvent(event: AccessibilityEvent?) { super.onInitializeAccessibilityEvent(event) // Call the super implementation to let super classes // set appropriate event properties. Then, add the new checked // property that is not supported by a super class. event?.isChecked = isChecked() } override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo?) { super.onInitializeAccessibilityNodeInfo(info) // Call the super implementation to let super classes set // appropriate info properties. Then, add the checkable and checked // properties that are not supported by a super class. info?.isCheckable = true info?.isChecked = isChecked() // You typically only need to add the text for the custom view. if (text?.isNotEmpty() == true) { info?.text = text } }
Java
@Override public void onPopulateAccessibilityEvent(AccessibilityEvent event) { super.onPopulateAccessibilityEvent(event); // Call the super implementation to populate its text for the // event. Then, add the text not present in a super class. // You typically only need to add the text for the custom view. CharSequence text = getText(); if (!TextUtils.isEmpty(text)) { event.getText().add(text); } } @Override public void onInitializeAccessibilityEvent(AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); // Call the super implementation to let super classes // set appropriate event properties. Then, add the new checked // property that is not supported by a super class. event.setChecked(isChecked()); } @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); // Call the super implementation to let super classes set // appropriate info properties. Then, add the checkable and checked // properties that are not supported by a super class. info.setCheckable(true); info.setChecked(isChecked()); // You typically only need to add the text for the custom view. CharSequence text = getText(); if (!TextUtils.isEmpty(text)) { info.setText(text); } }
يمكنك تنفيذ هذه الطرق مباشرةً في فئة طريقة العرض المخصّصة.
توفير سياق مخصّص لتسهيل الاستخدام
يمكن لخدمات تسهيل الاستخدام فحص العرض الهرمي الذي يحتوي على مكوّن واجهة المستخدم الذي ينشئ حدث إمكانية الوصول. ويسمح هذا الإجراء لخدمات تسهيل الاستخدام بتوفير معلومات سياقية أكثر المعلومات لمساعدة المستخدمين.
هناك حالات لا يمكن فيها لخدمات تسهيل الاستخدام الحصول على معلومات كافية من العرض التسلسل الهرمي. ومن الأمثلة على ذلك عنصر تحكّم واجهة مخصّص يتضمّن عنصرَين أو أكثر بشكل منفصل. المناطق القابلة للنقر، مثل عنصر التحكم في التقويم. في هذه الحالة، يتعذر على الخدمات تقديم معلومات معلومات لأن الأقسام الفرعية القابلة للنقر ليست جزءًا من التسلسل الهرمي للعرض.
في المثال في الشكل 1، يتم تنفيذ التقويم بأكمله كطريقة عرض واحدة، وبالتالي عند تلقّي الخدمات معلومات كافية عن محتوى طريقة العرض واختيار المستخدم ضمن العرض ما لم يقدّم مطور البرامج معلومات إضافية. على سبيل المثال، إذا نقر أحد المستخدمين في اليوم الذي يحمل التصنيف 17، لن يتلقّى إطار عمل تسهيل الاستخدام إلا المعلومات الوصفية للتحكّم في التقويم بالكامل في هذه الحالة، تُعلن خدمة تسهيل الاستخدام TalkBack "التقويم" أو "تقويم أبريل" ولا يعرف المستخدم اليوم الذي يتم اختياره.
لتوفير معلومات سياقية كافية للخدمات المخصصة لتسهيل الاستخدام في مثل هذه الحالات، طريقة لتحديد العرض الهرمي لطريقة العرض الافتراضية. التدرج الهرمي لطريقة العرض الافتراضية لمطوّري التطبيقات بهدف توفير تسلسل هرمي تكميلي لخدمات تسهيل الاستخدام تتطابق بشكل وثيق مع المعلومات التي تظهر على الشاشة. وتتيح هذه الطريقة لخدمات تسهيل الاستخدام توفير المزيد من معلومات سياق مفيدة للمستخدمين.
هناك حالة أخرى قد تكون فيها الحاجة إلى تسلسل هرمي لطريقة العرض الافتراضية هي واجهة مستخدم تحتوي على
مجموعة من عناصر التحكم في View
التي تتضمن دوالاً وثيقة الصلة، حيث يؤدي الإجراء على أحد العناصر
يؤثر عنصر التحكم في محتويات عنصر واحد أو أكثر — مثل منتقي الأرقام الذي يتم فصله
وأسفل الشاشة. في هذه الحالة، لا يمكن لخدمات تسهيل الاستخدام الحصول على معلومات كافية بسبب
أحد الإجراءات على عنصر تحكم يؤدي إلى تغيير المحتوى في عنصر آخر، وقد لا تؤدي العلاقة بين عناصر التحكم هذه
بوضوح للخدمة.
للتعامل مع هذا الموقف، عليك تجميع عناصر التحكم ذات الصلة مع طريقة عرض شاملة وتوفير عنصر تحكم افتراضي العرض الهرمي من هذه الحاوية لتمثيل المعلومات والسلوك اللذين تقدمهما والتحكم المستمر.
لتوفير تسلسل هرمي لطريقة عرض افتراضية لأحد طرق العرض، يمكنك إلغاء
getAccessibilityNodeProvider()
في طريقة العرض المخصصة أو مجموعة طرق العرض المخصصة وعرض تنفيذ
AccessibilityNodeProvider
يمكنك تنفيذ عرض هرمي لطريقة العرض الافتراضية باستخدام "مكتبة الدعم" مع
ViewCompat.getAccessibilityNodeProvider()
وتقديم طريقة تنفيذ
AccessibilityNodeProviderCompat
لتبسيط مهمة تقديم المعلومات لخدمات إمكانية الوصول وإدارة
تركيز سهولة الوصول، يمكنك بدلاً من ذلك تنفيذ
ExploreByTouchHelper
وتوفر AccessibilityNodeProviderCompat
ويمكن إرفاقها كملف شخصي
AccessibilityDelegateCompat
عن طريق الاتصال
setAccessibilityDelegate
على سبيل المثال، راجع
ExploreByTouchHelperActivity
يتم استخدام ExploreByTouchHelper
أيضًا من خلال التطبيقات المصغّرة الخاصة بإطار العمل، مثل
CalendarView
، من خلال
عرض ملف الطفل
SimpleMonthView
التعامل مع أحداث اللمس المخصّصة
قد تتطلب عناصر التحكّم في العرض المخصّص سلوك حدث لمس غير عادي، كما هو موضّح في الأمثلة التالية.
تحديد الإجراءات المستندة إلى النقرات
إذا كان تطبيقك المصغّر يستخدم
OnClickListener
أو
OnLongClickListener
سيتعامل النظام مع
ACTION_CLICK
أو
ACTION_LONG_CLICK
إجراءات مناسبة لك. إذا كان تطبيقك يستخدم أداة أكثر تخصيصًا تعتمد على
OnTouchListener
تحديد معالجات مخصصة لإجراءات إمكانية الوصول المستندة إلى النقرات. لإجراء ذلك، اتصل بـ
replaceAccessibilityAction()
لكل إجراء، كما هو موضح في مقتطف الرمز التالي:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { ... // Assumes that the widget is designed to select text when tapped, and selects // all text when tapped and held. In its strings.xml file, this app sets // "select" to "Select" and "select_all" to "Select all". ViewCompat.replaceAccessibilityAction( binding.textSelectWidget, ACTION_CLICK, getString(R.string.select) ) { view, commandArguments -> selectText() } ViewCompat.replaceAccessibilityAction( binding.textSelectWidget, ACTION_LONG_CLICK, getString(R.string.select_all) ) { view, commandArguments -> selectAllText() } }
Java
@Override protected void onCreate(Bundle savedInstanceState) { ... // Assumes that the widget is designed to select text when tapped, and select // all text when tapped and held. In its strings.xml file, this app sets // "select" to "Select" and "select_all" to "Select all". ViewCompat.replaceAccessibilityAction( binding.textSelectWidget, ACTION_CLICK, getString(R.string.select), (view, commandArguments) -> selectText()); ViewCompat.replaceAccessibilityAction( binding.textSelectWidget, ACTION_LONG_CLICK, getString(R.string.select_all), (view, commandArguments) -> selectAllText()); }
إنشاء أحداث نقرات مخصّصة
يمكن لعنصر تحكّم مخصّص استخدام السمة onTouchEvent(MotionEvent)
المستمع لاكتشاف
ACTION_DOWN
و
هناك ACTION_UP
من الأحداث و
إلى تشغيل حدث نقرة خاصة. للحفاظ على التوافق مع خدمات سهولة الوصول،
فإن الرمز الذي
معالجة حدث النقر المخصّص هذا، يجب إجراء ما يلي:
للتعامل مع هذه المتطلبات بكفاءة، يجب أن تلغي الرمز البرمجي الخاص بك
طريقة واحدة (performClick()
)،
التي يجب عليها استدعاء التنفيذ الفائق لهذه الطريقة ثم تنفيذ أي إجراءات
الذي يتطلبه حدث النقر. عند اكتشاف إجراء النقر المخصّص، يجب أن يستدعي هذا الرمز عندئذٍ
طريقة performClick()
. يوضح مثال التعليمة البرمجية التالي هذا النمط.
Kotlin
class CustomTouchView(context: Context) : View(context) { var downTouch = false override fun onTouchEvent(event: MotionEvent): Boolean { super.onTouchEvent(event) // Listening for the down and up touch events. return when (event.action) { MotionEvent.ACTION_DOWN -> { downTouch = true true } MotionEvent.ACTION_UP -> if (downTouch) { downTouch = false performClick() // Call this method to handle the response and // enable accessibility services to // perform this action for a user who can't // tap the touchscreen. true } else { false } else -> false // Return false for other touch events. } } override fun performClick(): Boolean { // Calls the super implementation, which generates an AccessibilityEvent // and calls the onClick() listener on the view, if any. super.performClick() // Handle the action for the custom click here. return true } }
Java
class CustomTouchView extends View { public CustomTouchView(Context context) { super(context); } boolean downTouch = false; @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); // Listening for the down and up touch events switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downTouch = true; return true; case MotionEvent.ACTION_UP: if (downTouch) { downTouch = false; performClick(); // Call this method to handle the response and // enable accessibility services to // perform this action for a user who can't // tap the touchscreen. return true; } } return false; // Return false for other touch events. } @Override public boolean performClick() { // Calls the super implementation, which generates an AccessibilityEvent // and calls the onClick() listener on the view, if any. super.performClick(); // Handle the action for the custom click here. return true; } }
يساعد النمط السابق على ضمان توافق حدث النقر المخصّص مع تسهيل الاستخدام
باستخدام طريقة performClick()
لإنشاء حدث تسهيل الاستخدام
لتوفير نقطة دخول لخدمات تسهيل الاستخدام للتصرف نيابةً عن المستخدم الذي ينفذ
حدث النقر.