برای کمک به کاربرانی که نیازهای دسترسپذیری دارند، چارچوب Android به شما امکان میدهد سرویس دسترسپذیریای ایجاد کنید که بتواند محتوای برنامهها را به کاربران ارائه دهد و همچنین ازجانب آنها با برنامهها کار کند.
Android چندین سرویس دسترسپذیری سیستم ارائه میدهد، ازجمله:
- TalkBack: به افراد کمبینا یا نابینا کمک میکند. این برنامه محتوا را ازطریق صدای ترکیبی اعلام میکند و در پاسخ به اشارههای کاربر، کنشهایی را در برنامه انجام میدهد.
- دسترسی با کلید: به افراد دارای ناتوانی حرکتی کمک میکند. این کلاس عناصر تعاملی را برجسته میکند و در پاسخ به فشار دادن دکمه توسط کاربر، کنشهایی را انجام میدهد. این ویژگی امکان کنترل دستگاه را فقط بااستفاده از یک یا دو دکمه فراهم میکند.
برای کمک به افراد دارای نیازهای دسترسپذیری برای استفاده موفقیتآمیز از برنامهتان، برنامهتان باید از روالهای مطلوب شرحدادهشده در این صفحه پیروی کند که براساس دستورالعملهای شرحدادهشده در دسترسپذیرتر کردن برنامهها است.
هرکدام از این روالهای مطلوب که در بخشهای زیر شرح داده شدهاند میتوانند دسترسپذیری برنامهتان را بیشتر بهبود دهند:
- برچسبگذاری عناصر
- کاربران باید بتوانند محتوا و هدف هر عنصر میانای کاربر تعاملی و معنادار را در برنامهتان درک کنند.
- افزودن کنشهای دسترسپذیری
- با افزودن کنشهای دسترسپذیری، میتوانید به کاربران سرویسهای دسترسپذیری امکان دهید جریانهای کاربری مهم را در برنامهتان تکمیل کنند.
- استفاده از ویژگیهای دسترسپذیری داخلی
- Compose بهطور پیشفرض رفتارهای دسترسپذیری زیادی ارائه میدهد. از رفتارهای دسترسپذیری ازپیشتعریفشده استفاده کنید تا مؤلفههایتان را با کار اضافی کم یا بدون کار اضافی دسترسپذیر کنید. Compose همچنین روشهایی برای پشتیبانی از الزامات دسترسپذیری خاصتر که تحت پوشش ویژگیهای پیشفرض نیستند ارائه میدهد.
- استفاده کردن از نشانههایی غیراز رنگ
- کاربران باید بتوانند بهوضوح بین دستههای عناصر در واسط کاربر تمایز قائل شوند. برای انجام این کار، از الگوها و موقعیت، همراه با رنگ، برای بیان این تفاوتها استفاده کنید.
- دسترسپذیرتر کردن محتوای رسانهای
- به محتوای ویدیویی یا صوتی برنامهتان شرح اضافه کنید تا کاربرانی که از این محتوا استفاده میکنند مجبور نباشند کاملاً به نشانههای دیداری یا شنیداری متکی باشند.
عناصر برچسب
مهم است که برای هر عنصر تعاملی میانای کاربر در برنامهتان، برچسبهای مفید و توصیفی به کاربران ارائه دهید. هر برچسب باید معناشناسی عنصر خاصی را توضیح دهد—یعنی معنی و هدف عنصر. صفحهخوانهایی مثل TalkBack میتوانند این برچسبها را برای کاربران بخوانند.
در بیشتر موارد، Compose API و Material
پشتیبانی پیشفرض دسترسپذیری را در خود دارند. بااینحال، اگر لازم است ویژگیهای معنایی عنصر میانای کاربر را بهصورت دستی مشخص کنید، از اصلاحکننده semantics و ویژگی contentDescription استفاده کنید. برای اطلاعات بیشتر درباره معناشناسی، به
معناشناسی مراجعه کنید.
بخشهای زیر چند روش برچسبگذاری دیگر را شرح میدهند.
عناصر قابلویرایش
هنگام برچسبگذاری عناصر قابلویرایش، مانند فیلدهای نوشتاری، مفید است که نوشتاری را نشان دهید که نمونهای از ورودی معتبر در خود عنصر ارائه میدهد، علاوهبر اینکه این نوشتار نمونه را برای صفحهخوانها دردسترس قرار دهید. در این شرایط، میتوانید از نوشتار جایبان، که نوشتار راهنما نیز نامیده میشود، استفاده کنید.
در مثال زیر، TextField پارامتر placeholder دارد که
نوشتار راهنما ارائه میدهد.
val usernameState = rememberTextFieldState() TextField( state = usernameState, lineLimits = TextFieldLineLimits.SingleLine, placeholder = { Text("Enter Username") } )
همچنین معمول است که فیلد نوشتاری دارای برچسب توصیفی مربوطه باشد که آنچه را که کاربران باید بهعنوان ورودی وارد کنند توصیف میکند.
در مثال زیر، TextField دارای پارامتر label است که
شرح دسترسپذیری ارائه میدهد.
TextField( state = rememberTextFieldState(initialText = "Hello"), label = { Text("Label") } )
برای اطلاعات بیشتر درباره نوشتار و ورودی کاربر، به پیکربندی فیلدهای نوشتاری مراجعه کنید.
عناصر موجود در مجموعه
هنگام افزودن برچسب به عناصر مجموعه، هر برچسب باید یکتا باشد. بهاینترتیب، سرویسهای دسترسپذیری سیستم میتوانند هنگام اعلام برچسب دقیقاً به یک عنصر روی صفحه ارجاع دهند. این مطابقت به کاربران اطلاع میدهد که چه زمانی در واسط کاربر جابهجا میشوند یا چه زمانی تمرکز را به عنصری منتقل میکنند که قبلاً آن را پیدا کردهاند.
برای مثال، وقتی LazyColumn یا LazyRow دارید، از اصلاحکننده semantics برای اختصاص دادن collectionItemInfo یکتا به هر مورد استفاده کنید، همانطور که در قطعه کد زیر نشان داده شده است:
MilkyWayList( modifier = Modifier .semantics { collectionInfo = CollectionInfo( rowCount = milkyWay.count(), columnCount = 1 ) } ) { milkyWay.forEachIndexed { index, text -> Text( text = text, modifier = Modifier.semantics { collectionItemInfo = CollectionItemInfo(index, 0, 0, 0) } ) } }
برای اطلاعات بیشتر درباره ویژگیهای معنایی فهرستها و شبکهها، اطلاعات فهرست و مورد را ببینید.
گروههای محتوای مرتبط
اگر برنامهتان چندین عنصر میانای کاربر را نمایش میدهد که گروهی طبیعی را تشکیل میدهند، مثل
جزئیات آهنگ یا مشخصههای پیام، این عناصر را در یک
محفظه اصلی (مثل Column، Row، یا Box) مرتب کنید. از اصلاحکننده semantics محفظه اصلی
برای تنظیم mergeDescendants روی true استفاده کنید.
بهاینترتیب، سرویسهای دسترسپذیری میتوانند شرح محتوای عناصر داخلی را یکی پساز دیگری در یک اعلامیه ارائه دهند. ادغام کردن عناصر مرتبط به کاربران فناوری کمکی کمک میکند اطلاعات روی صفحه را بهطور مؤثرتری پیدا کنند.
در قطعه کد زیر، Row composable بهعنوان محفظه اصلی عمل میکند.
درون Row عناصر مرتبطی وجود دارد که فرادادههای پست وبلاگ را نشان میدهد—چهرک نویسنده، نام نویسنده، و زمان تخمینی خواندن.
تنظیم mergeDescendants روی true این عناصر داخلی را گروهبندی میکند، بنابراین
سرویسهای دسترسپذیری میتوانند آنها را بهعنوان یک واحد درنظر بگیرند.
@Composable private fun PostMetadata(metadata: Metadata) { // Merge elements below for accessibility purposes Row(modifier = Modifier.semantics(mergeDescendants = true) {}) { Image( imageVector = Icons.Filled.AccountCircle, contentDescription = null // decorative ) Column { Text(metadata.author.name) Text("${metadata.date} • ${metadata.readTimeMinutes} min read") } } }
هنگام گروهبندی عناصر مرتبط مانند مثال قبلی، فقط محفظه والد را تعاملی کنید. از افزودن اصلاحکنندههای clickable یا focusable
به عناصر فرزند داخلی خودداری کنید. درعوض، اصلاحکنندهها را روی Row یا Column ولی اعمال کنید.
ازآنجاییکه سرویسهای دسترسپذیری شرح عناصر داخلی را در یک عبارت واحد اعلام میکنند، مهم است که هر شرح را تا حد امکان کوتاه نگه دارید و درعینحال معنی عنصر را منتقل کنید.
توجه: بهطور کلی، هنگام ایجاد شرح محتوا برای یک گروه، از جمعآوری نوشتار فرزندان آن خودداری کنید. این کار باعث میشود شرح گروه شکننده شود و وقتی نوشتار فرزند تغییر میکند، شرح گروه ممکن است دیگر با نوشتار نمایان مطابقت نداشته باشد.
در بافت فهرست یا شبکه، صفحهخوان ممکن است نوشتار گرههای نوشتاری فرزند عنصر فهرست یا شبکه را ادغام کند. بهتر است از اصلاح این اعلامیه خودداری کنید.
برای اطلاعات بیشتر درباره ادغام کردن معناشناسی، به ادغام کردن و پاک کردن مراجعه کنید.
سرصفحهها در نوشتار
برخیاز برنامهها از عنوانها برای خلاصه کردن گروههای نوشتاری که در صفحه نشان داده میشود استفاده میکنند. اگر
عنصر خاصی نشاندهنده عنوان است، میتوانید هدف آن را
برای سرویسهای دسترسپذیری با تنظیم ویژگی heading در اصلاحکننده semantics
مشخص کنید.
@Composable private fun Subsection(text: String) { Text( text = text, style = MaterialTheme.typography.headlineSmall, modifier = Modifier.semantics { heading() } ) }
کاربران سرویسهای دسترسپذیری میتوانند بهجای پیمایش بین پاراگرافها یا کلمهها، بین عنوانها پیمایش کنند. این انعطافپذیری تجربه پیمایش نوشتار را بهبود میبخشد.
برای اطلاعات بیشتر درباره ویژگی معنایی heading، به عنوانها مراجعه کنید.
عنوانهای قاب دسترسپذیری
در Android 9 (سطح میانای برنامهسازی کاربردی ۲۸) و بالاتر، میتوانید عنوانهای مناسب دسترسپذیری برای قابهای صفحه ارائه دهید. برای اهداف دسترسپذیری، قاب بخشی از پنجره است که ازنظر بصری متمایز است.
برای اینکه سرویسهای دسترسپذیری بتوانند رفتار پنجرهمانند قاب را درک کنند، عنوانهای توصیفی به قابهای برنامهتان بدهید. سپس سرویسهای دسترسپذیری میتوانند اطلاعات دقیقتری را به کاربران ارائه دهند وقتی ظاهر یا محتوای قاب تغییر میکند.
ShareSheet( message = "Choose how to share this photo", modifier = Modifier .fillMaxWidth() .align(Alignment.TopCenter) .semantics { paneTitle = "New bottom sheet" } )
برای اطلاعات بیشتر درباره ویژگی معنایی paneTitle،
مؤلفههای پنجرهمانند را ببینید.
عناصر تزئینی
اگر عنصری در میانای کاربر شما فقط برای فاصلهگذاری دیداری یا اهداف ظاهر دیداری وجود دارد، ویژگیهای مناسب را روی عنصر تنظیم کنید تا نشان دهید سرویسهای دسترسپذیری میتوانند آن را نادیده بگیرند.
برای ترکیبپذیرهای Image یا Icon، contentDescription = null را تنظیم کنید. برای سایر
عناصر صرفاً تزئینی که هیچ بافت یا عملکردی ارائه نمیدهند، میتوانید
از hideFromAccessibility استفاده کنید. این ویژگی معنایی به سرویسهای دسترسپذیری میگوید
که این مورد را نادیده بگیرند.
اگر یک ترکیبپذیر تعاملی حاوی عناصر فرزند تزئینی و غیرتعاملی است، از clearAndSetSemantics استفاده کنید تا مطمئن شوید که سرویسهای دسترسپذیری آنها را پیمایش نمیکنند. توجه داشته باشید که clearAndSetSemantics معناشناسی پیشفرض یک عنصر و فرزندان آن را کاملاً پاک میکند. این کار به شما امکان میدهد عنصر دسترسپذیری جدید و یکپارچهای را تعریف کنید. معمولاً از این رویکرد برای مؤلفههای سفارشی پیچیده استفاده میکنید.
در مثال زیر، Icon و Text عناصر فرزند تزئینی
درون یک کلید سفارشی هستند. برای جلوگیری از پیمایش این فرزندان بهصورت جداگانه توسط سرویسهای دسترسپذیری، میتوانید معناشناسی آنها را بااستفاده از clearAndSetSemantics در Row والد پاک کنید. این به سرویسهای دسترسپذیری میگوید
که با کل Row بهعنوان کلید قابلپیمایش رفتار کنند:
// Developer might intend this to be a toggleable. // Using `clearAndSetSemantics`, on the Row, a clickable modifier is applied, // a custom description is set, and a Role is applied. @Composable fun FavoriteToggle() { val checked = remember { mutableStateOf(true) } Row( modifier = Modifier .toggleable( value = checked.value, onValueChange = { checked.value = it } ) .clearAndSetSemantics { stateDescription = if (checked.value) "Favorited" else "Not favorited" toggleableState = ToggleableState(checked.value) role = Role.Switch }, ) { Icon( imageVector = Icons.Default.Favorite, contentDescription = null // not needed here ) Text("Favorite?") } }
برای اطلاعات بیشتر درباره پاک کردن معناشناسی، به پاک کردن و تنظیم معناشناسی مراجعه کنید.
افزودن کنشهای دسترسپذیری
مهم است که مطمئن شوید کاربران سرویسهای دسترسپذیری راهی برای تکمیل همه جریانهای کاربر در برنامهتان دارند.
اگر تعامل ترکیبپذیر سفارشی شما وضعیت برنامه را بهگونهای تغییر میدهد که
واضح نیست، بااستفاده از پارامترهایی مثل onClickLabel یا onLongClickLabel در Modifier.clickable یا Modifier.combinedClickable، برچسبهای توصیفی برای کنشهای ضربه استاندارد ارائه دهید.
برای تعاملات پیچیدهای که نمیتوان آنها را به ضربههای استاندارد نگاشت کرد، از customActions استفاده کنید.
برای مثال، اگر برنامهتان به کاربران اجازه میدهد موردی را به مکان دیگری بکشند یا روی موردی در فهرست تند بکشند، میتوانید با قرار دادن این کنش دراختیار سرویسهای دسترسپذیری، روش جایگزینی برای تکمیل این جریانهای کاربر ارائه دهید. بهاینترتیب، کاربران TalkBack، دسترسی صوتی، یا «دسترسی با کلید» میتوانند کارهایی را انجام دهند که درغیراینصورت ممکن است فقط ازطریق اشارهها دردسترس باشد.
در Compose، میتوانید کنشهای دسترسپذیری سفارشی را ازطریق ویژگی
customActions در اصلاحکننده semantics بااستفاده از
CustomAccessibilityAction تعریف کنید.
برای مثال، اگر برنامهتان به کاربران اجازه میدهد برای بستن موردی روی آن تند بکشند، میتوانید این عملکرد را ازطریق کنش دسترسپذیری سفارشی نشان دهید:
SwipeToDismissBox( modifier = Modifier.semantics { // Represents the swipe to dismiss for accessibility customActions = listOf( CustomAccessibilityAction( label = "Remove article from list", action = { removeArticle() true } ) ) }, state = rememberSwipeToDismissBoxState(), backgroundContent = {} ) { ArticleListItem() }
با پیادهسازی کنش دسترسپذیری سفارشی، کاربران میتوانند ازطریق منو کنشها به کنش دسترسی پیدا کنند.
برای اطلاعات بیشتر درباره کنشهای سفارشی، به کنشهای سفارشی مراجعه کنید.
قابلفهم کردن کنشهای دردسترس
وقتی عنصر میانای کاربر از کنشهایی مثل لمس کردن و نگه داشتن پشتیبانی میکند، سرویس دسترسپذیریای مثل TalkBack آن را بهصورت «برای فشار طولانی، دوضربه بزنید و نگه دارید» اعلام میکند.
این اعلان عمومی هیچ زمینهای درباره عملکرد لمس کردن و نگه داشتن به کاربر ارائه نمیدهد.
برای اینکه این اعلامیه مفیدتر باشد، شرح معناداری برای این کنش مشخص کنید.
در Compose، اصلاحکنندههای تعامل استاندارد مانند clickable و
combinedClickable دارای پارامترهای داخلی (یعنی onClickLabel و
onLongClickLabel) هستند که میتوانید از آنها برای ارائه توضیحات برای کنشها استفاده کنید،
مانند مثال زیر:
var contextMenuPhotoId by rememberSaveable { mutableStateOf<Int?>(null) } val haptics = LocalHapticFeedback.current LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 128.dp)) { items(photos, { it.id }) { photo -> ImageItem( photo, Modifier .combinedClickable( onClick = { activePhotoId = photo.id }, onLongClick = { haptics.performHapticFeedback(HapticFeedbackType.LongPress) contextMenuPhotoId = photo.id }, onLongClickLabel = stringResource(R.string.open_context_menu) ) ) } } if (contextMenuPhotoId != null) { PhotoActionsSheet( photo = photos.first { it.id == contextMenuPhotoId }, onDismissSheet = { contextMenuPhotoId = null } ) }
این کار باعث میشود TalkBack «منوِ بافت را باز کنید» را اعلام کند، که به کاربران کمک میکند هدف کنش را درک کنند.
همچنین میتوانید برچسبی را مستقیماً در اصلاحکننده semantics مشخص کنید.
برای اطلاعات بیشتر درباره پاسخ دادن به تکضربها و کلیکها، تکضرب زدن و فشار دادن و عناصر تعاملی را ببینید.
استفاده از ویژگیهای دسترسپذیری داخلی
هنگام طراحی واسط کاربر برنامهتان، از ویژگیهای دسترسپذیری داخلی استفاده کنید تا از پیادهسازی مجدد عملکردهایی که قبلاً وجود داشتهاند اجتناب کنید. میاناهای برنامهسازی کاربردی Material، Compose UI، و Foundation بهطور پیشفرض بسیاری از روشهای دسترسپذیر را پیادهسازی و ارائه میکنند.
در Jetpack Compose، از composableهای داخلی مانند Button، Switch، و
Checkbox برای ایجاد میاناهای کاربر دسترسپذیر استفاده کنید. این مؤلفهها با اصلاحکنندههای semantics ازپیش بستهبندیشده، مثل role و stateDescription، ارائه میشوند که میتوانید از آنها برای دسترسپذیرتر کردن برنامههایتان استفاده کنید.
اعمال معناشناسی به مؤلفههای سفارشی
هنگام ایجاد مؤلفه سفارشی، به نوع پشتیبانی دسترسپذیری که این مؤلفه برای ایفای نقش خود نیاز دارد توجه کنید. اغلب،
میاناهای برنامهسازی کاربردی Compose استانداردی که ازقبل استفاده میکنید (مانند clickable، toggleable، یا
selectable) کافی هستند زیرا بهطور خودکار درخت معنایی را برای شما پر میکنند.
بااینحال، برخیاز مؤلفهها به اطلاعات خاصتری نسبتبه آنچه اصلاحکنندههای استاندارد ارائه میدهند نیاز دارند. در این موارد، بهدنبال اصلاحکنندههای تخصصی (مانند
triStateToggleable) بگردید یا اگر وجود نداشت، بهطور صریح معناشناسی را بااستفاده از
Modifier.semantics سطح پایین ارائه دهید.
برای مثال، TriStateSwitch را درنظر بگیرید، کلیدی با سه حالت (روشن،
خاموش، و نامشخص).
درحالیکه یک اصلاحکننده استاندارد toggleable دو حالت را فرض میکند،
اصلاحکننده triStateToggleable پیچیدگی حالت سوم را مدیریت میکند. این ویژگی بهطور خودکار Role (Switch) و State دسترسپذیری را تنظیم میکند. بهاینترتیب،
سرویسهای دسترسپذیری اطلاعات دقیقی دریافت میکنند و نیازی نیست
معناشناسی را بهطور دستی تعریف کنید.
تکهکد زیر TriStateSwitch را بااستفاده از این رویکرد نشان میدهد:
@Composable fun TriStateSwitch( state: ToggleableState, onClick: () -> Unit, modifier: Modifier = Modifier ) { // A real implementation would include custom drawing for the switch. // This example uses a Box to demonstrate the semantics. Box( modifier = modifier .size(width = 64.dp, height = 40.dp) // triStateToggleable handles the semantics (Role and State) // automatically, so explicit Modifier.semantics is not needed here. .triStateToggleable( state = state, onClick = onClick, role = Role.Switch ) // Add visual feedback based on the state .background( when (state) { ToggleableState.On -> Color.Green ToggleableState.Off -> Color.Gray ToggleableState.Indeterminate -> Color.Yellow } ) ) } // Usage within another composable: var state by remember { mutableStateOf(ToggleableState.Off) } TriStateSwitch( state = state, onClick = { state = when (state) { ToggleableState.Off -> ToggleableState.Indeterminate ToggleableState.Indeterminate -> ToggleableState.On ToggleableState.On -> ToggleableState.Off } } )
هنگام ساختن مؤلفه سفارشی، مطمئن شوید که همه ویژگیهای معنایی مربوطه را برای اهداف دسترسپذیری ارائه میدهید. برای مثال، اگر مؤلفه شما از یک کنترل استاندارد مانند کلید یا دکمه تقلید میکند، این ویژگیها شامل نقش مؤلفه (مانند Role.Switch یا Role.Button)، stateDescription (مانند «روشن»، «خاموش»، «علامتگذاریشده»، یا «علامتگذارینشده»)، و هر برچسب کنش مرتبطی میشود. برای اطلاعات بیشتر، به مؤلفههای سفارشی مراجعه کنید.
استفاده از نشانههایی غیراز رنگ
برای کمک به کاربران مبتلا به کوررنگی، از نشانههایی غیراز رنگ برای تشخیص عناصر میانای کاربر در صفحههای برنامهتان استفاده کنید. این تکنیکها میتواند شامل استفاده از شکلها یا اندازههای مختلف، ارائه الگوهای نوشتاری یا دیداری، یا افزودن بازخورد صوتی یا لمسی (لامسهای) برای علامتگذاری تفاوتهای عناصر باشد.
شکل ۱ دو نسخه از یک فعالیت را نشان میدهد. یک نسخه فقط از رنگ برای تمایز بین دو کنش احتمالی در گردش کار استفاده میکند. نسخه دیگر از روال مطلوب گنجاندن شکل و نوشتار علاوهبر رنگ برای برجسته کردن تفاوتهای بین دو گزینه استفاده میکند:
محتوای رسانهای را دسترسپذیرتر کنید
اگر درحال توسعه برنامهای هستید که شامل محتوای رسانهای، مانند کلیپ ویدیویی یا ضبط صدا است، سعی کنید به کاربرانی که انواع مختلفی از نیازهای دسترسپذیری دارند کمک کنید تا مطالب را درک کنند. بهطور خاص، سعی کنید کارهای زیر را انجام دهید:
- کنترلهایی را اضافه کنید که به کاربران اجازه میدهد رسانه را موقتاً متوقف یا متوقف کنند، میزان صدا را تغییر دهند، و زیرنویس (زیرنویس ناشنوایان) را روشن/خاموش کنند.
- اگر ویدیویی اطلاعاتی را ارائه میدهد که برای تکمیل گردش کار حیاتی است، همان محتوا را در قالب جایگزین، مانند ترانویسی، ارائه دهید.
منابع بیشتر
برای اطلاعات بیشتر درباره دسترسپذیرتر کردن برنامهتان، منابع تکمیلی زیر را ببینید: