لمساعدة الأشخاص الذين يعانون من احتياجات إمكانية الوصول على استخدام تطبيقك بنجاح، قم بتصميم تطبيقك لتلبية المتطلبات الرئيسية لإمكانية الوصول.
مراعاة الحدّ الأدنى لأحجام مساحات اللمس
إنّ أي عنصر على الشاشة يمكن لشخص ما النقر عليه أو لمسه أو التفاعل معه يجب أن يكون كبيرًا بما يكفي للتفاعل الموثوق به. عند تحديد حجم هذه العناصر، احرص على ضبط الحدّ الأدنى للحجم على 48 بكسل مستقل الكثافة لاتّباع إرشادات تسهيل الاستخدام ذات التصميم المتعدد الأبعاد بشكل صحيح.
يمكنك ضبط الحد الأدنى للحجم داخليًا في مكوّنات التصميم المتعدد الأبعاد، مثل Checkbox
وRadioButton
وSwitch
Slider
وSurface
. على سبيل المثال، عندما يتم ضبط معلَمة onCheckedChange
الخاصة بـ Checkbox
على قيمة غير فارغة، يتضمّن مربّع الاختيار مساحة متروكة ليكون العرض والارتفاع 48 وحدة بكسل مستقلة الكثافة (dp) على الأقل.
@Composable private fun CheckableCheckbox() { Checkbox(checked = true, onCheckedChange = {}) }
عند ضبط المعلَمة onCheckedChange
على قيمة فارغة، لا يتم تضمين المساحة المتروكة لأنّه لا يمكن التفاعل مع المكوِّن مباشرةً.
@Composable private fun NonClickableCheckbox() { Checkbox(checked = true, onCheckedChange = null) }
عند تنفيذ عناصر التحكّم في الاختيار، مثل Switch
أو RadioButton
أو
Checkbox
، عادةً ما تُرفع السلوك القابل للنقر إلى حاوية رئيسية، وتضبط معاودة الاتصال للنقرات على العنصر القابل للإنشاء على null
، وتضيف عنصر تعديل toggleable
أو selectable
إلى العنصر الرئيسي القابل للإنشاء.
@Composable private fun CheckableRow() { MaterialTheme { var checked by remember { mutableStateOf(false) } Row( Modifier .toggleable( value = checked, role = Role.Checkbox, onValueChange = { checked = !checked } ) .padding(16.dp) .fillMaxWidth() ) { Text("Option", Modifier.weight(1f)) Checkbox(checked = checked, onCheckedChange = null) } } }
عندما يكون حجم الجزء القابل للإنشاء القابل للنقر أصغر من الحد الأدنى لحجم ناحية اللمس المستهدفة، سيستمر تطبيق Compose في زيادة حجم مساحة اللمس. ويتم ذلك من خلال توسيع حجم مساحة اللمس المستهدفة خارج حدود العنصر القابل للإنشاء.
يحتوي المثال التالي على رمز Box
صغير جدًا قابل للنقر. يتم تلقائيًا توسيع منطقة اللمس المستهدفة خارج حدود Box
، لذلك سيؤدي النقر بجانب Box
إلى تشغيل حدث النقر.
@Composable private fun SmallBox() { var clicked by remember { mutableStateOf(false) } Box( Modifier .size(100.dp) .background(if (clicked) Color.DarkGray else Color.LightGray) ) { Box( Modifier .align(Alignment.Center) .clickable { clicked = !clicked } .background(Color.Black) .size(1.dp) ) } }
لمنع التداخل المحتمل بين مناطق اللمس في عناصر مختلفة للإنشاء،
استخدِم دائمًا حدًا أدنى كبيرًا بما يكفي لحجم العنصر القابل للإنشاء. في المثال، يعني ذلك استخدام
أداة التعديل sizeIn
لضبط الحدّ الأدنى لحجم المربّع الداخلي:
@Composable private fun LargeBox() { var clicked by remember { mutableStateOf(false) } Box( Modifier .size(100.dp) .background(if (clicked) Color.DarkGray else Color.LightGray) ) { Box( Modifier .align(Alignment.Center) .clickable { clicked = !clicked } .background(Color.Black) .sizeIn(minWidth = 48.dp, minHeight = 48.dp) ) } }
إضافة تصنيفات النقرات
يمكنك استخدام تصنيف النقر لإضافة معنى دلالي لسلوك النقر في عنصر قابل للإنشاء. تصف تسميات النقر ما يحدث عندما يتفاعل المستخدم مع العنصر القابل للإنشاء. تستخدم خدمات إمكانية الوصول تصنيفات النقر للمساعدة في وصف التطبيق للمستخدمين ذوي الاحتياجات الخاصة.
اضبط تصنيف النقرة من خلال ضبط مَعلمة في أداة تعديل clickable
:
@Composable private fun ArticleListItem(openArticle: () -> Unit) { Row( Modifier.clickable( // R.string.action_read_article = "read article" onClickLabel = stringResource(R.string.action_read_article), onClick = openArticle ) ) { // .. } }
بدلاً من ذلك، إذا لم تتمكّن من الوصول إلى المعدِّل القابل للنقر، اضبط تصنيف النقر في معدِّل الدلالات:
@Composable private fun LowLevelClickLabel(openArticle: () -> Boolean) { // R.string.action_read_article = "read article" val readArticleLabel = stringResource(R.string.action_read_article) Canvas( Modifier.semantics { onClick(label = readArticleLabel, action = openArticle) } ) { // .. } }
وصف العناصر المرئية
عند تحديد Image
أو Icon
قابل للإنشاء، لا تتوفر طريقة تلقائية لإطار عمل Android لفهم ما يعرضه التطبيق. تحتاج إلى تمرير وصف نصي للعنصر المرئي.
تخيل شاشة حيث يمكن للمستخدم مشاركة الصفحة الحالية مع الأصدقاء. تحتوي هذه الشاشة على أيقونة مشاركة قابلة للنقر:
استنادًا إلى الرمز فقط، لا يمكن لإطار عمل Android وصفه لمستخدم من ذوي العجز البصري. يحتاج إطار عمل Android إلى وصف نصي إضافي للأيقونة.
تصف المَعلمة contentDescription
عنصرًا مرئيًا. استخدِم سلسلة مترجَمة، كما هي مرئية للمستخدم
@Composable private fun ShareButton(onClick: () -> Unit) { IconButton(onClick = onClick) { Icon( imageVector = Icons.Filled.Share, contentDescription = stringResource(R.string.label_share) ) } }
بعض العناصر المرئية زخرفية بحتة وقد لا ترغب في توصيلها للمستخدم. عند ضبط المعلَمة contentDescription
على null
، تشير
إلى إطار عمل Android أن هذا العنصر ليس له إجراءات أو حالة مرتبطة.
@Composable private fun PostImage(post: Post, modifier: Modifier = Modifier) { val image = post.imageThumb ?: painterResource(R.drawable.placeholder_1_1) Image( painter = image, // Specify that this image has no semantic meaning contentDescription = null, modifier = modifier .size(40.dp, 40.dp) .clip(MaterialTheme.shapes.small) ) }
الأمر متروك لك لتحديد ما إذا كان العنصر المرئي بحاجة إلى إضافة
contentDescription
. اسأل نفسك عما إذا كان العنصر ينقل المعلومات
التي سيحتاجها المستخدم لأداء مهمته. إذا لم يكن الأمر كذلك،
فمن الأفضل ترك الوصف.
دمج العناصر
تتيح خدمات تسهيل الاستخدام مثل TalkBack و"الوصول عبر مفتاح تحكّم" للمستخدمين نقل التركيز بين العناصر الظاهرة على الشاشة. من المهم أن يتم التركيز على العناصر على الدقة الصحيحة. عندما يتم التركيز على كل عنصر قابل للإنشاء منخفض المستوى في شاشتك بشكل مستقل، يتعين على المستخدمين التفاعل كثيرًا للتنقل عبر الشاشة. إذا تم دمج العناصر معًا بشكل كبير جدًا، فقد لا يفهم المستخدمون العناصر التي تنتمي معًا
عند تطبيق عنصر تعديل clickable
على عنصر قابل للإنشاء، يدمج Compose
تلقائيًا جميع العناصر التي يحتوي عليها العنصر القابل للإنشاء. ينطبق ذلك أيضًا على ListItem
، فالعناصر داخل القائمة التي يتم دمجها معًا، وخدمات تسهيل الاستخدام تعرضها كعنصر واحد.
من الممكن أن يكون لديك مجموعة من العناصر القابلة للإنشاء التي تشكّل مجموعة منطقية، ولكن هذه المجموعة غير قابلة للنقر أو تكون جزءًا من عنصر قائمة. ستظل ترغب في أن تعرضها خدمات إمكانية الوصول كعنصر واحد. على سبيل المثال، تخيل عنصرًا قابلاً للإنشاء يعرض الصورة الرمزية للمستخدم واسمه وبعض المعلومات الإضافية:
يمكنك تفعيل سياسة ComposeAllowed لدمج هذه العناصر باستخدام المَعلمة mergeDescendants
في المعدِّل semantics
. بهذه الطريقة، تختار خدمات تسهيل الاستخدام العنصر المدمج فقط، ويتم دمج جميع الخصائص الدلالية للعناصر التابعة.
@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") } } }
تركز خدمات تسهيل الاستخدام الآن على الحاوية بأكملها في آنٍ واحد ودمج محتواها:
إضافة إجراءات مخصّصة
ألقِ نظرة على عنصر القائمة التالي:
عند استخدام قارئ شاشة مثل TalkBack لسماع ما يتم عرضه على الشاشة، يتم أولاً اختيار العنصر بأكمله، ثم رمز الإشارة المرجعية.
في قائمة طويلة، قد يصبح هذا متكررًا جدًا. النهج الأفضل هو تحديد إجراء مخصص
يسمح للمستخدم بوضع إشارة مرجعية على العنصر. ضَع في اعتبارك أنّه عليك أيضًا إزالة سلوك رمز الإشارة نفسها بشكل صريح للتأكّد من عدم اختياره من قِبل خدمة تسهيل الاستخدام. ويتم ذلك باستخدام المعدِّل clearAndSetSemantics
:
@Composable private fun PostCardSimple( /* ... */ isFavorite: Boolean, onToggleFavorite: () -> Boolean ) { val actionLabel = stringResource( if (isFavorite) R.string.unfavorite else R.string.favorite ) Row( modifier = Modifier .clickable(onClick = { /* ... */ }) .semantics { // Set any explicit semantic properties customActions = listOf( CustomAccessibilityAction(actionLabel, onToggleFavorite) ) } ) { /* ... */ BookmarkButton( isBookmarked = isFavorite, onClick = onToggleFavorite, // Clear any semantics properties set on this node modifier = Modifier.clearAndSetSemantics { } ) } }
وصف حالة عنصر
يمكن لعنصر قابل للإنشاء تحديد stateDescription
للدلالات التي يستخدمها
إطار عمل Android لقراءة حالة العنصر القابل للإنشاء. على سبيل المثال، يمكن أن تكون حالة العنصر القابل للإنشاء "محددة" أو "غير محددة". في بعض الحالات، قد ترغب في إلغاء تسميات الوصف للحالة التلقائية
التي تستخدمها Compose. يمكنك إجراء ذلك من خلال تحديد تصنيفات وصف الحالة بشكل صريح قبل تحديد عنصر قابل للإنشاء على أنّه قابل للتبديل:
@Composable private fun TopicItem(itemTitle: String, selected: Boolean, onToggle: () -> Unit) { val stateSubscribed = stringResource(R.string.subscribed) val stateNotSubscribed = stringResource(R.string.not_subscribed) Row( modifier = Modifier .semantics { // Set any explicit semantic properties stateDescription = if (selected) stateSubscribed else stateNotSubscribed } .toggleable( value = selected, onValueChange = { onToggle() } ) ) { /* ... */ } }
تحديد العناوين
تعرض التطبيقات أحيانًا الكثير من المحتوى على شاشة واحدة في حاوية يمكن التمرير بينها. على سبيل المثال، يمكن أن تعرض الشاشة المحتوى الكامل لمقالة يقرأها المستخدم:
يواجه المستخدمون ذوو احتياجات إمكانية الوصول صعوبة في التنقل في مثل هذه الشاشة. للمساعدة في التنقل، حدد العناصر التي هي عناوين. في المثال السابق، يمكن تعريف كل عنوان قسم فرعي كعنوان لإمكانية الوصول. تسمح بعض خدمات تسهيل الاستخدام، مثل TalkBack، للمستخدمين بالانتقال مباشرةً من العنوان إلى العنوان.
في علامة التبويب Compose، أنت تشير إلى أنّ العنصر القابل للإنشاء هو عنوان من خلال تحديد خاصية semantics
الخاصة به:
@Composable private fun Subsection(text: String) { Text( text = text, style = MaterialTheme.typography.headlineSmall, modifier = Modifier.semantics { heading() } ) }
التعامل مع العناصر المخصّصة القابلة للإنشاء
عندما تستبدل مكونات Material معينة في تطبيقك بإصدارات مخصصة، عليك أن تضع اعتبارات سهولة الوصول في الاعتبار.
لنفترض أنّك ستستبدل المادة Checkbox
بالتنفيذ الخاص بك.
يمكنك نسيان إضافة المعدِّل triStateToggleable
الذي يعالج
خصائص تسهيل الاستخدام لهذا المكوِّن.
كقاعدة إرشادية، انظر إلى تنفيذ المكوِّن في مكتبة Material ومحاكاة أي سلوك يمكنك العثور عليه بشأن سهولة الوصول. بالإضافة إلى ذلك، عليك الاستفادة بشكل كبير من معدِّلات الأساس، بدلاً من معدِّلات مستوى واجهة المستخدم، حيث تشمل اعتبارات سهولة الوصول طريقة مبتكرة.
اختبر تنفيذ المكونات المخصصة باستخدام خدمات إمكانية الوصول متعددة للتحقق من سلوكها.
مراجع إضافية
- أدوات تسهيل الاستخدام: المفاهيم والتقنيات الأساسية الشائعة في جميع مراحل تطوير تطبيقات Android
- إنشاء تطبيقات سهلة الاستخدام: الخطوات الرئيسية التي يمكنك اتّخاذها لتسهيل استخدام تطبيقك
- مبادئ تحسين إمكانية الوصول إلى التطبيقات: المبادئ الأساسية التي يجب وضعها في الاعتبار عند العمل على تسهيل الوصول إلى تطبيقك
- اختبار تسهيل الاستخدام: اختبار مبادئ وأدوات لتسهيل الاستخدام على Android