برای کمک به کاربران با نیازهای دسترسپذیری، چارچوب Android به شما امکان میدهد یک سرویس دسترسپذیری ایجاد کنید که میتواند محتوا را از برنامهها به کاربران ارائه کند و همچنین برنامهها را از طرف آنها اجرا کند.
Android چندین سرویس دسترسی به سیستم را ارائه می دهد، از جمله موارد زیر:
- TalkBack : به افرادی که بینایی ضعیفی دارند یا نابینا هستند کمک می کند. این برنامه محتوا را از طریق صدای ترکیبی اعلام می کند و در پاسخ به حرکات کاربر اقداماتی را روی یک برنامه انجام می دهد.
- دسترسی سوئیچ : به افرادی که دارای معلولیت حرکتی هستند کمک می کند. عناصر تعاملی را برجسته می کند و اقداماتی را در پاسخ به فشار دادن دکمه توسط کاربر انجام می دهد. این امکان را برای کنترل دستگاه تنها با استفاده از یک یا دو دکمه فراهم می کند.
برای کمک به افرادی که نیازهای دسترسپذیری دارند از برنامه شما با موفقیت استفاده کنند، برنامه شما باید از بهترین شیوههای شرحدادهشده در این صفحه پیروی کند که بر اساس دستورالعملهای توضیحدادهشده در دسترسی بیشتر برنامهها است .
هر یک از این بهترین شیوهها که در بخشهای بعدی توضیح داده شدهاند، میتوانند دسترسی برنامه شما را بیشتر بهبود بخشند:
- عناصر برچسب
- کاربران باید بتوانند محتوا و هدف هر عنصر رابط کاربری تعاملی و معنادار در برنامه شما را درک کنند.
- اقدامات دسترسپذیری را اضافه کنید
- با افزودن کنشهای دسترسپذیری، میتوانید کاربران سرویسهای دسترسپذیری را فعال کنید تا جریانهای کاربر حیاتی را در برنامه شما تکمیل کنند.
- ویجت های سیستم را گسترش دهید
- به جای ایجاد نماهای سفارشی خود، بر روی عناصر view که چارچوب شامل می شود، بسازید. نمای چارچوب و کلاسهای ویجت در حال حاضر بیشتر قابلیتهای دسترسپذیری مورد نیاز برنامه شما را ارائه میکنند.
- از نشانه هایی غیر از رنگ استفاده کنید
- کاربران باید بتوانند به وضوح بین دسته بندی عناصر در یک رابط کاربری تمایز قائل شوند. برای این کار از الگوها و موقعیت به همراه رنگ برای بیان این تفاوت ها استفاده کنید.
- محتوای رسانه ای را در دسترس تر کنید
- توضیحاتی را به محتوای ویدیویی یا صوتی برنامه خود اضافه کنید تا کاربرانی که این محتوا را مصرف می کنند نیازی به تکیه کامل به نشانه های دیداری یا شنیداری نداشته باشند.
عناصر برچسب
مهم است که برچسبهای مفید و توصیفی را برای هر عنصر رابط کاربری تعاملی در برنامه خود در اختیار کاربران قرار دهید. هر برچسب باید معنی و هدف یک عنصر خاص را توضیح دهد. صفحهخوانهایی مانند TalkBack میتوانند این برچسبها را به کاربران اعلام کنند.
در بیشتر موارد، توضیحات یک عنصر UI را در فایل منبع طرحبندی که حاوی عنصر است، مشخص میکنید. معمولاً، همانطور که در راهنمای در دسترستر کردن برنامهها توضیح داده شده است، برچسبها را با استفاده از ویژگی contentDescription
اضافه میکنید. چندین تکنیک برچسب گذاری دیگر نیز در بخش های زیر توضیح داده شده است.
عناصر قابل ویرایش
هنگام برچسبگذاری عناصر قابل ویرایش، مانند اشیاء EditText
، نشان دادن متنی که نمونهای از ورودی معتبر را در خود عنصر ارائه میدهد، مفید است، علاوه بر این که این متن نمونه در دسترس خوانندگان صفحه نمایش قرار میگیرد. در این مواقع، همانطور که در قطعه زیر نشان داده شده است، می توانید از ویژگی android:hint
استفاده کنید:
<!-- The hint text for en-US locale would be "Apartment, suite, or building". --> <EditText android:id="@+id/addressLine2" android:hint="@string/aptSuiteBuilding" ... />
در این شرایط، شی View
باید ویژگی android:labelFor
خود را روی شناسه عنصر EditText
تنظیم کند. برای جزئیات بیشتر به بخش زیر مراجعه کنید.
جفت عناصری که یکی دیگری را توصیف می کند
معمول است که یک عنصر EditText
یک شی View
متناظر داشته باشد که توصیف می کند کاربران باید چه چیزی را در عنصر EditText
وارد کنند. می توانید این رابطه را با تنظیم ویژگی android:labelFor
شیء View
نشان دهید.
نمونه ای از برچسب زدن چنین جفت عناصر در قطعه زیر ظاهر می شود:
<!-- Label text for en-US locale would be "Username:" --> <TextView android:id="@+id/usernameLabel" ... android:text="@string/username" android:labelFor="@+id/usernameEntry" /> <EditText android:id="@+id/usernameEntry" ... /> <!-- Label text for en-US locale would be "Password:" --> <TextView android:id="@+id/passwordLabel" ... android:text="@string/password android:labelFor="@+id/passwordEntry" /> <EditText android:id="@+id/passwordEntry" android:inputType="textPassword" ... />
عناصر در یک مجموعه
هنگام افزودن برچسب به عناصر یک مجموعه، هر برچسب باید منحصر به فرد باشد. به این ترتیب، سرویسهای دسترسی سیستم میتوانند در هنگام اعلام برچسب دقیقاً به یک عنصر روی صفحه اشاره کنند. این مکاتبات به کاربران این امکان را می دهد که بدانند چه زمانی در UI چرخه می زنند یا چه زمانی تمرکز را به عنصری که قبلاً کشف کرده اند منتقل می کنند.
به طور خاص، متن اضافی یا اطلاعات متنی را در عناصر موجود در طرحبندیهای مورد استفاده مجدد - مانند اشیاء RecyclerView
- بگنجانید تا هر عنصر فرزند بهطور منحصربهفرد شناسایی شود.
برای انجام این کار، شرح محتوا را به عنوان بخشی از اجرای آداپتور خود تنظیم کنید، همانطور که در قطعه کد زیر نشان داده شده است:
کاتلین
data class MovieRating(val title: String, val starRating: Integer) class MyMovieRatingsAdapter(private val myData: Array<MovieRating>): RecyclerView.Adapter<MyMovieRatingsAdapter.MyRatingViewHolder>() { class MyRatingViewHolder(val ratingView: ImageView) : RecyclerView.ViewHolder(ratingView) override fun onBindViewHolder(holder: MyRatingViewHolder, position: Int) { val ratingData = myData[position] holder.ratingView.contentDescription = "Movie ${position}: " + "${ratingData.title}, ${ratingData.starRating} stars" } }
جاوا
public class MovieRating { private String title; private int starRating; // ... public String getTitle() { return title; } public int getStarRating() { return starRating; } } public class MyMovieRatingsAdapter extends RecyclerView.Adapter<MyAdapter.MyRatingViewHolder> { private MovieRating[] myData; public static class MyRatingViewHolder extends RecyclerView.ViewHolder { public ImageView ratingView; public MyRatingViewHolder(ImageView iv) { super(iv); ratingView = iv; } } @Override public void onBindViewHolder(MyRatingViewHolder holder, int position) { MovieRating ratingData = myData[position]; holder.ratingView.setContentDescription("Movie " + position + ": " + ratingData.getTitle() + ", " + ratingData.getStarRating() + " stars") } }
گروه های محتوای مرتبط
اگر برنامه شما چندین عنصر رابط کاربری را نشان میدهد که یک گروه طبیعی را تشکیل میدهند، مانند جزئیات یک آهنگ یا ویژگیهای یک پیام، این عناصر را در یک ظرف مرتب کنید که معمولاً زیر کلاس ViewGroup
است. ویژگی android:screenReaderFocusable
شی ظرف را روی true
و ویژگی android:focusable
هر شیء داخلی را روی false
تنظیم کنید. به این ترتیب، سرویسهای دسترسی میتوانند توضیحات محتوای عناصر درونی را یکی پس از دیگری در یک اعلامیه ارائه دهند. این ادغام عناصر مرتبط به کاربران فناوری کمکی کمک می کند تا اطلاعات روی صفحه را به طور موثرتری کشف کنند.
قطعه زیر حاوی تکههایی از محتوا است که به یکدیگر مربوط میشوند، بنابراین عنصر کانتینر، نمونهای از ConstraintLayout
، دارای android:screenReaderFocusable
است که روی true
تنظیم شده است و عناصر TextView
داخلی هر کدام دارای ویژگی android:focusable
که روی false
تنظیم شدهاند:
<!-- In response to a single user interaction, accessibility services announce both the title and the artist of the song. --> <ConstraintLayout android:id="@+id/song_data_container" ... android:screenReaderFocusable="true"> <TextView android:id="@+id/song_title" ... android:focusable="false" android:text="@string/my_song_title" /> <TextView android:id="@+id/song_artist" android:focusable="false" android:text="@string/my_songwriter" /> </ConstraintLayout>
از آنجایی که سرویسهای دسترسپذیری توصیفات عناصر درونی را در یک گفتار اعلام میکنند، مهم است که هر توضیحی را تا حد امکان کوتاه نگه دارید و در عین حال معنای عنصر را منتقل کنید.
توجه: به طور کلی، باید از ایجاد توضیحات محتوایی برای یک گروه با تجمیع متن فرزندان آن اجتناب کنید. انجام این کار باعث می شود توضیحات گروه شکننده باشد و وقتی متن فرزند تغییر می کند، ممکن است توضیحات گروه دیگر با متن قابل مشاهده مطابقت نداشته باشد.
در یک فهرست یا یک زمینه شبکه، یک صفحهخوان ممکن است متن یک فهرست یا گرههای متنی عنصر شبکه را ادغام کند. بهتر است از اصلاح این اطلاعیه خودداری کنید.
گروه های تو در تو
اگر رابط برنامه شما اطلاعات چند بعدی را ارائه می دهد، مانند لیست روزانه رویدادهای جشنواره، از ویژگی android:screenReaderFocusable
در کانتینرهای گروه داخلی استفاده کنید. این طرح برچسبگذاری تعادل خوبی بین تعداد اعلانهای مورد نیاز برای کشف محتوای صفحه و طول هر اعلامیه فراهم میکند.
قطعه کد زیر یک روش برای برچسب زدن گروه ها در داخل گروه های بزرگتر را نشان می دهد:
<!-- In response to a single user interaction, accessibility services announce the events for a single stage only. --> <ConstraintLayout android:id="@+id/festival_event_table" ... > <ConstraintLayout android:id="@+id/stage_a_event_column" android:screenReaderFocusable="true"> <!-- UI elements that describe the events on Stage A. --> </ConstraintLayout> <ConstraintLayout android:id="@+id/stage_b_event_column" android:screenReaderFocusable="true"> <!-- UI elements that describe the events on Stage B. --> </ConstraintLayout> </ConstraintLayout>
عنوان در متن
برخی از برنامه ها از عناوین برای خلاصه کردن گروه های متنی که روی صفحه نمایش ظاهر می شوند استفاده می کنند. اگر یک عنصر View
خاص یک عنوان را نشان میدهد، میتوانید با تنظیم ویژگی android:accessibilityHeading
عنصر، هدف آن را برای خدمات دسترسپذیری true
کنید.
کاربران خدمات دسترسپذیری میتوانند به جای بین پاراگرافها یا بین کلمات، بین سرفصلها پیمایش کنند. این انعطافپذیری تجربه ناوبری متن را بهبود میبخشد.
عناوین قاب دسترسی
در Android 9 (سطح API 28) و بالاتر، میتوانید عناوین سازگار با قابلیت دسترسی را برای صفحههای صفحه ارائه کنید. برای اهداف دسترسپذیری، یک صفحه یک بخش بصری مجزا از یک پنجره است، مانند محتوای یک قطعه. برای اینکه سرویسهای دسترسپذیری رفتار پنجرهمانند یک صفحه را درک کنند، عناوین توصیفی را به پنجرههای برنامه خود بدهید. هنگامی که ظاهر یا محتوای یک صفحه تغییر می کند، سرویس های دسترسی می توانند اطلاعات دقیق تری را به کاربران ارائه دهند.
برای تعیین عنوان یک صفحه، از ویژگی android:accessibilityPaneTitle
استفاده کنید، همانطور که در قطعه زیر نشان داده شده است:
<!-- Accessibility services receive announcements about content changes that are scoped to either the "shopping cart view" section (top) or "browse items" section (bottom) --> <MyShoppingCartView android:id="@+id/shoppingCartContainer" android:accessibilityPaneTitle="@string/shoppingCart" ... /> <MyShoppingBrowseView android:id="@+id/browseItemsContainer" android:accessibilityPaneTitle="@string/browseProducts" ... />
عناصر تزئینی
اگر عنصری در رابط کاربری شما فقط برای فاصله بصری یا اهداف ظاهری بصری وجود دارد، ویژگی android:importantForAccessibility
آن را روی "no"
تنظیم کنید.
اقدامات دسترسپذیری را اضافه کنید
مهم است که به کاربران سرویسهای دسترسپذیری اجازه دهید به راحتی همه جریانهای کاربر را در برنامه شما انجام دهند. به عنوان مثال، اگر کاربر بتواند روی یک مورد در فهرست انگشت خود را بکشد، این عمل میتواند در معرض سرویسهای دسترسپذیری نیز قرار گیرد تا کاربران یک راه جایگزین برای تکمیل جریان کاربر مشابه داشته باشند.
همه اقدامات را در دسترس قرار دهید
ممکن است کاربر TalkBack، Voice Access یا Switch Access به روشهای جایگزینی برای تکمیل جریانهای کاربر خاص در برنامه نیاز داشته باشد. برای اقدامات مرتبط با حرکات مانند کشیدن و رها کردن یا کشیدن انگشت، برنامه شما میتواند عملکردها را به گونهای نمایش دهد که برای کاربران سرویسهای دسترسپذیری قابل دسترسی باشد.
با استفاده از کنشهای دسترسپذیری ، برنامه میتواند راههای جایگزینی برای تکمیل یک اقدام برای کاربران فراهم کند.
به عنوان مثال، اگر برنامه شما به کاربران اجازه میدهد تا روی یک مورد تند بکشند، میتوانید عملکرد را از طریق یک عملکرد دسترسی سفارشی، مانند این، نشان دهید:
کاتلین
ViewCompat.addAccessibilityAction( // View to add accessibility action itemView, // Label surfaced to user by an accessibility service getText(R.id.archive) ) { _, _ -> // Same method executed when swiping on itemView archiveItem() true }
جاوا
ViewCompat.addAccessibilityAction( // View to add accessibility action itemView, // Label surfaced to user by an accessibility service getText(R.id.archive), (view, arguments) -> { // Same method executed when swiping on itemView archiveItem(); return true; } );
With the custom accessibility action implemented, users can access the action through the actions menu.
Make available actions understandable
When a view supports actions such as touch & hold, an accessibility service such as TalkBack announces it as "Double tap and hold to long press."
This generic announcement doesn't give the user any context about what a touch & hold action does.
To make this announcement more descriptive, you can replace the accessibility action’s announcement like so:
Kotlin
ViewCompat.replaceAccessibilityAction( // View that contains touch & hold action itemView, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_LONG_CLICK, // Announcement read by TalkBack to surface this action getText(R.string.favorite), null )
جاوا
ViewCompat.replaceAccessibilityAction( // View that contains touch & hold action itemView, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_LONG_CLICK, // Announcement read by TalkBack to surface this action getText(R.string.favorite), null );
This results in TalkBack announcing "Double tap and hold to favorite," helping users understand the purpose of the action.
Extend system widgets
Note: When you design your app's UI, use or extend
system-provided widgets that are as far down Android's class hierarchy as
possible. System-provided widgets that are far down the hierarchy already
have most of the accessibility capabilities your app needs. It's easier
to extend these system-provided widgets than to create your own from the more
generic View
,
ViewCompat
,
Canvas
, and
CanvasCompat
classes.
If you must extend View
or Canvas
directly, which
might be necessary for a highly customized experience or a game level, see
Make custom views more
accessible.
This section uses the example of implementing a special type of
Switch
called TriSwitch
while following
best practices around extending system widgets. A TriSwitch
object works similarly to a Switch
object, except that each instance of
TriSwitch
allows the user to toggle among three possible states.
Extend from far down the class hierarchy
The Switch
object inherits from several framework UI classes in its hierarchy:
View ↳ TextView ↳ Button ↳ CompoundButton ↳ Switch
بهتر است کلاس جدید TriSwitch
مستقیماً از کلاس Switch
گسترش یابد. به این ترتیب، چارچوب دسترسپذیری اندروید بیشتر قابلیتهای دسترسی مورد نیاز کلاس TriSwitch
را فراهم میکند:
- اقدامات دسترسپذیری: اطلاعاتی برای سیستم در مورد اینکه چگونه سرویسهای دسترسی میتوانند هر ورودی احتمالی کاربر را که روی یک شی
TriSwitch
انجام میشود شبیهسازی کنند. (به ارث رسیده ازView
.) - رویدادهای دسترسپذیری: اطلاعاتی برای سرویسهای دسترسپذیری درباره هر راه ممکنی که ظاهر یک شی
TriSwitch
میتواند در هنگام تازهسازی یا بهروزرسانی صفحه تغییر کند. (به ارث رسیده ازView
.) - ویژگی ها: جزئیات مربوط به هر شی
TriSwitch
، مانند محتوای هر متنی که نمایش می دهد. (به ارث رسیده ازTextView
.) - اطلاعات وضعیت: شرح وضعیت فعلی یک شی
TriSwitch
، مانند "تیک خورده" یا "برگزیده نشده". (به ارث رسیده ازCompoundButton
.) - شرح متنی حالت: توضیحی مبتنی بر متن از آنچه هر حالت نشان می دهد. (به ارث رسیده از
Switch
.)
این رفتار از Switch
و سوپرکلاس های آن تقریباً همان رفتار اشیاء TriSwitch
است. بنابراین، اجرای شما می تواند بر گسترش تعداد حالت های ممکن از دو به سه تمرکز کند.
تعریف رویدادهای سفارشی
هنگامی که ویجت سیستم را گسترش می دهید، احتمالاً جنبه ای از نحوه تعامل کاربران با آن ویجت را تغییر می دهید. بسیار مهم است که این تغییرات تعاملی را تعریف کنید تا سرویسهای دسترسپذیری بتوانند ویجت برنامه شما را بهروزرسانی کنند، گویی کاربر مستقیماً با ویجت تعامل دارد.
یک دستورالعمل کلی این است که برای هر بازخوانی مبتنی بر view که لغو میکنید، همچنین باید با نادیده گرفتن ViewCompat.replaceAccessibilityAction()
، عملکرد دسترسی مربوطه را دوباره تعریف کنید. در آزمایشهای برنامهتان، میتوانید با فراخوانی ViewCompat.performAccessibilityAction()
رفتار این اقدامات بازتعریف شده را تأیید کنید.
چگونه این اصل می تواند برای اشیاء TriSwitch کار کند
بر خلاف یک شی Switch
معمولی، ضربه زدن روی یک شی TriSwitch
در سه حالت ممکن چرخه میشود. بنابراین، عملکرد دسترسی ACTION_CLICK
مربوطه باید بهروزرسانی شود:
کاتلین
class TriSwitch(context: Context) : Switch(context) { // 0, 1, or 2 var currentState: Int = 0 private set init { updateAccessibilityActions() } private fun updateAccessibilityActions() { ViewCompat.replaceAccessibilityAction(this, ACTION_CLICK, action-label) { view, args -> moveToNextState() }) } private fun moveToNextState() { currentState = (currentState + 1) % 3 } }
جاوا
public class TriSwitch extends Switch { // 0, 1, or 2 private int currentState; public int getCurrentState() { return currentState; } public TriSwitch() { updateAccessibilityActions(); } private void updateAccessibilityActions() { ViewCompat.replaceAccessibilityAction(this, ACTION_CLICK, action-label, (view, args) -> moveToNextState()); } private void moveToNextState() { currentState = (currentState + 1) % 3; } }
از نشانه هایی غیر از رنگ استفاده کنید
برای کمک به کاربران با کمبود دید رنگی، از نشانه هایی غیر از رنگ برای تشخیص عناصر UI در صفحه نمایش برنامه خود استفاده کنید. این تکنیکها میتواند شامل استفاده از اشکال یا اندازههای مختلف، ارائه الگوهای متنی یا بصری، یا افزودن بازخورد صوتی یا لمسی (هپتیک) برای مشخص کردن تفاوتهای عناصر باشد.
شکل 1 دو نسخه از یک فعالیت را نشان می دهد. یک نسخه فقط از رنگ برای تمایز بین دو عمل ممکن در یک گردش کار استفاده می کند. نسخه دیگر از بهترین تمرین شامل اشکال و متن علاوه بر رنگ برای برجسته کردن تفاوتهای بین دو گزینه استفاده میکند:
محتوای رسانه ای را در دسترس تر کنید
اگر در حال توسعه برنامهای هستید که حاوی محتوای رسانهای است، مانند یک کلیپ ویدیویی یا ضبط صدا، سعی کنید از کاربرانی که انواع مختلف نیازهای دسترسی دارند در درک این مطالب پشتیبانی کنید. به ویژه، ما شما را به انجام موارد زیر تشویق می کنیم:
- شامل کنترلهایی باشد که به کاربران اجازه میدهد رسانه را متوقف یا متوقف کنند، صدا را تغییر دهند و زیرنویسها را تغییر دهند.
- اگر یک ویدیو اطلاعاتی را ارائه میکند که برای تکمیل یک گردش کار حیاتی است، همان محتوا را در قالبی جایگزین، مانند رونوشت، ارائه دهید.
منابع اضافی
برای کسب اطلاعات بیشتر در مورد دسترسی بیشتر برنامه خود، به منابع اضافی زیر مراجعه کنید: