14

Is it possible to move the accessibility focus (VoiceOver for iOS and Talkback for Android) to a defined widget when pressing a button?

I've tried searching in the Semantics package but I can't find a way to obtain this.

It would be enough also to make the screen reader restart the semantics tree from the beginning.

I have a PageView with 3 pages and buttons to move back/forward using a PageController. I would like to move the focus to the beginning of the page when this changes using the button (that invokes _pageController.animateToPage).

LorenzOliveto
  • 7,796
  • 1
  • 20
  • 47
  • Did you tried with FocusNode? ```FocusScope.of(context).requestFocus(_myFocusNode);``` – AmazingBite Jul 30 '19 at 14:05
  • I have added details about the widget structure, unfortunately I don't have a textfield so I don't think I can't set a FocusNode to a normal Widget. – LorenzOliveto Jul 30 '19 at 14:09
  • There is a widget called Focus in which you can attach a FocusNode, a child widget, and some callbacks. Did I understand you correctly that you wanted the screen reader to automatically read what the focus is changed to upon the button press? I did try to create something similar to what you described with a Focus widget, and the focus seems to change according to print statements, but the highlighting of Talkback remains in place and nothing is read aloud unless manually pressing elsewhere afterwards. I can attach the code if requested (not posted yet as I'm unsure its a proper answer). – Tor-Martin Holen Jul 30 '19 at 20:57
  • 2
    What I want is to change the talkback focus from the button to the start of the page (another widget). I tried what you described but as you say the focus don't change. I'm searching for an equivalent of the natives UIAccessibilityLayoutChangedNotification/AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED for Flutter? – LorenzOliveto Jul 31 '19 at 06:51

2 Answers2

5

In short, no, there currently is no method that allows you to move the accessibility focus through code.

Referring to the disclaimer mention at https://stackoverflow.com/a/28481095/6668797 as some background (even though Android still allows us to do this..)

DISCLAIMER: Forcing focus on Activity load to be anywhere but at the top bar is always (okay, always should almost never be said), but really, just don't do it. It is a violation of all sorts of WCAG 2.0 regulations, including 3.2.1 and 3.2.3, regarding predictable navigation and context changes respectively. You are, likely, actually making your app MORE inaccessible by doing this.

http://www.w3.org/TR/WCAG20/#consistent-behavior

The Dart team currently stands steadfast behind that rule, so it just hasn't been a priority to add this feature.

If you really wish to notify the user that a different page is now visible, you can use SemanticsService.announce() to inform the user after some action. For example, set this in onPageChanged,

onPageChanged: (int page) {
  // announce new page
}
TWL
  • 6,228
  • 29
  • 65
0

There currently isn't a way to do this in Flutter. Input focus and accessibility focus are two different things. Lots of people seem to suggest this:

FocusScope.of(context).requestFocus(_myFocusNode);

The problem is that this only changes the input focus. The accessibility focus, which is the green / blue / black box provided by TalkBack and Voiceover, doesn't change.

That's why you can verify the focus with a print statement but the box hasn't moved.

As of right now there's no way to change the accessibility focus in Flutter. This is a massive oversight and a huge roadblock to creating truly accessible apps.

EDIT For the sake of completeness I did find an ugly workaround to this.

If you change the focus to a form field, such as a textfield, then the accessibility focus will update as well.

In my case I'm using a FlatButton which has pretty much no styling attached to it. Obviously you then have to make that button do something, but it at least gets you in the neighborhood of where you want to be.

Hacky? Absolutely, but in lieu of better options this is what I've got at the moment.

ragingprog
  • 103
  • 6
  • Your edit may have worked at a time or in very specific context, but every situation we tried it in on Flutter 3+ failed. – Rob Caraway Jul 11 '22 at 14:56