Compose'da erişilebilirliği iyileştirmek için atılacak temel adımlar

Erişilebilirlik ihtiyacı olan kişilerin uygulamanızı başarılı bir şekilde kullanmalarına yardımcı olmak için Google Play'den yeni bir uygulama indirip yükleyin.

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 herhangi bir öğe olmalıdır. büyüklükte olması gerekir. Bu öğeleri boyutlandırırken Materyal Tasarım'a uygun olması için minimum boyutu 48 dp olarak ayarlayın erişilebilirlik yönergelerine göz atın.

Checkbox, RadioButton, Switch gibi malzeme bileşenleri Slider ve Surface: Bu minimum boyutu dahili olarak ayarlayabilirsiniz. Bileşen, kullanıcı işlemleri alabildiğinde. Örneğin, bir Checkbox onCheckedChange parametresi boş olmayan bir değere ayarlanmışsa onay kutusu genişliği ve yüksekliği en az 48 dp olmalıdır.

@Composable
private fun CheckableCheckbox() {
    Checkbox(checked = true, onCheckedChange = {})
}

onCheckedChange parametresi null değerine ayarlandığında dolgu dahil edilir.

@Composable
private fun NonClickableCheckbox() {
    Checkbox(checked = true, onCheckedChange = null)
}

Şekil 1. Dolgusuz bir onay kutusu.

Switch, RadioButton veya Checkbox için tıklanabilir özellikte, tıklama davranışını bir üst kapsayıcıya composable'da null öğesine tıklama geri çağırması yapın ve bir toggleable veya Üst composable'a selectable değiştiricisi.

@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 bir composable'ın boyutu, minimum dokunma hedefinden küçük olduğunda boyutu artırılırsa Oluştur dokunma hedefi boyutunu artırır. Bunu, dokunma hedefi boyutunu composable'ın sınırlarının dışına çıkarın.

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şletilir, bu nedenle Box işaretinin eklenmesi tıklama etkinliğini tetiklemeye devam eder.

@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 temas alanları arasında olası çakışmaları önlemek için her zaman composable için yeterince büyük bir minimum boyut kullanın. Örnekte bu, iç kutu için minimum boyutu ayarlamak üzere sizeIn değiştiricinin 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 etiketleri ekleme

Bir reklamın tıklama davranışına anlamsal anlam eklemek için tıklama etiketi kullanabilirsiniz. composable'dan bahsetmek istiyorum. Tıklama etiketleri, kullanıcı composable'dan bahsetmek istiyorum. Erişilebilirlik hizmetleri, uygulamanın nasıl tanıtılacağını açıklamak için tıklama etiketlerini kullanır. belirli gereksinimleri olan kullanıcılara yöneliktir.

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 anlamsal değiştiricideki tıklama etiketi:

@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 unsurları açıklayabilme

Image veya Icon composable tanımlarken uygulamanın ne olduğunu anlaması için Android çerçevesinin otomatik görüntüleniyor. Görsel öğe için metin açıklaması iletmeniz gerekir.

Kullanıcının geçerli sayfayı arkadaşlarıyla paylaşabileceği bir ekran düşünün. Bu ekranda tıklanabilir bir paylaş simgesi bulunuyor:

Tıklanabilir simgelerden oluşan bir şerit ve

Sadece simgeye dayalı olarak Android çerçevesi onu görsel olarak anlatamaz yardımcı olur. Android çerçevesinin açıklamaya tıklayın.

contentDescription parametresi, görsel bir öğeyi açıklar. Yerelleştirilmiş dize.

@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 bu öğeleri kullanıcıya gösterir. contentDescription parametresini null olarak ayarladığınızda Android çerçevesine, bu öğenin ilişkili olmadığını işlemleri veya durumu gösterir.

@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 belirli bir reklamın gerekip contentDescription Öğenin belirli bir bilgiyi kullanıcının görevini yerine getirmesi gerekir. Aksi takdirde, açıklama ekleyin.

Öğeleri birleştir

TalkBack ve Anahtar Erişimi gibi erişilebilirlik hizmetleri, kullanıcıların odağını hareket ettirmesine olanak tanır otomatik olarak düzenlememiz gerekir. Öğelerin odak noktasının doğru ayrıntı düzeyine sahip. Ekranınızdaki her bir alt düzey composable, kullanıcılar ekran boyunca hareket edebilmek için çok fazla etkileşim kurmak zorunda kalıyor. Öğeler çok agresif bir şekilde birleştirilirse kullanıcılar hangi öğelerin öğeler birbirine ait

Bir composable'a clickable değiştirici uyguladığınızda, Oluştur'u tıklayın. composable'ın içerdiği tüm öğeleri otomatik olarak birleştirir. Bu durum ListItem; bir liste öğesi içindeki öğelerin birleştirilmesi ve erişilebilirlik bunları tek bir öğe olarak görür.

Mantıksal bir grup oluşturan bir composable diziniz olabilir, ancak grubu tıklanabilir veya liste öğesinin parçası değil. Yine de erişilebilirlik bunları tek bir öğe olarak görüntülemelerini sağlar. Mesela sınırsız sayıda kullanıcının avatarını, adını ve bazı ek bilgileri gösterir:

Kullanıcı adını içeren bir kullanıcı arayüzü öğeleri grubu. Ad seçildi.

Bu öğeleri birleştirmek için mergeDescendants öğesini kullanarak Oluştur'u etkinleştirebilirsiniz. parametresini semantics değiştiricisine ekleyin. Böylece erişilebilirlik hizmetleri yalnızca birleştirilmiş öğeyi ve alt öğelerin tüm anlamsal özelliklerini seçer 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 kapsayıcının tamamına odaklanarak diğer platformlar:

Kullanıcı adını içeren bir kullanıcı arayüzü öğeleri grubu. Tüm öğeler birlikte seçilir.

Özel işlem ekleyin

Aşağıdaki liste öğesine göz atın:

Bir makale başlığı, yazar ve yer işareti simgesi içeren tipik bir liste öğesi.

Ekranda görüntülenenleri duymak için TalkBack gibi bir ekran okuyucu kullandığınızda ekranında, ilk olarak öğenin tamamı ve daha sonra yer işareti simgesi seçilir.

Tüm öğelerin birlikte seçildiği liste öğesi.

Yalnızca yer işareti simgesinin seçili olduğu liste öğesi

Uzun bir listede bu kısım çok tekrarlanabilir. Daha iyi bir yaklaşım Kullanıcının öğeye yer işareti koymasına olanak tanıyan özel bir işlem tanımlayın. Unutmamanız gereken noktalar Ayrıca, yer işareti simgesinin davranışını açık bir şekilde kaldırmanızı da erişilebilirlik hizmeti tarafından seçilmediğinden emin olun. Bu clearAndSetSemantics değiştiricisiyle yapılıyor:

@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 elementin durumunu açıklama

Bir composable, anlamlar için bir stateDescription tanımlayabilir. Android çerçevesi, composable'ın bulunduğu durumu sesli olarak okur. Örneğin, Örneğin, geçiş yapılabilir bir composable, "işaretli" veya "işaretsiz" durumu. Bazı durumlarda, varsayılan durum açıklamasını geçersiz kılmak etiketleri içerir. Eyaletin durumunu açıkça belirterek bunu yapabilirsiniz. bir composable'ı geçiş yapılabilir olarak tanımlamadan önce açıklama etiketlerini:

@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ımla

Uygulamalar bazen kaydırılabilir bir kapsayıcıda bir ekranda çok fazla içerik gösterir. Örneğin, bir ekranda kullanıcının görüntülediği bir makalenin tüm içeriği okuyor:

Kaydırılabilir kapsayıcıda bir makale metni içeren blog yayınının ekran görüntüsü.

Erişilebilirlik ihtiyaçları olan kullanıcılar bu tür bir ekranda gezinirken zorluk yaşar. Yardımcı olmak hangi öğelerin başlık olduğunu belirtin. Yukarıdaki örnekte her bir alt bölüm başlığı, erişilebilirlik başlığı olarak tanımlanabilir. Biraz TalkBack gibi erişilebilirlik hizmetleri, kullanıcıların doğrudan başlığını kullanın.

Compose'da bir composable'ın başlık olduğunu belirtmek için semantics mülkü:

@Composable
private fun Subsection(text: String) {
    Text(
        text = text,
        style = MaterialTheme.typography.headlineSmall,
        modifier = Modifier.semantics { heading() }
    )
}

Özel composable'ları işleme

Uygulamanızdaki belirli Malzeme bileşenlerini özel bileşenlerle değiştirdiğinizde erişilebilirlikle ilgili hususları aklınızda bulundurmanız gerekir.

Materyal Checkbox öğesini kendi uygulamanızla değiştirdiğinizi varsayalım. triStateToggleable değiştiricisini eklemeyi unutabilirsiniz. erişilebilirlik özelliklerini ayarlayın.

Genel bir kural olarak, bileşenin uygulama paketindeki Malzeme kitaplığı'nda olmalı ve bulduğunuz tüm erişilebilirlik davranışlarını taklit etmelidir. Ayrıca, kullanıcı arayüzü düzeyi yerine Temel değiştiricileri yoğun bir şekilde kullanın erişilebilirlikle ilgili dikkat edilmesi gereken noktaları içerir.

Özel bileşen uygulamanızı birden çok bileşenle test edin erişilebilirlik hizmetlerini inceleyin.

Ek kaynaklar