'Image without content description using Compose

In my app that only uses Jetpack Compose, I want show an image without a content description. The goal of this element is specifically to show how not to do it; I want TalkBack to pronounce it as 'unlabeled' and any other AccessibilityService to handle it like that service handles it. Therefore, the service needs to receive an AccessibilityNodeInfo node with as class name "android.widget.ImageView" and contentDescription = null

Google tried their very best to prevent developers from creating a bad experience for visually impaired and succeeded. An image without a content description is removed from the semantics tree and is not read out; an AccessibilitityService will not be aware of it:

Image(
    painter = painter,
    contentDescription = null
)

Mimicking Image() and manually setting the Role to Image and not setting a description also removes it from the semantics tree:

Layout(
    {},
    modifier
        .semantics { this.role = Role.Image }
        .paint(painter)
) { _, constraints ->
    layout(constraints.minWidth, constraints.minHeight) {}
}

Also when I use an xml layout containing an ImageView without a content description, this does not show as an element to any accessibility services.

Compose implements MyNodeProvider, an AccessibilityNodeProvider which is Androids bridge between an accessibility service and an app. This is the class that populates the AccessibilityNodeInfo with a description or removes it from the tree. Because this is private, this cannot be altered.

Is it possible with Compose for an element to show up as "android.widget.ImageView" with contentDescription = null?



Solution 1:[1]

If you want TalkBack to pronounce it as 'unlabeled', wouldn't setting the content description to 'unlabeled' be the way to go?

The question is not much clear, but if you want the content to be identified as nothing special or interactive with TalkBack, you could always set the contentDescription to null.

BASED ON THE UPDATE

You can simply use an AndroidView for this purpose

AndroidView(
  factory = {
    ImageView(...) // Populate it here
  }
)

This is in itself a Composable function so you can literally just swap out your Image Composable with this and it'll work.

Take The Migration Codelab to get full insights on API usage.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1