Erişilebilirlik ihtiyacı olan kullanıcıların uygulamanızı başarıyla kullanmasına yardımcı olmak için uygulamanızı temel erişilebilirlik gereksinimlerini destekleyecek şekilde tasarlayın.
Minimum dokunma hedefi boyutlarını göz önünde bulundurun
Ekranda gösterilen ve kullanıcıların tıklayabileceği, dokunabileceği veya etkileşimde bulunabileceği öğeler, güvenilir etkileşim için yeterli büyüklükte olmalıdır. Bu öğeleri boyutlandırırken Materyal Tasarım erişilebilirlik yönergelerini doğru şekilde uygulamak için minimum boyutu 48 dp'ye ayarladığınızdan emin olun.
Checkbox
, RadioButton
, Switch
,
Slider
ve Surface
gibi malzeme bileşenleri, yalnızca bileşenin kullanıcı işlemlerini alabildiği durumlarda bu minimum boyutu dahili olarak ayarlar. Örneğin, bir Checkbox
öğesinin onCheckedChange
parametresi null olmayan bir değere ayarlandığında, onay kutusunda en az 48 dp genişliğe ve yüksekliğe sahip dolgu bulunur.
@Composable private fun CheckableCheckbox() { Checkbox(checked = true, onCheckedChange = {}) }
onCheckedChange
parametresi null değerine ayarlandığında bileşenle doğrudan etkileşim kurulamayacağından dolgu dahil edilmez.
@Composable private fun NonClickableCheckbox() { Checkbox(checked = true, onCheckedChange = null) }
Switch
, RadioButton
veya Checkbox
gibi seçim kontrollerini uygularken genellikle tıklanabilir davranışı üst kapsayıcıya kaldırır, composable'da tıklama geri çağırmasını null
olarak ayarlar ve üst composable'a toggleable
ya da selectable
değiştiricisi eklersiniz.
@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) } } }
Tıklanabilir composable'ın boyutu minimum dokunma hedefi boyutundan küçük olsa da Oluşturma, dokunma hedefi boyutunu artırır. Bunu, dokunma hedefi boyutunu composable'ın sınırlarının dışına genişleterek yapılır.
Aşağıdaki örnekte çok küçük bir tıklanabilir Box
bulunmaktadır. Dokunma hedefi alanı, otomatik olarak Box
sınırlarının dışına genişletildiğinden Box
öğesinin yanına dokunmak da tıklama etkinliğini tetikler.
@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) ) } }
Farklı composable'ların dokunma alanları arasında olası çakışmaları önlemek amacıyla composable için her zaman yeterince büyük bir minimum boyut kullanın. Bu örnekte, iç kutu için minimum boyutu ayarlamak üzere sizeIn
değiştiricisinin kullanılması anlamına gelir:
@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) ) } }
Tıklama etiketi ekleme
Bir composable'ın tıklama davranışına anlamsal anlam eklemek için tıklama etiketi kullanabilirsiniz. Tıklama etiketleri, kullanıcı composable ile etkileşimde bulunduğunda ne olacağını açıklar. Erişilebilirlik hizmetleri, uygulamayı belirli ihtiyaçları olan kullanıcılara açıklamak için tıklama etiketleri kullanır.
clickable
değiştiricisinde bir parametre ileterek tıklama etiketini ayarlayın:
@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 ) ) { // .. } }
Alternatif olarak, tıklanabilir değiştiriciye erişiminiz yoksa tıklama etiketini anlamsal değiştiricisinde ayarlayın:
@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) } ) { // .. } }
Görsel öğeleri açıklama
Bir Image
veya Icon
composable tanımladığınızda, Android çerçevesinin uygulamanın neyi görüntülediğini otomatik olarak anlaması mümkün değildir. Görsel öğenin metin biçiminde bir açıklamasını iletmeniz gerekir.
Kullanıcının mevcut sayfayı arkadaşlarıyla paylaşabildiği bir ekran düşünün. Bu ekranda tıklanabilir paylaş simgesi bulunur:
Sadece simgeden yola çıkarak Android çerçevesi bunu görme engelli bir kullanıcıya açıklayamaz. Android çerçevesi, simge için ek bir metin açıklaması gerektirir.
contentDescription
parametresi, görsel bir öğeyi açıklar. Kullanıcının görebileceği yerelleştirilmiş bir dize kullanın.
@Composable private fun ShareButton(onClick: () -> Unit) { IconButton(onClick = onClick) { Icon( imageVector = Icons.Filled.Share, contentDescription = stringResource(R.string.label_share) ) } }
Bazı görsel öğeler tamamen dekoratiftir ve bunları kullanıcıya anlatmak istemeyebilirsiniz. contentDescription
parametresini null
olarak ayarladığınızda Android çerçevesine, bu öğenin ilişkili işlemleri veya durumu olmadığını belirtirsiniz.
@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) ) }
Belirli bir görsel öğe için contentDescription
gerekli olup olmadığına karar vermek size kalmıştır. Öğenin, kullanıcının görevini yerine getirmek için
ihtiyaç duyacağı bilgileri aktarıp aktarmadığını kendinize sorun. Yoksa açıklamayı
yerine koymamak daha iyidir.
Öğeleri birleştir
TalkBack ve Anahtar Erişimi gibi erişilebilirlik hizmetleri, kullanıcıların odağı ekrandaki öğeler arasında taşımasına olanak tanır. Öğelerin doğru ayrıntı düzeyinde odaklanması önemlidir. Ekranınızdaki her düşük seviye composable bağımsız olarak odaklandığında, kullanıcıların ekranda hareket etmek için çok fazla etkileşimde bulunması gerekir. Öğeler aşırı agresif bir şekilde birleştirilirse kullanıcılar hangi öğelerin
Bir composable'a clickable
değiştirici uyguladığınızda Compose
bu composable'ın içerdiği tüm öğeleri otomatik olarak birleştirir. Bu durum ListItem
için de geçerlidir; bir liste öğesindeki öğeler birleştirilir ve erişilebilirlik hizmetleri bunları tek bir öğe olarak görüntüler.
Mantıksal bir grup oluşturan bir grup composable'ın olması mümkündür, ancak bu grup tıklanabilir veya bir liste öğesinin parçası değildir. Erişilebilirlik hizmetlerinin bunları da tek bir öğe olarak görmesini istersiniz. Örneğin, bir kullanıcının avatarını, adını ve bazı ek bilgileri gösteren bir composable düşünün:
semantics
değiştiricisinde mergeDescendants
parametresini kullanarak bu öğeleri birleştirmek için Oluştur'u etkinleştirebilirsiniz. Bu şekilde, erişilebilirlik hizmetleri yalnızca birleştirilmiş öğeyi seçer ve alt öğelerin tüm anlambilim özellikleri birleştirilir.
@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") } } }
Erişilebilirlik hizmetleri artık içeriklerini birleştirerek aynı anda tüm container'a odaklanır:
Özel işlemler ekleme
Şu liste öğesine göz atın:
Ekranda nelerin gösterildiğini duymak için TalkBack gibi bir ekran okuyucu kullandığınızda, uygulama önce öğenin tamamını, sonra da yer işareti simgesini seçer.
Uzun bir listede bu durum çok fazla tekrarlanabilir. Kullanıcının öğeye yer işareti koymasına izin veren özel bir işlem tanımlamak daha iyi bir yaklaşım olur. Erişilebilirlik hizmeti tarafından seçilmediğinden emin olmak için yer işareti simgesinin davranışını açıkça kaldırmanız gerektiğini de unutmayın. Bu işlem, clearAndSetSemantics
değiştiricisiyle yapılır:
@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 { } ) } }
Bir öğenin durumunu açıklama
composable, Android çerçevesinin composable'ın bulunduğu durumu sesli olarak okumak için kullandığı anlamlar için bir stateDescription
tanımlayabilir. Örneğin, geçiş yapılabilir bir composable, "işaretli" veya "işaretsiz" durumunda olabilir. Bazı durumlarda, Oluştur'un kullandığı varsayılan durum açıklaması etiketlerini geçersiz kılmak isteyebilirsiniz. Bir composable'ı geçiş yapılabilir olarak tanımlamadan önce durum açıklama etiketlerini açıkça belirterek bunu yapabilirsiniz:
@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() } ) ) { /* ... */ } }
Başlıkları tanımlayın
Uygulamalar bazen kaydırılabilir bir kapsayıcının içinde tek bir ekranda çok sayıda içerik gösterir. Örneğin, bir ekranda kullanıcının okumakta olduğu makalenin tam içeriği gösterilebilir:
Erişilebilirlik ihtiyacı olan kullanıcılar, böyle bir ekranda gezinirken zorlanır. Gezinmeye yardımcı olmak için hangi öğelerin başlık olduğunu belirtin. Yukarıdaki örnekte, her alt bölüm başlığı bir erişilebilirlik başlığı olarak tanımlanabilir. TalkBack gibi bazı erişilebilirlik hizmetleri, kullanıcıların doğrudan bir başlıktan başlığa gitmesine olanak tanır.
Compose'da semantics
özelliğini tanımlayarak bir composable'ın heading olduğunu belirtirsiniz:
@Composable private fun Subsection(text: String) { Text( text = text, style = MaterialTheme.typography.headlineSmall, modifier = Modifier.semantics { heading() } ) }
Özel composable'ları yönetin
Uygulamanızdaki belirli Material bileşenlerini özel sürümlerle değiştirdiğinizde, erişilebilirlikle ilgili konuları aklınızda bulundurmanız gerekir.
Checkbox
Materyalini kendi uygulamanızla değiştirdiğinizi varsayalım.
Bu bileşenin erişilebilirlik özelliklerini işleyen triStateToggleable
değiştiricisini eklemeyi unutabilirsiniz.
Genel bir kural olarak, bileşenin Malzeme kitaplığındaki uygulamasına bakın ve bulduğunuz erişilebilirlik davranışlarının aynısını yapın. Ek olarak, kullanıcı arayüzü düzeyi değiştiricilerinden farklı olarak Temel değiştiricileri yoğun bir şekilde kullanın. Bunlar, kullanıma hazır erişilebilirlik özellikleri içerir.
Davranışını doğrulamak için özel bileşen uygulamanızı birden çok erişilebilirlik hizmetiyle test edin.
Ek kaynaklar
- Erişilebilirlik: Tüm Android uygulama geliştirmelerinde ortak olan temel kavramlar ve teknikler
- Erişilebilir Uygulamalar Derleme: Uygulamanızı daha erişilebilir hale getirmek için atabileceğiniz temel adımlar
- Uygulama erişilebilirliğini iyileştirme ilkeleri: Uygulamanızı daha erişilebilir hale getirmeye çalışırken unutulmaması gereken temel ilkeler
- Erişilebilirlik için test etme: Android erişilebilirliği için test ilkeleri ve araçları