Oluşturulan Anlamsal Bilgiler

Beste, uygulamanızın kullanıcı arayüzünü tanımlar ve kompozisyonların çalıştırılmasıyla oluşturulur. Beste, kullanıcı arayüzünüzü açıklayan bestelerden oluşan bir ağaç yapısıdır.

Bestenin yanında, Anlamsal ağacı adı verilen paralel bir ağaç vardır. Bu ağaçta, kullanıcı arayüzünüz Erişilebilirlik hizmetleri ve Test çerçevesi için anlaşılabilir bir alternatif olarak açıklanmaktadır. 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 uygulamayla ilgili iddialarda bulunmak için bu bilgileri kullanır. Anlamsal ağacı, bestelerinizi nasıl çizeceğiniz hakkında bilgi içermez, ancak bestelerinizin anlamsal anlamı hakkında bilgi içerir.

Şekil 1. Tipik bir kullanıcı arayüzü hiyerarşisi ve anlambilim ağacı.

Uygulamanız, Compose temeli ve malzeme kitaplığındaki besteler ve değiştiricilerden oluşuyorsa Anlamsal ağacı sizin için otomatik olarak doldurulur ve oluşturulur. Ancak özel düşük seviyeli kompozisyon eklerken bunların anlamlarını manuel olarak sağlamanız gerekir. Ayrıca ağacınızın ekrandaki öğelerin anlamını doğru veya tam olarak yansıtmadığı durumlar da olabilir. Bu durumda ağacı uyarlayabilirsiniz.

Örneğin, şu özel takvim oluşturabilirsiniz:

2. Şekil. Seçilebilir gün öğeleriyle oluşturulabilen özel bir takvim.

Bu örnekte, tüm takvim Layout composable kullanılarak ve doğrudan Canvas öğesine çekilerek alt düzey bir oluşturma etkinliği olarak uygulanmıştır. Başka bir işlem yapmazsanız erişilebilirlik hizmetleri, oluşturulan öğenin içeriği ve kullanıcının takvimdeki seçimi hakkında yeterli bilgiyi almaz. Örneğin, bir kullanıcı 17. günü içeren günü tıklarsa erişilebilirlik çerçevesi yalnızca tüm takvim kontrolünün açıklama bilgilerini alır. Bu durumda, TalkBack erişilebilirlik hizmeti "Takvim"i veya daha da iyisi "Nisan Takvimi"ni duyurur ve kullanıcı hangi günün seçildiğini merak eder. Anlamsal bilgileri manuel olarak bu şekilde daha erişilebilir hale getirebilirsiniz.

Anlamsal özellikler

Kullanıcı arayüzü ağacındaki, anlamsal anlamlara sahip tüm düğümlerin anlambilim ağacında paralel bir düğümü vardır. Semantik ağacındaki düğüm, karşılık gelen composable öğesinin anlamını içeren özellikleri içerir. Örneğin, Text kompozisyonu text semantik özelliğini içerir çünkü bu, composable öğesinin anlamını ifade eder. Icon, metinde Icon öğesinin anlamını ileten bir contentDescription özelliği (geliştirici tarafından ayarlandıysa) içerir. Compose temel kitaplığı üzerine oluşturulan besteler ve değiştiriciler, alakalı özellikleri sizin için zaten ayarlar. İsteğe bağlı olarak, özellikleri semantics ve clearAndSetSemantics değiştiricileriyle kendiniz ayarlayabilir veya geçersiz kılabilirsiniz. Örneğin, bir düğüme özel erişilebilirlik işlemleri ekleyebilir, açılabilir bir öğe için alternatif bir durum açıklaması sağlayabilir veya oluşturulan belirli bir metnin başlık olarak değerlendirilmesi gerektiğini belirtebilirsiniz.

Semantik ağacını görselleştirmek için Layout Inspector aracını veya testlerimizin içinde printToLog() yöntemini kullanabiliriz. Bu işlem, Logcat'in içindeki mevcut Semantics ağacını yazdırır.

class MyComposeTest {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun MyTest() {
        // Start the app
        composeTestRule.setContent {
            MyTheme {
                Text("Hello world!")
            }
        }
        // Log the full semantics tree
        composeTestRule.onRoot().printToLog("MY TAG")
    }
}

Bu testin sonucu şöyle olur:

    Printing with useUnmergedTree = 'false'
    Node #1 at (l=0.0, t=63.0, r=221.0, b=120.0)px
     |-Node #2 at (l=0.0, t=63.0, r=221.0, b=120.0)px
       Text = '[Hello world!]'
       Actions = [GetTextLayoutResult]

Anlamsal özelliklerin, bir beste öğesinin anlamını aktarmak için nasıl kullanıldığını görmek üzere bir örneğe göz atalım. Şimdi bir Switch düşünelim. Kullanıcıya şöyle görünür:

3. Şekil. "Açık" ve "Kapalı" durumundaki bir anahtar.

Bu öğenin anlamını açıklamak için şöyle diyebilirsiniz: "Bu, geçiş yapılabilir bir öğe olan ve şu anda 'Açık' durumunda olan bir anahtar. Etkileşimde bulunmak için simgeyi tıklayabilirsiniz."

Anlamsal özellikler tam olarak bunun için kullanılır. Bu Switch öğesinin anlamsal düğümü, Düzen İnceleyici ile görselleştirildiği gibi aşağıdaki özellikleri içerir:

4. Şekil. Oluşturulan bir Switch'in Semantik özelliklerini gösteren Düzen İnceleyici.

Role, baktığımız öğenin türünü gösterir. StateDescription, "Açık" durumuna nasıl referans verilmesi gerektiğini açıklar. Varsayılan olarak bu, "Açık" kelimesinin yerelleştirilmiş bir halidir ancak bağlama göre daha spesifik hale getirilebilir (ör. "Etkin"). ToggleableState, Switch'in mevcut durumudur. OnClick özelliği, bu öğeyle etkileşim kurmak için kullanılan yöntemi belirtir. Anlamsal özelliklerin tam listesi için SemanticsProperties nesnesine göz atın. Kullanılabilecek Erişilebilirlik İşlemlerinin tam listesi için SemanticsActions nesnesine göz atın.

Uygulamanızda oluşturulan her bir kompozisyonun anlamsal özelliklerini takip etmek, birçok güçlü olasılığın önünü açar. Birkaç örnek:

  • TalkBack, ekranda gösterilenleri sesli okumak için özellikleri kullanır ve kullanıcının ekranda sorunsuz bir şekilde etkileşimde bulunmasına olanak tanır. Anahtarımız için "Açık; Anahtar; açmak/kapatmak için iki kez dokunun" yazabilir. Kullanıcı, Anahtar'ı kapatmak için ekranına iki kez dokunabilir.
  • Test çerçevesi, düğümleri bulmak, bunlarla etkileşim kurmak ve iddialarda bulunmak için özellikleri kullanır. Switch için örnek bir test şöyle olabilir:
    val mySwitch = SemanticsMatcher.expectValue(
        SemanticsProperties.Role, Role.Switch
    )
    composeTestRule.onNode(mySwitch)
        .performClick()
        .assertIsOff()

Birleştirilmiş ve ayrılmış Semantik ağacı

Daha önce belirtildiği gibi, kullanıcı arayüzü ağacındaki her bir oluşturma işlemi sıfır veya daha fazla semantik özelliğine sahip olabilir. Anlamsal bir özellik ayarlanmamışsa Anlamsal ağacın parçası olarak dahil edilmez. Bu şekilde, Anlamsal ağacı yalnızca gerçekten anlamsal anlam içeren düğümleri içerir. Bununla birlikte, bazen ekranda gösterilenin doğru anlamını aktarmak için bazı düğümlerin alt ağaçlarını birleştirmek ve bunları tek bir ağ olarak ele almak da yararlıdır. Bu şekilde, her alt düğümle tek tek uğraşmak yerine bir düğüm kümesini bir bütün olarak değerlendirebiliriz. Genel kural olarak, bu ağaçtaki her düğüm Erişilebilirlik hizmetleri kullanılırken odaklanılabilir bir öğeyi temsil eder.

Böyle bir kompozisyona örnek olarak Button verilebilir. Düğmeyi, birden fazla alt düğüm içeriyor olsa da tek bir öğe olarak ele almak istiyoruz:

Button(onClick = { /*TODO*/ }) {
    Icon(
        imageVector = Icons.Filled.Favorite,
        contentDescription = null
    )
    Spacer(Modifier.size(ButtonDefaults.IconSpacing))
    Text("Like")
}

Anlamsal ağacımızda, 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) {} çağrısı yaparak alt öğelerinin semantik özelliklerini birleştirmek istediklerini belirtebilir. Bu özelliğin true değerine ayarlanması, anlamsal özelliklerin birleştirilmesi gerektiğini gösterir. Button örneğimizde composable, bu semantics değiştiricisini içeren clickable değiştiricisini dahili olarak kullanır.Button Bu nedenle, Düğmenin alt düğümleri birleştirilir. Oluşturulan dosyanızdaki birleştirme davranışını ne zaman değiştirmeniz gerektiği hakkında daha fazla bilgi edinmek için erişilebilirlik dokümanlarını okuyun.

Temel ve Malzeme Oluşturma kitaplıklarındaki çeşitli değiştiriciler ve birleştirilebilir öğeler bu özellik kümesine sahiptir. Örneğin, clickable ve toggleable değiştiricileri, alt öğelerini otomatik olarak birleştirir. Ayrıca, ListItem kompozisyonu alt öğelerini birleştirir.

Ağaçları inceleme

Semantik ağacı söz konusu olduğunda, aslında iki farklı ağaçtan bahsediyoruz. mergeDescendants, true olarak ayarlandığında alt düğümleri birleştiren birleştirilmiş bir Semantik ağacı vardır. Ayrıca, birleştirmeyi uygulamayan ancak tüm düğümleri sağlam tutan birleştirilmemiş bir anlamsal ağaç vardır. Erişilebilirlik hizmetleri birleştirilen 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.

Her iki ağacı da printToLog() yöntemiyle inceleyebilirsiniz. Varsayılan olarak ve önceki örneklerde olduğu gibi, birleştirilen ağaç günlüğe kaydedilir. Bunun yerine, ayrılmamış ağacı yazdırmak için onRoot() eşleştiricinin useUnmergedTree parametresini true değerine ayarlayın:

composeTestRule.onRoot(useUnmergedTree = true).printToLog("MY TAG")

Düzen İnceleyici, görünüm filtresinde tercih edilen ağacı seçerek hem birleştirilmiş hem de ayrılmış Anlamsal ağacını görüntülemenizi sağlar:

5.Şekil Hem birleştirilmiş hem de ayrılmamış Semantik ağacının görüntülenmesine olanak tanıyan Düzen İnceleyici görünüm seçenekleri.

Düzen İnceleyici, ağacınızdaki her bir düğüm için özellikler panelinde o düğümde hem Birleştirilmiş Anlamsal hem de Anlamsal ayarları gösterir:

Test Çerçevesi'ndeki eşleştiriciler, varsayılan olarak birleştirilmiş Semantik ağacını kullanır. Bu nedenle, içinde gösterilen metinle eşleşen bir düğmeyle etkileşimde bulunabilirsiniz:

composeTestRule.onNodeWithText("Like").performClick()

Daha önce onRoot eşleştiricide yaptığımız gibi, eşleyicilerin useUnmergedTree parametresini true olarak ayarlayarak bu davranışı geçersiz kılabilirsiniz.

Birleştirme davranışı

composable, alt öğelerinin birleştirilmesi gerektiğini belirtiyorsa bu birleştirme işlemi tam olarak nasıl gerçekleşir?

Her anlamsal mülkün tanımlanmış bir birleştirme stratejisi vardır. Örneğin, ContentDescription özelliği, tüm alt ContentDescription değerlerini bir listeye ekler. Bir anlamsal mülkün birleştirme stratejisini, SemanticsProperties.kt içinde mergePolicy uygulamasını kontrol ederek kontrol edebilirsiniz. Mülkler her zaman üst veya alt değeri seçmeyi, değerleri bir liste veya dizede birleştirmeyi, birleştirmeye hiçbir şekilde izin vermemeyi ve bunun yerine istisna belirlemeyi ya da başka bir özel birleştirme stratejisini kullanmayı seçebilir.

Önemli bir not, kendi ayarladıkları mergeDescendants = true alt öğelerinin birleştirmeye dahil edilmemesidir. Bir örnekle açıklayalım:

6.Şekil Resim, metin ve yer işareti simgesi içeren liste öğesi.

Burada tıklanabilir bir liste öğesi var. Kullanıcı satıra bastığında uygulama, kullanıcının makaleyi okuyabileceği makale ayrıntıları sayfasına yönlendirilir. Liste öğesinin içinde, bu makaleye yer işareti koymak için bir düğme bulunmaktadır. Bu örnekte, iç içe yerleştirilmiş bir tıklanabilir öğemiz vardır. Dolayısıyla düğme, birleştirilmiş ağaçta ayrı olarak görünür. Satırdaki içeriğin geri kalanı birleştirilir:

7. Şekil. Birleştirilmiş ağaç, Satır düğümünün içindeki bir listede birden çok metin içeriyor. Ayrılmış ağaç, oluşturulacak her Metin için ayrı düğümler içerir.

Anlamsal ağacı uyarlama

Daha önce belirtildiği gibi, belirli anlamsal özellikleri 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ız erişilebilir olmayabilir ve testler beklediğinizden farklı davranabilir. Semantik ağacını uyarlamanız gereken bazı yaygın kullanım alanları hakkında daha fazla bilgi edinmek için erişilebilirlik belgelerini okuyun. Test hakkında daha fazla bilgi için Test Kılavuzu'na göz atın.