Xamarin-android: [Bug] Change Accessibility focus in Android

Created on 24 Feb 2020  路  7Comments  路  Source: xamarin/xamarin-android

Description

Not able to change the accessibility focus on a certain element after a certain event (like a button press).
Asked also on Community

Steps to Reproduce

  1. Create an Android project
  2. Insert some random elements (like 3 buttons)
  3. Handle the Click of one of the buttons
  4. In the Click handler try to change the accessibility focus on one of the other buttons
  5. Test the app on a physical device with TalkBack ON

Expected Behavior

When you tap a certain button the screen reader should change the focus to the wanted button

Actual Behavior

Using the expected command, myview.SendAccessibilityEvent(EventTypes.ViewAccessibilityFocused) the screen reader only read the accessibility name of myview without actually setting the focus on it, that remain on the pressed button.
Using some other commands, like myview.SendAccessibilityEvent(EventTypes.ViewFocused) or b3.SendAccessibilityEvent(EventTypes.WindowsChanged) nothing happen.
Using some other command like myview.SendAccessibilityEventUnchecked(AccessibilityEvent.WindowsChangeAccessibilityFocused) (that should actually be the right one that work in Android Studio), it give the error Argument 1: cannot convert from 'Android.Views.Accessibility.WindowsChange' to 'Android.Views.Accessibility.AccessibilityEvent

Other information

In Android Studio, using Java, to set the accessibility focus on a certain myview you have to do myview.sendAccessibilityEvent(AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED) and it works fine. In Xamarin, using C#, everything that I tried doesn't work properly.

Reproduction Link

Git repository example

question

All 7 comments

Seems to be an issue related with Xamarin.Android. @samhouts can we move this issue to https://github.com/xamarin/xamarin-android/issues?

EventTypes.ViewAccessibilityFocused corresponds to AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED.

If you want to do an equivalent of sendAccessibilityEvent(AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED), you will need to do:

myview.SendAccessibilityEvent((EventTypes) (int) WindowsChange.AccessibilityFocused);

The perils of enumification...

EventTypes.ViewAccessibilityFocused corresponds to AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED.

If you want to do an equivalent of sendAccessibilityEvent(AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED), you will need to do:

myview.SendAccessibilityEvent((EventTypes) (int) WindowsChange.AccessibilityFocused);

The perils of enumification...

Damn, I feel so stupid for haven't seen that. Thanks a lot!

I believe you could do this:

myview.SendAccessibilityEvent(EventTypes.ViewHoverEnter)

I believe you could do this:

myview.SendAccessibilityEvent(EventTypes.ViewHoverEnter)

Oh, yes, that worked too. Thanks!

In case it's helpful additional info, I believe the AccessibilityEvent.WINDOWS_CHANGE_* constant values are not intended to be used when dispatching accessibility events. I believe those values are instead only meant to be used to compare to the return value from AccessibilityEvent.getWindowChanges().

So I think it would be recommended to use one of the AccessibilityEvent.TYPE_* constant values when providing an argument to SendAccessibilityEvent().

In this case, if you've previously found that WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED gives you the desired behavior, using EventTypes.ViewHoverEnter would be a good choice because TYPE_VIEW_HOVER_ENTER and WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED have the same integer value of 128 (0x00000080).

(Note also that getWindowChanges() and the WINDOWS_CHANGE_* constants are only available starting in Android API level 28, while sendAccessibilityEvent() and the TYPE_* constants are available in older Android API levels.)

In case it's helpful additional info, I believe the AccessibilityEvent.WINDOWS_CHANGE_* constant values are not intended to be used when dispatching accessibility events. I believe those values are instead only meant to be used to compare to the return value from AccessibilityEvent.getWindowChanges().

So I think it would be recommended to use one of the AccessibilityEvent.TYPE_* constant values when providing an argument to SendAccessibilityEvent().

In this case, if you've previously found that WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED gives you the desired behavior, using EventTypes.ViewHoverEnter would be a good choice because TYPE_VIEW_HOVER_ENTER and WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED have the same integer value of 128 (0x00000080).

(Note also that getWindowChanges() and the WINDOWS_CHANGE_* constants are only available starting in Android API level 28, while sendAccessibilityEvent() and the TYPE_* constants are available in older Android API levels.)

Oh I see. Perfect, very clear and exahustive, really appreciate that thanks.

Was this page helpful?
0 / 5 - 0 ratings