12

For an application that I work on, I need to implement accessibility. Everything works fine except for one screen where I have to fragments added to my activity. Basically, the fragment that is above is a dial keyboard to enter a passcode. This fragment is added with a fragmentTransaction.

The thing is that the talkback focus is set on the elements of the underneath fragment.

Do you know if there is a way to set the talkback focus on the dial fragment ? I just want to "disable" the fragment underneath to get focus

Thanks,

Matthias
  • 999
  • 11
  • 25

7 Answers7

10

UPDATE

I figured out the solution. you can disable the accessibility of the first fragment before you do the fragment transaction.

rootView = inflater.inflate(R.layout.first_fragment, null, false);

rootView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);

and now you commit your fragment transaction. Second fragment won't leak the focus to first fragment.

Don't forget to enable the accessibility of first fragment in case you're coming back to the first fragment.

if(rootView != null) {
    rootView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
}
Ali
  • 2,427
  • 22
  • 25
  • This works fine but child views not getting focus on first fragment on next swipe. Any solution? – fargath Sep 25 '18 at 10:33
  • @fargath you have to enable the accessibility of first fragment using the second code example – Martin Osorio Mar 11 '20 at 17:37
  • 1
    This solution works great. If you are using databinding, then onCreateView use: MyFragmentLayoutBinding binding = DataBindingUtil.inflate(inflater, R.layout.my_fragment_layout, container, false); binding.getRoot.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); – Martin Osorio Mar 11 '20 at 17:39
3

Are you using fragmentTransaction.add?

If so you sould use fragmentTransaction.replace!

Add function also did problems with clicking the below fragment views.

So please, use replace.

Shay Aslan
  • 39
  • 1
1

Your problem isn't "sending" focus to the correct place. Forcing focus around to different places is generally a bad idea, and inaccessible. Your problem is that you have elements on the screen that aren't visible, but are being focused by TalkBack. What you want to do is hide these elements from TalkBack. Actually, you probably want to remove them completely, but let's assume that they need to be on the screen. What you can do is hide them from the accessibility service:

rootViewOfFragment.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);

This will hide those views from TalkBack. This is a better solution than forcing focus to a specific element, as this is generally an accessibility violation under WCag 2.0. Though if the elements on screen are not completely hidden by your "top" fragment, this is also a violation, and you should actually just leave things be.

MobA11y
  • 18,425
  • 3
  • 49
  • 76
0

Look at method View.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED). sendAccessibilityEvent changes focus from Talkback. I don't know much about Talkback, pls read a link on SO @ When using TalkBack, what is the preferred way to alert the user when the contents of a TextView have changed?.

Good luck...

Community
  • 1
  • 1
The Original Android
  • 6,147
  • 3
  • 26
  • 31
  • Forcing accessibility focus around is a bad idea. A: it's an accessibility violation under WCag 2.0. B: what if the user swypes back? They'll still end up focusing those things that he doesn't want focused. – MobA11y May 19 '15 at 13:31
0

Maybe you can call requestAccessibilityFocus() when the second fragment resumes

@Override
public void onResume() {
    super.onResume();
    yourView.requestAccessibilityFocus();
}
IKavanagh
  • 6,089
  • 11
  • 42
  • 47
zhpoo
  • 726
  • 4
  • 10
0

Adding

view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);`
view.performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);

inside onResume

and adding

view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);

inside onPause works for me.

reidzeibel
  • 1,622
  • 1
  • 19
  • 24
0

Using replace fragment over add fragment is IMO a best answer, see here

https://stackoverflow.com/a/21684520/3540391

Jacques Giraudel
  • 352
  • 4
  • 19