Move accessibility focus programmatically

2,572

Solution 1

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
}

Solution 2

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.

Share:
2,572
LorenzOliveto
Author by

LorenzOliveto

Currently iOS developer in Modena, Italy.

Updated on November 30, 2022

Comments

  • LorenzOliveto
    LorenzOliveto over 1 year

    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).