3

I would like to make my app accessible with Tlkback, but I don't know how could I set different content descriptions for both states of a switch or toggle button.

Do you have any suggestions?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Propacsek
  • 31
  • 2

2 Answers2

2

You can set content description programmatically like this.

toggleButton.setOnClickListener( new View.OnClickListener() {
        @Override
        public void onClick( View v ) {
            if( toggleButton.isChecked() ) {
                toggleButton.setContentDescription( "Selected" );
            } else {
                toggleButton.setContentDescription( "Unselected" );
            }
        }
    } );
Apollo
  • 420
  • 3
  • 6
1

Use AccessibilityNodeInfo's setChecked and setCheckable. https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setCheckable(boolean)

class MyAccessibilityDelegate extends View.AccessibilityDelegate {

  MyButton button;

  public constructor (MyButton button) {
    this.button = button;
  }

  @Override
  public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(host, info);
    
    info.setCheckable(true);
    info.setChecked(button.getChecked());

And then add delegate to your view/layout/etc.

class MyButton extends View {
...
  public constructor() {
    setAccessibilityDelegate(new MyAccessibilityDelegate(this);
  }
...
}

Explanation: All accessibility services should be using AccessibilityNodeInfo to determine what is spoken out loud. setCheckable makes the service aware that the View has modifiable states, while setChecked actually changes the "checked/not checked" callout.

essen_star
  • 46
  • 3
  • If there is a view/row that has a couple of textviews AND a switch, we need to add `MyAccessibilityDelegate` to the root of the view so the TalkBack read all together. Then, the new issue will be, TalkBack will read the state of the Switch sooner. – Dr.jacky Jan 25 '22 at 13:35
  • If you want accessibility focus to stop at the root, then you can set `importantForAccessibility=true` for the root View's xml. TalkBack will automatically aggregate all the children view's accessibility info and read them in accessibility order, including the child `MyButton` with `MyAccessibilityDelegate`. – essen_star Jan 27 '22 at 01:25
  • My issue is the root has `importantForAccessibility="yes"` but, TalkBack reads all children except the Switch! That's the reason I came to this question and answer. To set the cd with the delegate; which didn't work either.(I tried both solutions, set the delegate on Switch and Parent) – Dr.jacky Jan 27 '22 at 08:53
  • 1
    Oh interesting. What class is your root view? Have you tried checking the [node info tree](https://withintent.uncorkedstudios.com/tutorial-debugging-android-accessibility-818cfd361414#:~:text=Turn%20on%20Node%20Tree%20Debugging&text=In%20Settings%20%3E%20Accessibility%20%3E%20TalkBack%20%3E,output%20level%20to%20%E2%80%9CVerbose.%E2%80%9D)? Without knowing more, my guess is that either the Switch isn't being set as an Accessibility child – essen_star Jan 27 '22 at 19:27
  • The root is `CardView`. then next parent is `ConstraintLayout`. – Dr.jacky Jan 28 '22 at 10:26