Geçiş sırasını kontrol etme

Varsayılan olarak, Compose uygulamasındaki erişilebilirlik ekran okuyucu davranışı uygulanır beklenen okuma düzeninde, (genellikle soldan sağa, sonra yukarıdan aşağıya) Ancak algoritmanın belirleyemeyeceği bazı uygulama düzeni türleri vardır. gerçek okuma sırasını değiştirebilirsiniz. Görüntülemeye dayalı uygulamalarda şunları yapabilirsiniz: traversalBefore ve traversalAfter özelliklerini kullanarak bu tür sorunları düzeltin. Compose 1.5'ten itibaren Compose eşit derecede esnek bir API sağlıyor. kavramsal model olduğunu düşünebiliriz.

isTraversalGroup ve traversalIndex, şu anlamlara gelen semantik özelliklerdir: Böylece, uygun değildir. isTraversalGroup, kendini tanımlar anlamsal olarak önemli gruplar, traversalIndex ise sıralamayı ayarlar ayrı ayrı ele alabilirsiniz. isTraversalGroup öğesini tek başına kullanabilirsiniz, veya daha fazla özelleştirme için traversalIndex ile.

isTraversalGroup ve traversalIndex özelliklerini şurada kullanın: uygulamasını kullanın.

Öğeleri isTraversalGroup ile gruplandır

isTraversalGroup, bir anlamsal bağlamın geçerli olup olmadığını tanımlayan bir boole özelliğidir. düğüm bir geçiş grubudur. Bu düğüm türü, işlevi bir sınır veya sınır olarak kullanın.

Bir düğümde isTraversalGroup = true politikasının ayarlanması, o düğümün tüm alt öğelerinin diğer öğelere geçmeden önce ziyaret edildiğini gösterir. isTraversalGroup hizmetini şurada ayarlayabilirsiniz: Sütunlar, Satırlar veya Kutular gibi ekran okuyucusu olmayan odaklanılabilir düğümler.

Aşağıdaki örnekte isTraversalGroup kullanılmaktadır. Dört metin öğesi yayınlar. İlgili içeriği oluşturmak için kullanılan soldaki iki öğe bir CardBox öğesine ait, sağdaki iki öğe başka bir CardBox öğesine ait:

// CardBox() function takes in top and bottom sample text.
@Composable
fun CardBox(
    topSampleText: String,
    bottomSampleText: String,
    modifier: Modifier = Modifier
) {
    Box(modifier) {
        Column {
            Text(topSampleText)
            Text(bottomSampleText)
        }
    }
}

@Composable
fun TraversalGroupDemo() {
    val topSampleText1 = "This sentence is in "
    val bottomSampleText1 = "the left column."
    val topSampleText2 = "This sentence is "
    val bottomSampleText2 = "on the right."
    Row {
        CardBox(
            topSampleText1,
            bottomSampleText1
        )
        CardBox(
            topSampleText2,
            bottomSampleText2
        )
    }
}

Kod, aşağıdakine benzer bir çıkış üretir:

Soldaki sütunda "Bu" yazan, iki sütunlu düzen
  cümle sol sütundadır ve sağ sütunda 'Bu cümle sağda'dır.
Şekil 1. İki cümleden oluşan bir düzen (biri sol tarafta olmalıdır) sütununda, diğeri sağ sütunda) gösterilir.

Herhangi bir semantik ayarlanmadığından ekran okuyucunun varsayılan davranışı öğeleri soldan sağa ve yukarıdan aşağıya doğru kaydırın. İşte bu yüzden varsayılan olarak TalkBack cümle parçalarını yanlış sırayla okur:

"Bu cümlenin metni:" → "Bu cümle" → "sol sütun"a dokunun. → " sağ."

Parçaları doğru bir şekilde sıralamak için orijinal snippet'i isTraversalGroup - true:

@Composable
fun TraversalGroupDemo2() {
    val topSampleText1 = "This sentence is in "
    val bottomSampleText1 = "the left column."
    val topSampleText2 = "This sentence is"
    val bottomSampleText2 = "on the right."
    Row {
        CardBox(
//      1,
            topSampleText1,
            bottomSampleText1,
            Modifier.semantics { isTraversalGroup = true }
        )
        CardBox(
//      2,
            topSampleText2,
            bottomSampleText2,
            Modifier.semantics { isTraversalGroup = true }
        )
    }
}

isTraversalGroup her CardBox için özel olarak ayarlandığından, CardBox öğeleri sıralarken geçerli olan bazı sınırlardır. Bu örnekte sol Önce CardBox, ardından doğru CardBox okunur.

TalkBack artık cümle parçalarını doğru sırada sesli okuyor:

"Bu cümlenin metni:" → "sol sütun"a dokunun. → "Bu cümle" → " sağ."

Geçiş sırasını daha da özelleştirin

traversalIndex, TalkBack'i özelleştirmenize olanak tanıyan bir kayan özelliktir. sağlar. Öğeleri gruplamak TalkBack için yeterli değilse çalışması için traversalIndex öğesini Ekran okuyucunun sıralamasını daha da özelleştirmek için isTraversalGroup kullanın.

traversalIndex özelliği aşağıdaki özelliklere sahiptir:

  • Daha düşük traversalIndex değerlerine sahip öğelere öncelik verilir.
  • Olumlu veya olumsuz olabilir.
  • Varsayılan değer 0f değeridir.
  • Yalnızca ekran okuyucuya odaklanılabilir düğümleri etkiler. Örneğin, metin veya düğmeler. Örneğin, bir sütun için yalnızca traversalIndex ayarlanması, sütunda isTraversalGroup değeri de ayarlanmadığı sürece herhangi bir etkisi olmaz.

Aşağıdaki örnekte, traversalIndex ve isTraversalGroup birlikte.

Örnek: Çapraz saat kadranı

Kadran, standart geçiş sırasının standart gezinmeden farklı olduğu yaygın bir senaryodur. iş yeri. Bu bölümdeki örnek, bir kullanıcının saat kadranındaki sayılara bakıp saat ve dakika için rakamları seçin yuvalar.

Üzerinde saat seçici bulunan saat kadranı.
Şekil 2. Saat kadranı resmi.

Aşağıdaki basitleştirilmiş snippet'te, içinde 12 bölümün bulunduğu bir CircularLayout sayılar, 12'den başlayıp saat yönünde çemberin etrafında olacak şekilde çizilir:

@Composable
fun ClockFaceDemo() {
    CircularLayout {
        repeat(12) { hour ->
            ClockText(hour)
        }
    }
}

@Composable
private fun ClockText(value: Int) {
    Box(modifier = Modifier) {
        Text((if (value == 0) 12 else value).toString())
    }
}

Saat kadranı, varsayılan soldan sağa ve 100'den fazla metin olacak şekilde üstten alta doğru sıraladığınızda, TalkBack rakamları sırasıyla okuyor. Düzeltmek için bunun için aşağıdaki snippet'te gösterildiği gibi artan sayaç değerini kullanın:

@Composable
fun ClockFaceDemo() {
    CircularLayout(Modifier.semantics { isTraversalGroup = true }) {
        repeat(12) { hour ->
            ClockText(hour)
        }
    }
}

@Composable
private fun ClockText(value: Int) {
    Box(modifier = Modifier.semantics { this.traversalIndex = value.toFloat() }) {
        Text((if (value == 0) 12 else value).toString())
    }
}

Geçiş sıralamasını doğru şekilde ayarlamak için önce CircularLayout öğesini a bir geçiş grubu oluşturun ve isTraversalGroup = true değerini ayarlayın. Sonra, her bir saat metni düzene çizildiğinde karşılık gelen traversalIndex değerini sayaca ayarlayın değer.

Sayaç değeri sürekli olarak arttığından, her saat değeri Ekrana sayı eklendikçe traversalIndex büyür (saat değeri 0) traversalIndex değeri 0, saat değerinin traversalIndex değeri 1 olarak gösterilir. Böylece TalkBack'in bunları okuma sırası ayarlanmış olur. Şimdi sayılar CircularLayout içindeki öğeler beklenen sırada okunur.

Çünkü ayarlanan traversalIndexes yalnızca diğer aynı gruplandırma içinde olduğu için, ekran sıralamasının geri kalanı korunuyor. Başka bir deyişle, önceki kodda gösterilen anlamsal değişiklikler saat kadranındaki sıralamayı yalnızca isTraversalGroup = true ayarlandı.

CircularLayout's anlamı isTraversalGroup = true olarak ayarlanmadığında traversalIndex değişikliklerinin geçerli olacağını unutmayın. Ancak, Bağlamak için CircularLayout, saat kadranının on iki hanesi okunur ekrandaki diğer tüm öğeler ziyaret edildikten sonra. Bu işlem çünkü diğer tüm öğelerin varsayılan traversalIndex değeri 0f ve saat metin öğeleri, diğer tüm 0f öğelerinden sonra okunur.

Örnek: Kayan işlem düğmesi için geçiş sırasını özelleştirme

Bu örnekte traversalIndex ve isTraversalGroup, Materyal Tasarım kayan işlem düğmesinin (FAB) geçiş sıralaması. Temel aşağıdaki düzeni kullanabilirsiniz:

Üst uygulama çubuğu, örnek metin, kayan işlem düğmesi ve
  uygulama çubuğunda görünür.
Şekil 3. Üst uygulama çubuğu, örnek metin, kayan işlem düğmesi ve ve alt uygulama çubuğu.

Varsayılan olarak bu örnekteki düzen aşağıdaki TalkBack sırasına sahiptir:

Üst Uygulama Çubuğu → 0 ile 6 arasındaki örnek metinler → kayan işlem düğmesi (FAB) → Alt Uygulama Çubuğu

Ekran okuyucunun önce FAB'ye odaklanmasını isteyebilirsiniz. Bir traversalIndex işlemini FAB gibi bir Material öğesinde yapın:

@Composable
fun FloatingBox() {
    Box(modifier = Modifier.semantics { isTraversalGroup = true; traversalIndex = -1f }) {
        FloatingActionButton(onClick = {}) {
            Icon(imageVector = Icons.Default.Add, contentDescription = "fab icon")
        }
    }
}

Bu snippet'te, isTraversalGroup, true olarak ayarlandı ve aynı kutuda bir traversalIndex ayarlandı (-1f, 0f varsayılan değerinden küçüktür), kayan kutunun ekrandaki diğer tüm öğelerden önce gelir.

Daha sonra, kayan kutuyu ve diğer öğeleri bir yapı iskelesinin içine yerleştirebilirsiniz. Materyal Tasarım düzeni uygulanır:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ColumnWithFABFirstDemo() {
    Scaffold(
        topBar = { TopAppBar(title = { Text("Top App Bar") }) },
        floatingActionButtonPosition = FabPosition.End,
        floatingActionButton = { FloatingBox() },
        content = { padding -> ContentColumn(padding = padding) },
        bottomBar = { BottomAppBar { Text("Bottom App Bar") } }
    )
}

TalkBack öğelerle aşağıdaki sırayla etkileşim kurar:

FAB → Üst Uygulama Çubuğu → 0-6 arasındaki örnek metinler → Alt Uygulama Çubuğu

Ek kaynaklar