Erişilebilirlik hizmetleri ekrandaki öğeler arasında gezinirken bu öğelerin doğru ayrıntı düzeyinde gruplandırılması, ayrılması ve hatta gizlenmesi önemlidir. Ekranınızdaki her bir alt düzey composable bağımsız olarak vurgulandığında kullanıcıların ekranda gezinmek için çok fazla etkileşimde bulunması gerekir. Öğeler çok agresif bir şekilde birleştirilirse kullanıcılar hangi öğelerin mantıksal olarak bir arada olduğunu anlamayabilir. Ekranda yalnızca dekoratif amaçlı öğeler varsa bunlar erişilebilirlik hizmetlerinden gizlenebilir. Bu gibi durumlarda, semantiği birleştirmek, temizlemek ve gizlemek için Compose API'lerini kullanabilirsiniz.
Semantiği birleştirme
Üst düzey bir composable'a clickable değiştiricisi uyguladığınızda Compose, altındaki tüm alt öğeleri otomatik olarak birleştirir. Etkileşimli Compose Material ve Foundation bileşenlerinin varsayılan olarak birleştirme stratejilerini nasıl kullandığını anlamak için Etkileşimli öğeler bölümüne bakın.
Bir bileşenin birden fazla şekillendirilebilir öğeden oluşması yaygın bir durumdur. Bu composable'lar mantıksal bir grup oluşturabilir ve her biri önemli bilgiler içerebilir ancak yine de erişilebilirlik hizmetlerinin bunları tek bir öğe olarak görüntülemesini isteyebilirsiniz.
Örneğin, kullanıcının avatarını, adını ve bazı ek bilgileri gösteren bir composable düşünün:
Semantik değiştiricideki mergeDescendants parametresini kullanarak Compose'un bu öğeleri birleştirmesini sağlayabilirsiniz. Bu sayede erişilebilirlik hizmetleri, bileşeni tek bir varlık olarak ele alır ve alt öğelerin tüm semantik ö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 tüm kapsayıcıya aynı anda odaklanır ve içeriğini birleştirir:
Her semantik özelliğin tanımlanmış bir birleştirme stratejisi vardır. Örneğin, ContentDescription özelliği, tüm alt ContentDescription değerlerini bir listeye ekler. Semantik özelliğinin birleştirme stratejisini, SemanticsProperties.kt dosyasındaki mergePolicy uygulamasını kontrol ederek öğrenebilirsiniz.
Özellikler, üst veya alt değeri alabilir, değerleri bir liste ya da dize halinde birleştirebilir, birleştirmeye hiç izin vermeyip bunun yerine bir istisna oluşturabilir veya başka bir özel birleştirme stratejisi uygulayabilir.
Alt semantiklerin üst semantiklerle birleştirilmesini beklediğiniz ancak bunun gerçekleşmediği başka senaryolar da vardır. Aşağıdaki örnekte, alt öğeleri olan bir clickable liste öğesi üst öğesi var ve üst öğenin tüm alt öğeleri birleştirmesini bekleyebiliriz:
@Composable private fun ArticleListItem( openArticle: () -> Unit, addToBookmarks: () -> Unit, ) { Row(modifier = Modifier.clickable { openArticle() }) { // Merges with parent clickable: Icon( painter = painterResource(R.drawable.ic_logo), contentDescription = "Article thumbnail" ) ArticleDetails() // Defies the merge due to its own clickable: BookmarkButton(onClick = addToBookmarks) } }
Kullanıcı clickable öğesine Row bastığında makale açılır. Bunun içinde, makaleyi yer işaretlerine eklemek için bir BookmarkButton bulunur. Bu iç içe yerleştirilmiş düğme, birleştirilmemiş olarak gösterilirken satırdaki diğer alt içerikler birleştirilir:
Row düğümünün içindeki bir listede birden fazla metin içerir. Birleştirilmemiş ağaç, her Text composable için ayrı düğümler içerir.Bazı composable'lar, tasarım gereği bir üst öğe altında otomatik olarak birleştirilmez. Alt öğeler de birleştirilirken üst öğe, alt öğelerini birleştiremez. Bu durum, mergeDescendants = true ayarının açıkça belirlenmesiyle veya düğmeler ya da tıklanabilir öğeler gibi kendilerini birleştiren bileşenler aracılığıyla gerçekleşebilir. Belirli API'lerin nasıl birleştirildiğini veya birleştirmenin nasıl engellendiğini bilmek, beklenmedik davranışlarda hata ayıklamanıza yardımcı olabilir.
Alt öğeler, üst öğelerinin altında mantıklı ve anlamlı bir grup oluşturduğunda birleştirme özelliğini kullanın. Ancak iç içe yerleştirilmiş alt öğelerin kendi semantiklerinin manuel olarak ayarlanması veya kaldırılması gerekiyorsa diğer API'ler ihtiyaçlarınıza daha uygun olabilir (ör. clearAndSetSemantics).
Anlamsal öğeleri temizleme ve ayarlama
Anlamsal bilgilerin tamamen temizlenmesi veya üzerine yazılması gerekiyorsa clearAndSetSemantics güçlü bir API'dir.
Bir bileşenin kendi semantiğinin ve alt bileşenlerinin semantiğinin temizlenmesi gerektiğinde bu API'yi boş bir lambda ile kullanın. Semantiğinin üzerine yazılması gerektiğinde yeni içeriğinizi lambda'ya ekleyin.
Boş bir lambda ile temizleme yapıldığında, temizlenen semantiklerin erişilebilirlik, otomatik doldurma veya test gibi bu bilgileri kullanan hiçbir tüketiciye gönderilmediğini unutmayın. İçerik clearAndSetSemantics{/*semantic information*/} ile üzerine yazıldığında yeni semantikler, öğenin ve alt öğelerinin önceki tüm semantiklerinin yerini alır.
Aşağıda, simge ve metin içeren etkileşimli bir satırla temsil edilen özel bir açma/kapatma bileşeni örneği verilmiştir:
// 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?") } }
Simge ve metin bazı semantik bilgiler içerse de birlikte bu bileşenin açma/kapatma düğmesi olduğunu göstermezler. Bileşen hakkında ek bilgi vermeniz gerektiğinden birleştirme yeterli değildir.
Yukarıdaki snippet özel bir açma/kapatma bileşeni oluşturduğundan açma/kapatma özelliğinin yanı sıra stateDescription, toggleableState ve role semantiğini de eklemeniz gerekir. Bu sayede, bileşen durumu ve ilişkili işlem kullanılabilir olur. Örneğin, TalkBack "Etkinleştirmek için iki kez dokunun" yerine "Açmak/kapatmak için iki kez dokunun" şeklinde duyuru yapar.
Orijinal semantiği temizleyip yeni ve daha açıklayıcı semantikler ayarlayarak erişilebilirlik hizmetlerinin, bunun durumu değişebilen, açılıp kapatılabilir bir bileşen olduğunu görmesini sağlayabilirsiniz.
clearAndSetSemantics özelliğini kullanırken aşağıdakileri göz önünde bulundurun:
- Bu API ayarlandığında hizmetler bilgi almadığından, API'yi dikkatli kullanmak daha iyidir.
- Semantik bilgiler, yapay zeka temsilcileri ve benzer hizmetler tarafından ekranı anlamak için kullanılabilir. Bu nedenle, yalnızca gerektiğinde temizlenmelidir.
- Özel semantikler, API lambda içinde ayarlanabilir.
- Değiştiricilerin sıralaması önemlidir. Bu API, diğer birleştirme stratejilerinden bağımsız olarak, uygulandığı yerden sonraki tüm semantiği temizler.
Anlamsal öğeleri gizle
Bazı senaryolarda öğelerin erişilebilirlik hizmetlerine gönderilmesi gerekmez. Bu öğelerin ek bilgileri erişilebilirlik için gereksiz olabilir veya tamamen görsel olarak dekoratif ve etkileşimli olmayabilir. Bu gibi durumlarda, hideFromAccessibility API'sini kullanarak öğeleri gizleyebilirsiniz.
Aşağıdaki örneklerde, gizlenmesi gerekebilecek bileşenler gösterilmektedir: bir bileşeni kapsayan gereksiz bir filigran ve bilgileri dekoratif olarak ayırmak için kullanılan bir karakter.
@Composable fun WatermarkExample( watermarkText: String, content: @Composable () -> Unit, ) { Box { WatermarkedContent() // Mark the watermark as hidden to accessibility services. WatermarkText( text = watermarkText, color = Color.Gray.copy(alpha = 0.5f), modifier = Modifier .align(Alignment.BottomEnd) .semantics { hideFromAccessibility() } ) } } @Composable fun DecorativeExample() { Text( modifier = Modifier.semantics { hideFromAccessibility() }, text = "A dot character that is used to decoratively separate information, like •" ) }
Burada hideFromAccessibility kullanıldığında filigran ve dekorasyon, erişilebilirlik hizmetlerinden gizlenir ancak test gibi diğer kullanım alanları için semantiği korunur.
Kullanım alanlarının dökümü
Aşağıda, önceki API'ler arasındaki farkları net bir şekilde anlamak için kullanım alanlarının bir özeti verilmiştir:
- İçeriğin erişilebilirlik hizmetleri tarafından kullanılması amaçlanmadığında:
- İçerik muhtemelen dekoratif veya gereksiz olduğunda ancak yine de test edilmesi gerektiğinde
hideFromAccessibilitykullanın. - Üst ve alt semantiğin tüm hizmetler için temizlenmesi gerektiğinde boş bir lambda ile
clearAndSetSemantics{}kullanın. - Bir bileşenin semantiğinin manuel olarak ayarlanması gerektiğinde lambda içindeki içerikle birlikte
clearAndSetSemantics{/*content*/}kullanın.
- İçerik muhtemelen dekoratif veya gereksiz olduğunda ancak yine de test edilmesi gerektiğinde
- İçeriğin tek bir varlık olarak ele alınması gerektiğinde ve tüm alt öğelerinin bilgilerinin eksiksiz olması gerektiğinde:
- Anlamsal alt öğeleri birleştirme özelliğini kullanın.
Sizin için önerilenler
- Not: JavaScript devre dışı bırakıldığında bağlantı metni gösterilir.
- Compose'da erişilebilirlik
- [Compose'da Materyal Tasarım 2][19]
- Compose düzeninizi test etme