API varsayılanları

Material, Compose UI ve Foundation API'leri, varsayılan olarak birçok erişilebilir uygulamayı uygular ve sunar. Bunlar, belirli rollerini ve işlevlerini takip eden yerleşik semantikler içerir. Bu sayede, erişilebilirlik desteğinin çoğu, çok az veya hiç ek çalışma yapmadan sağlanır.

Uygun amaç için uygun API'leri kullanmak, bileşenlerin genellikle standart kullanım alanlarını kapsayan önceden tanımlanmış erişilebilirlik davranışlarıyla birlikte geldiği anlamına gelir. Ancak bu varsayılan ayarların erişilebilirlik ihtiyaçlarınıza uygun olup olmadığını her zaman kontrol edin. Değilse Oluşturma, daha spesifik gereksinimleri karşılamanın yollarını sunar.

Compose API'lerindeki varsayılan erişilebilirlik semantiğini ve kalıplarını anlamak, bunları erişilebilirlik göz önünde bulundurularak kullanmanıza yardımcı olur. Ayrıca, daha fazla özel bileşende erişilebilirliği desteklemenize yardımcı olur.

Minimum dokunma hedefi boyutları

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 kurallarına doğru şekilde uymak için minimum boyutu 48 dp olarak ayarladığınızdan emin olun.

Checkbox, RadioButton, Switch, Slider ve Surface gibi Material bileşenleri, bu minimum boyutu dahili olarak ayarlar ancak yalnızca bileşen kullanıcı işlemlerini alabiliyorsa. Örneğin, bir Checkbox öğesinin onCheckedChange parametresi sıfır olmayan bir değere ayarlandığında onay kutusu, en az 48 dp genişlik ve yüksekliğe sahip olacak şekilde dolgu içerir.

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

Genişliği ve yüksekliği 48 dp olan, varsayılan dolguya sahip bir onay kutusu.
Şekil 1. Varsayılan dolguya sahip bir onay kutusu.

onCheckedChange parametresi null olarak ayarlandığında, bileşenle doğrudan etkileşim kurulamadığından dolgu dahil edilmez.

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

Dolgu içermeyen bir onay kutusu.
Şekil 2. Doldurma içermeyen bir onay kutusu.

Switch, RadioButton veya Checkbox gibi seçim kontrollerini uygularken genellikle tıklanabilir davranışı üst kapsayıcıya taşımak için tıklama geri çağırmasını composable'da null olarak ayarlarsınız ve üst composable'a toggleable veya selectable değiştirici ekleyebilirsiniz.

@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)
        }
    }
}

"Seçenek" metninin yanındaki onay kutusu seçilir ve seçimi kaldırılır.
Şekil 3. Tıklanabilir davranışa sahip bir onay kutusu.

Tıklanabilir bir composable'ın boyutu minimum dokunma hedefi boyutundan küçük olduğunda Compose, dokunma hedefi boyutunu yine de artırır. Bu işlem, 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 yer alıyor. Dokunma hedefi alanı, Box sınırlarının ötesine otomatik olarak genişletilir. Bu nedenle, Box simgesinin yanına dokunulduğunda tıklama etkinliği tetiklenmeye 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)
        )
    }
}

Kutunun yanına dokunarak daha büyük bir dokunma hedefine genişletilen çok küçük bir tıklanabilir kutu.
Şekil 4. Daha büyük bir dokunma hedefi için genişletilen çok küçük bir tıklanabilir kutu.

Farklı composable'ların dokunma alanları arasında olası çakışmaları önlemek için composable'ın minimum boyutunu her zaman yeterince büyük tutun. Örneğin, bu durumda iç kutunun minimum boyutunu ayarlamak için sizeIn değiştiricisinin kullanılması gerekir:

@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)
        )
    }
}

Önceki örnekteki çok küçük kutu, daha büyük bir dokunma hedefi oluşturmak için büyütülür.
Şekil 5. Daha büyük bir kutu dokunma hedefi.

Grafik öğeler

Bir Image veya Icon composable tanımladığınızda Android çerçevesinin, uygulamanın ne gösterdiğini anlaması için otomatik bir yol yoktur. Grafik öğenin metin açıklamasını iletmeniz gerekir.

Kullanıcının mevcut sayfayı arkadaşlarıyla paylaşabileceği bir ekran düşünün. Bu ekranda tıklanabilir bir paylaşım simgesi bulunur:

"Paylaş" simgesinin vurgulandığı, tıklanabilir dört simgeden oluşan bir şerit.
Şekil 6. "Paylaş" simgesinin seçili olduğu, tıklanabilir simgelerden oluşan bir satır.

Android çerçevesi, yalnızca simgeye dayanarak bunu görme engelli bir kullanıcıya açıklayamaz. Android çerçevesi, simgenin ek bir metin açıklamasına ihtiyaç duyar.

contentDescription parametresi, bir grafik öğesini tanımlar. Kullanıcı tarafından görülebildiği için 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ı grafik öğeler tamamen dekoratif amaçlıdır ve kullanıcıya iletilmesi gerekmeyebilir. contentDescription parametresini null olarak ayarladığınızda, Android çerçevesine bu öğeyle ilişkili işlemler veya durum 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)
    )
}

contentDescription, esas olarak resim gibi grafik öğeleri için kullanılmak üzere tasarlanmıştır. Button veya Text gibi materyal bileşenleri ve clickable veya toggleable gibi işlem yapılabilir davranışlar, kendi davranışlarını açıklayan diğer önceden tanımlanmış semantiklerle birlikte gelir ve diğer Compose API'leri aracılığıyla değiştirilebilir.

Etkileşimli öğeler

Material ve Foundation Compose API'leri, kullanıcıların clickable ve toggleable değiştirici API'leri aracılığıyla etkileşimde bulunabileceği kullanıcı arayüzü öğeleri oluşturur. Etkileşimli bileşenler birden fazla öğeden oluşabileceğinden clickable ve toggleable, bileşenin tek bir mantıksal öğe olarak ele alınması için alt öğelerinin semantiğini varsayılan olarak birleştirir.

Örneğin, bir Materyal Button, alt simge ve biraz metinden oluşabilir. Material Button, çocukları ayrı ayrı ele almak yerine varsayılan olarak çocukların semantiğini birleştirir. Böylece erişilebilirlik hizmetleri bunları uygun şekilde gruplandırabilir:

Birleştirilmemiş ve birleştirilmiş alt öğe semantiğine sahip düğmeler.
Şekil 7. Birleştirilmemiş ve birleştirilmiş alt öğe semantiğine sahip düğmeler.

Benzer şekilde, clickable değiştiricisinin kullanılması da bir composable'ın alt öğelerinin semantiğini tek bir öğede birleştirmesine neden olur. Bu öğe, erişilebilirlik hizmetlerine karşılık gelen bir işlem temsiliyle birlikte gönderilir:

Row(
    // Uses `mergeDescendants = true` under the hood
    modifier = Modifier.clickable { openArticle() }
) {
    Icon(
        painter = painterResource(R.drawable.ic_logo),
        contentDescription = "Open",
    )
    Text("Accessibility in Compose")
}

Erişilebilirlik hizmetlerine ek bilgi sağlamak ve işlemin daha iyi bir gösterimini sunmak için üst öğe tıklanabilirinde belirli bir onClickLabel de ayarlayabilirsiniz:

Row(
    modifier = Modifier
        .clickable(onClickLabel = "Open this article") {
            openArticle()
        }
) {
    Icon(
        painter = painterResource(R.drawable.ic_logo),
        contentDescription = "Open"
    )
    Text("Accessibility in Compose")
}

Örnek olarak TalkBack'i ele alalım. Bu clickable değiştirici ve tıklama etiketi, TalkBack'in "Etkinleştirmek için iki kez dokunun" şeklindeki daha genel varsayılan geri bildirimi yerine "Bu makaleyi açmak için iki kez dokunun" şeklinde bir işlem ipucu vermesini sağlar.

Bu geri bildirim, işlem türüne göre değişir. Uzun tıklama, TalkBack'in "Şunu yapmak için iki kez dokunup basılı tutun" ipucunu ve ardından bir etiketi okumasına neden olur:

Row(
    modifier = Modifier
        .combinedClickable(
            onLongClickLabel = "Bookmark this article",
            onLongClick = { addToBookmarks() },
            onClickLabel = "Open this article",
            onClick = { openArticle() },
        )
) {}

Bazı durumlarda, clickable değiştiricisine doğrudan erişiminiz olmayabilir (örneğin, daha düşük bir iç içe yerleştirilmiş katmanda ayarlandığında) ancak yine de duyuru etiketini varsayılandan değiştirmek isteyebilirsiniz. Bunu yapmak için semantics değiştiricisini kullanarak duyuruyu değiştirmekten clickable ayarını ayırın ve işlem gösterimini değiştirmek için tıklama etiketini orada ayarlayın:

@Composable
private fun ArticleList(openArticle: () -> Unit) {
    NestedArticleListItem(
        // Clickable is set separately, in a nested layer:
        onClickAction = openArticle,
        // Semantics are set here:
        modifier = Modifier.semantics {
            onClick(
                label = "Open this article",
                action = {
                    // Not needed here: openArticle()
                    true
                }
            )
        }
    )
}

Tıklama işlemini iki kez iletmeniz gerekmez. clickable veya Button gibi mevcut Compose API'leri bu işlemi sizin için gerçekleştirir. Birleştirme mantığı, en dıştaki değiştirici etiketin ve işlemin mevcut bilgiler için yapıldığını doğrular. Önceki örnekte, NestedArticleListItem, openArticle() tıklama işlemini otomatik olarak clickable semantiğine geçirir. İkinci anlam değiştirici işleminde tıklama işlemini boş bırakabilirsiniz. Ancak, tıklama etiketi ilkinde bulunmadığı için ikinci anlamsal değiştiriciden onClick(label = "Open this document") alınır.

Alt öğe semantiğinin üst öğe semantiğiyle birleştirilmesini beklediğiniz ancak bu durumun gerçekleşmediği senaryolarla karşılaşabilirsiniz. Daha ayrıntılı bilgi için Birleştirme ve temizleme konusuna bakın.

Özel bileşenler

Özel bir bileşen oluştururken Material kitaplığında veya diğer Compose kitaplıklarında benzer bir bileşenin uygulanmasını inceleyin. Ardından, erişilebilirlik davranışını uygun şekilde taklit edin veya değiştirin. Örneğin, Materyal Checkbox öğesini kendi uygulamanızla değiştirirseniz mevcut Checkbox uygulamasına bakmak, bileşenin erişilebilirlik özelliklerini işleyen triStateToggleable değiştiricisini eklemenizi hatırlatır. Ayrıca, bu bölümde ele alınan yerleşik erişilebilirlik hususlarını ve mevcut Compose uygulamalarını içerdiğinden Foundation değiştiricilerden yoğun bir şekilde yararlanın.

Ayrıca, Anlamları netleştirme ve ayarlama bölümünde özel açma/kapatma bileşeni örneğini ve API yönergelerinde özel bileşenlerde erişilebilirliği destekleme hakkında daha ayrıntılı bilgileri bulabilirsiniz.