Bir composable'ın taşıdığı birincil bilgilerin (ör. Text composable'ın metin dizesi) yanı sıra kullanıcı arayüzü öğeleri hakkında daha fazla ek bilgiye sahip olmak faydalı olabilir.
Compose'da bir bileşenin anlamı ve rolü hakkındaki bilgilere semantik denir. Semantik, erişilebilirlik, otomatik doldurma ve test gibi hizmetlere composable'lar hakkında ek bağlam sağlamanın bir yoludur. Örneğin, kamera simgesi görsel olarak yalnızca bir resim olabilir ancak semantik anlamı "Fotoğraf çek" olabilir.
Uygun semantiği uygun Compose API'leriyle birleştirerek bileşeniniz hakkında mümkün olduğunca fazla bilgiyi erişilebilirlik hizmetlerine sağlarsınız. Bu hizmetler de bileşenin kullanıcıya nasıl sunulacağına karar verir.
Material ve Compose kullanıcı arayüzü ve Foundation API'leri, belirli rol ve işlevlerine uygun yerleşik semantiklerle birlikte gelir. Ancak bu semantikleri mevcut API'ler için değiştirebilir veya özel bileşenler için yeni semantikler ayarlayabilirsiniz.
Semantik özellikler
Semantik özellikler, ilgili composable'ın anlamını ifade eder. Örneğin, Text composable'ı, text semantik özelliğini içerir çünkü bu composable'ın anlamı budur. Icon, simgenin anlamını metin olarak ileten bir contentDescription özelliği (geliştirici tarafından ayarlanmışsa) içerir.
Semantik özelliklerin, bir composable'ın anlamını nasıl ilettiğini düşünün. Switch düşünün. Kullanıcıya şu şekilde görünür:
Switch "Açık" ve "Kapalı" durumunda.Bu öğenin anlamını açıklamak için şunları söyleyebilirsiniz: "Bu, 'Açık' durumunda açılıp kapatılabilen bir anahtardır. Etkileşimde bulunmak için tıklayabilirsiniz."
Semantik özellikler tam olarak bu amaçla kullanılır. Bu Switch öğesinin semantik düğümü, Layout Inspector ile görselleştirildiği gibi aşağıdaki özellikleri içerir:
Switch composable'ının Semantics özelliklerini gösteren Layout Inspector.Role, öğenin türünü belirtir. StateDescription, "Açık" durumuna nasıl referans verilmesi gerektiğini açıklar. Varsayılan olarak bu, "Açık" kelimesinin yerelleştirilmiş bir sürümüdür ancak bağlama göre daha spesifik hale getirilebilir (örneğin, "Etkin"). ToggleableState, anahtarın mevcut durumudur. OnClick özelliği, bu öğeyle etkileşimde bulunmak için kullanılan yönteme referans verir.
Uygulamanızdaki her bir composable'ın semantik özelliklerini takip etmek, birçok güçlü olasılığın kilidini açar:
- Erişilebilirlik hizmetleri, ekranda gösterilen kullanıcı arayüzünü temsil etmek ve kullanıcıların bu arayüzle etkileşimde bulunmasına olanak tanımak için özellikleri kullanır. Switch composable'ı için Talkback, "Açık; Switch; açmak/kapatmak için iki kez dokunun" diyebilir. Kullanıcı, anahtarı kapatmak için ekranına iki kez dokunabilir.
-
Test çerçevesi, düğümleri bulmak, onlarla etkileşim kurmak ve iddialarda bulunmak için özellikleri kullanır:
val mySwitch = SemanticsMatcher.expectValue( SemanticsProperties.Role, Role.Switch ) composeTestRule.onNode(mySwitch) .performClick() .assertIsOff()
Compose temel kitaplığı üzerine oluşturulan composable'lar ve değiştiriciler, ilgili özellikleri varsayılan olarak sizin için ayarlar. İsterseniz belirli kullanım alanları için erişilebilirlik desteğini iyileştirmek amacıyla bu özellikleri manuel olarak değiştirebilir veya composable'larınızın birleştirme ya da temizleme stratejisini değiştirebilirsiniz.
Bileşeninizin belirli içerik türünü erişilebilirlik hizmetlerine bildirmek için çeşitli semantikler uygulayabilirsiniz. Bu eklemeler, mevcut ana semantik bilgileri destekler ve erişilebilirlik hizmetlerinin bileşeninizin nasıl temsil edildiğini, duyurulduğunu veya etkileşimde bulunulduğunu hassas bir şekilde ayarlamasına yardımcı olur.
Semantik özelliklerin tam listesi için SemanticsProperties nesnesine bakın. Olası erişilebilirlik işlemlerinin tam listesi için SemanticsActions nesnesine bakın.
Başlıklar
Uygulamalarda genellikle uzun makaleler veya haber sayfaları gibi metin açısından zengin içeriklere sahip ekranlar bulunur. Bu ekranlar genellikle başlıklarla farklı alt bölümlere ayrılır:
Erişilebilirlik ihtiyaçları olan kullanıcılar bu tür bir ekranda kolayca gezinmekte zorlanabilir. Bazı erişilebilirlik hizmetleri, gezinme deneyimini iyileştirmek için doğrudan bölümler veya başlıklar arasında daha kolay gezinme imkanı sunar. Bunu etkinleştirmek için semantik özelliğini tanımlayarak bileşeninizin heading olduğunu belirtin:
@Composable private fun Subsection(text: String) { Text( text = text, style = MaterialTheme.typography.headlineSmall, modifier = Modifier.semantics { heading() } ) }
Uyarılar ve pop-up'lar
Bileşeniniz Snackbar gibi bir uyarı veya pop-up ise erişilebilirlik hizmetlerine yeni bir yapının veya içerik güncellemelerinin kullanıcılara iletilebileceğini bildirmek isteyebilirsiniz.
Uyarı benzeri bileşenler liveRegion semantik özelliğiyle işaretlenebilir. Bu sayede erişilebilirlik hizmetleri, bu bileşende veya alt öğelerinde yapılan değişiklikleri kullanıcıya otomatik olarak bildirebilir:
PopupAlert( message = "You have a new message", modifier = Modifier.semantics { liveRegion = LiveRegionMode.Polite } )
Kullanıcıların dikkatini ekrandaki uyarılara veya önemli değişikliklere kısa süreliğine çekmek istediğiniz çoğu durumda liveRegionMode.Polite kullanmalısınız.
Rahatsız edici geri bildirimleri önlemek için liveRegion.Assertive özelliğini dikkatli kullanmanız gerekir.
Kullanıcıların zamana duyarlı içeriklerden haberdar olmasının çok önemli olduğu durumlarda kullanılmalıdır:
PopupAlert( message = "Emergency alert incoming", modifier = Modifier.semantics { liveRegion = LiveRegionMode.Assertive } )
Kullanıcıları sürekli geri bildirimlerle bunaltmamak için geri sayım zamanlayıcıları gibi sık sık güncellenen içeriklerde canlı bölgeler kullanılmamalıdır.
Pencere benzeri bileşenler
ModalBottomSheet gibi pencere benzeri özel bileşenlerin, çevrelerindeki içerikten ayırt edilebilmesi için ek sinyallere ihtiyacı vardır. Bunun için paneTitle semantiğini kullanabilirsiniz. Böylece, ilgili pencere veya bölme değişiklikleri, ana semantik bilgileriyle birlikte erişilebilirlik hizmetleri tarafından uygun şekilde temsil edilebilir:
ShareSheet( message = "Choose how to share this photo", modifier = Modifier .fillMaxWidth() .align(Alignment.TopCenter) .semantics { paneTitle = "New bottom sheet" } )
Referans için Material 3'ün bileşenleri için paneTitle nasıl kullandığını inceleyin.
Hata bileşenleri
Hata benzeri bileşenler gibi diğer içerik türlerinde, erişilebilirlik ihtiyaçları olan kullanıcılar için ana semantik bilgileri genişletmek isteyebilirsiniz.
Hata durumlarını tanımlarken erişilebilirlik hizmetlerini error semantiği hakkında bilgilendirebilir ve genişletilmiş hata mesajları sağlayabilirsiniz.
Bu örnekte TalkBack, ana hata metni bilgilerini ve ardından ek, genişletilmiş mesajları okur:
Error( errorText = "Fields cannot be empty", modifier = Modifier .semantics { error("Please add both email and password") } )
İlerleme durumu izleme bileşenleri
İlerlemeyi takip eden özel bileşenler için kullanıcıları, mevcut ilerleme değeri, aralığı ve adım boyutu dahil olmak üzere ilerleme değişiklikleri hakkında bilgilendirmek isteyebilirsiniz. Bunu progressBarRangeInfo semantiğiyle yapabilirsiniz. Bu sayede erişilebilirlik hizmetleri, ilerleme durumu değişikliklerinden haberdar olur ve kullanıcıları buna göre güncelleyebilir. Farklı yardımcı teknolojiler, ilerleme durumunun artışını ve azalışını belirtmek için farklı yöntemler kullanabilir.
ProgressInfoBar( modifier = Modifier .semantics { progressBarRangeInfo = ProgressBarRangeInfo( current = progress, range = 0F..1F ) } )
Liste ve öğe bilgileri
Çok sayıda öğe içeren özel listelerde ve tablolarda, erişilebilirlik hizmetlerinin toplam öğe sayısı ve dizinler gibi daha ayrıntılı bilgiler alması da faydalı olabilir.
Bu uzun listede, listede ve öğelerde sırasıyla collectionInfo ve collectionItemInfo semantiği kullanılarak erişilebilirlik hizmetleri, kullanıcılara metin tabanlı semantik bilgilerin yanı sıra toplam koleksiyondaki hangi öğe dizininde olduklarını bildirebilir:
MilkyWayList( modifier = Modifier .semantics { collectionInfo = CollectionInfo( rowCount = milkyWay.count(), columnCount = 1 ) } ) { milkyWay.forEachIndexed { index, text -> Text( text = text, modifier = Modifier.semantics { collectionItemInfo = CollectionItemInfo(index, 0, 0, 0) } ) } }
Durum açıklaması
Bir composable, Android çerçevesinin composable'ın içinde bulunduğu durumu okumak için kullandığı semantikler için bir stateDescription tanımlayabilir. Örneğin, açma/kapatma düğmesi olan bir composable "işaretli" veya "işaretlenmemiş" durumda olabilir. Bazı durumlarda, Compose'un kullandığı varsayılan durum açıklaması etiketlerini geçersiz kılmak isteyebilirsiniz. Bunu yapmak için, bir composable'ı açma/kapatma olarak tanımlamadan önce durum açıklaması etiketlerini açıkça belirtmeniz gerekir:
@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() } ) ) { /* ... */ } }
Özel işlemler
Özel işlemler, kapatmak için kaydırma veya sürükle ve bırak gibi daha karmaşık dokunmatik ekran hareketleri için kullanılabilir. Bu hareketler, motor bozuklukları veya diğer engelleri olan kullanıcıların etkileşim kurması açısından zor olabilir.
Kaydırarak kapatma hareketini daha erişilebilir hale getirmek için özel bir işleme bağlayabilir, kapatma işlemini ve etiketi buraya iletebilirsiniz:
SwipeToDismissBox( modifier = Modifier.semantics { // Represents the swipe to dismiss for accessibility customActions = listOf( CustomAccessibilityAction( label = "Remove article from list", action = { removeArticle() true } ) ) }, state = rememberSwipeToDismissBoxState(), backgroundContent = {} ) { ArticleListItem() }
TalkBack gibi bir erişilebilirlik hizmeti, bileşeni vurgular ve menüsünde daha fazla işlem olduğunu belirtir. Bu işlemler, kaydırarak kapatma işlemini temsil eder:
Özel işlemlerin bir başka kullanım alanı da, daha fazla kullanılabilir işlem içeren öğelerin bulunduğu uzun listelerdir. Kullanıcıların her bir öğe için her işlemi tek tek yinelemesi sıkıcı olabilir:
Gezinme deneyimini iyileştirmek için (özellikle Anahtar Erişimi veya Sesli Erişim gibi etkileşime dayalı yardımcı teknolojiler için faydalıdır) kapsayıcıda özel işlemler kullanarak işlemleri ayrı bir işlem menüsüne taşıyabilirsiniz:
ArticleListItemRow( modifier = Modifier .semantics { customActions = listOf( CustomAccessibilityAction( label = "Open article", action = { openArticle() true } ), CustomAccessibilityAction( label = "Add to bookmarks", action = { addToBookmarks() true } ), ) } ) { Article( modifier = Modifier.clearAndSetSemantics { }, onClick = openArticle, ) BookmarkButton( modifier = Modifier.clearAndSetSemantics { }, onClick = addToBookmarks, ) }
Bu gibi durumlarda, alt öğeleri özel işlemlere taşıdığınız için clearAndSetSemantics değiştiricisiyle orijinal alt öğelerin semantiğini manuel olarak temizlediğinizden emin olun.
Anahtar Erişimi'ni örnek olarak kullanırsak kapsayıcı seçildiğinde menüsü açılır ve mevcut iç içe yerleştirilmiş işlemler burada listelenir:
Semantik ağacı
Oluşturma, uygulamanızın kullanıcı arayüzünü tanımlar ve composable'lar çalıştırılarak oluşturulur. Oluşturma, kullanıcı arayüzünüzü açıklayan composable'lardan oluşan bir ağaç yapısıdır.
Oluşturma'nın yanında, semantik ağacı adı verilen paralel bir ağaç bulunur. Bu ağaç, kullanıcı arayüzünüzü Erişilebilirlik hizmetleri ve Test çerçevesi tarafından anlaşılabilir alternatif bir şekilde açıklar. Erişilebilirlik hizmetleri, uygulamayı belirli bir ihtiyacı olan kullanıcılara açıklamak için ağacı kullanır. Test çerçevesi, uygulamanızla etkileşim kurmak ve uygulama hakkında iddialarda bulunmak için ağacı kullanır. Semantik ağacı, composable'larınızı nasıl çizeceğinizle ilgili bilgileri içermez ancak composable'larınızın semantik anlamı ile ilgili bilgileri içerir.
Uygulamanız, Compose Foundation ve Material kitaplığındaki composable'lar ve değiştiricilerden oluşuyorsa Semantics ağacı sizin için otomatik olarak doldurulur ve oluşturulur. Ancak özel alt düzey composable'lar eklerken semantiğini manuel olarak sağlamanız gerekir. Ağacınızın, ekrandaki öğelerin anlamını doğru veya tam olarak temsil etmediği durumlar da olabilir. Bu durumda ağacı uyarlayabilirsiniz.
Örneğin, aşağıdaki özel takvim composable'ını ele alalım:
Bu örnekte, takvimin tamamı tek bir alt düzey composable olarak uygulanır. Layout composable'ı kullanılır ve doğrudan Canvas üzerine çizim yapılır.
Başka bir işlem yapmazsanız erişilebilirlik hizmetleri, composable'ın içeriği ve kullanıcının takvimdeki seçimi hakkında yeterli bilgi almaz. Örneğin, kullanıcı 17'yi içeren günü tıklarsa erişilebilirlik çerçevesi yalnızca tüm takvim denetimi için açıklama bilgilerini alır. Bu durumda TalkBack erişilebilirlik hizmeti "Takvim" veya biraz daha iyi bir ifadeyle "Nisan Takvimi" duyurusunu yapar ve kullanıcı hangi günün seçildiğini merak eder. Bu composable'ı daha erişilebilir hale getirmek için semantik bilgileri manuel olarak eklemeniz gerekir.
Birleştirilmiş ve birleştirilmemiş ağaç
Daha önce de belirtildiği gibi, kullanıcı arayüzü ağacındaki her composable'da sıfır veya daha fazla semantik özellik ayarlanmış olabilir. Semantik özellikleri ayarlanmamış bir composable, semantik ağacına dahil edilmez. Bu sayede, semantik ağacı yalnızca semantik anlam içeren düğümleri içerir. Ancak bazen ekranda gösterilenlerin doğru anlamını iletmek için düğümlerin belirli alt ağaçlarını birleştirip tek bir ağaç olarak ele almak da yararlı olur. Böylece her bir alt düğümle ayrı ayrı ilgilenmek yerine bir düğüm kümesini bir bütün olarak değerlendirebilirsiniz. Genel bir kural olarak, bu ağaçtaki her düğüm, erişilebilirlik hizmetleri kullanılırken odaklanılabilir bir öğeyi temsil eder.
Bu tür bir composable'a örnek olarak Button verilebilir. Birden fazla alt düğüm içerse bile bir düğümü tek bir öğe olarak düşünebilirsiniz:
Button(onClick = { /*TODO*/ }) { Icon( imageVector = Icons.Filled.Favorite, contentDescription = null ) Spacer(Modifier.size(ButtonDefaults.IconSpacing)) Text("Like") }
Semantik ağacında, düğmenin alt öğelerinin özellikleri birleştirilir ve düğme, ağaçta tek bir yaprak düğüm olarak sunulur:
Oluşturulabilir öğeler ve değiştiriciler, Modifier.semantics
(mergeDescendants = true) {} öğesini çağırarak alt öğelerinin semantik özelliklerini birleştirmek istediklerini belirtebilir. Bu özelliğin true olarak ayarlanması, semantik özelliklerin birleştirilmesi gerektiğini gösterir. Button örneğinde, Button composable dahili olarak bu semantics değiştiriciyi içeren clickable değiştiricisini kullanır. Bu nedenle, düğmenin alt düğümleri birleştirilir.
Birleştirilebilir öğenizde birleştirme davranışını ne zaman değiştirmeniz gerektiği hakkında daha fazla bilgi edinmek için erişilebilirlik belgelerini okuyun.
Foundation ve Material Compose kitaplıklarındaki çeşitli değiştiriciler ve composable'lar bu özelliğe sahiptir. Örneğin, clickable ve toggleable değiştiricileri, alt öğelerini otomatik olarak birleştirir. Ayrıca ListItem composable'ı, alt öğelerini birleştirir.
Ağacı inceleme
Semantik ağacı aslında iki farklı ağaçtan oluşur. mergeDescendants, true olarak ayarlandığında alt düğümleri birleştiren birleştirilmiş bir Semantics ağacı vardır.
Ayrıca, birleştirme işlemini uygulamayan ancak her düğümü olduğu gibi tutan birleştirilmemiş bir Semantics ağacı da vardır. Erişilebilirlik hizmetleri, birleştirilmemiş ağacı kullanır ve mergeDescendants özelliğini dikkate alarak kendi birleştirme algoritmalarını uygular. Test çerçevesi, varsayılan olarak birleştirilmiş ağacı kullanır.
printToLog() yöntemini kullanarak her iki ağacı da inceleyebilirsiniz. Varsayılan olarak ve önceki örneklerde olduğu gibi birleştirilmiş ağaç günlüğe kaydedilir. Bunun yerine birleştirilmemiş ağacı yazdırmak için onRoot() eşleştiricisinin useUnmergedTree parametresini true olarak ayarlayın:
composeTestRule.onRoot(useUnmergedTree = true).printToLog("MY TAG")
Layout Inspector, görünüm filtresinde tercih edilen seçeneği belirleyerek hem birleştirilmiş hem de birleştirilmemiş Semantics ağacını görüntülemenize olanak tanır:
Layout Inspector, ağacınızdaki her düğüm için hem birleştirilmiş semantiği hem de özellikler panelinde bu düğümde ayarlanan semantiği gösterir:
Test çerçevesindeki eşleştiriciler, varsayılan olarak birleştirilmiş semantik ağacını kullanır.
Bu nedenle, Button ile etkileşim kurmak için içindeki metni eşleştirmeniz gerekir:
composeTestRule.onNodeWithText("Like").performClick()
Eşleştiricilerin useUnmergedTree parametresini true olarak ayarlayarak bu davranışı geçersiz kılabilirsiniz. Bu, onRoot eşleştiricisinde de geçerlidir.
Ağacı uyarlama
Daha önce de belirtildiği gibi, belirli semantik özelliklerini geçersiz kılabilir veya temizleyebilir ya da ağacın birleştirme davranışını değiştirebilirsiniz. Bu, özellikle kendi özel bileşenlerinizi oluştururken geçerlidir. Doğru özellikleri ve birleştirme davranışını ayarlamazsanız uygulamanıza erişilemeyebilir ve testler beklediğinizden farklı davranabilir. Test hakkında daha fazla bilgi edinmek istiyorsanız test kılavuzuna göz atı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
- Compose düzeninizi test etme