תמיכה ב-TalkBack באפליקציות לטלוויזיה

לפעמים לאפליקציות לטלוויזיה יש תרחישים לדוגמה שמקשים על משתמשים שמסתמכים TalkBack כדי להשתמש באפליקציה. כדי לספק חוויית TalkBack טובה יותר מומלץ לעיין בכל אחד מהסעיפים במדריך וליישם את השינויים האפליקציה בעת הצורך. אם באפליקציה שלך נעשה שימוש בתצוגות בהתאמה אישית, עליך לעיין גם מדריך תואם שמתאר איך לתמוך בנגישות באמצעות צפיות.

טיפול בתצוגות בתוך התצוגה

למשתמשי TalkBack יכול להיות קשה לנווט בתצוגות בתוך תצוגות מפורטות. כשהדבר אפשרי, תצוגה של ההורה או של הילד או הילדה שניתן להתמקד בהם ב-TalkBack, אבל לא לשניהם.

כדי שניתן יהיה להתמקד בתצוגה של TalkBack, מגדירים את focusable ואת focusableInTouchMode למאפיין true. השלב הזה נחוץ כי כשמפעילים את TalkBack, חלק ממכשירי הטלוויזיה עשויים להיכנס למצב מגע ולצאת ממנו.

כדי שלא תהיה אפשרות להתמקד בתצוגה מפורטת, אפשר מספיק להגדיר את focusable ל-false. עם זאת, אם התצוגה היא מעשית (כלומר, התואם ל-AccessibilityNodeInfo יש ACTION_CLICK), הוא עדיין עשוי שניתן להתמקד בהם.

שינוי התיאורים של פעולות

כברירת מחדל, TalkBack מכריז "צריך ללחוץ על 'בחירה' כדי להפעיל" לקבלת צפיות פרקטיות. לגבי פעולות מסוימות, המונח 'הפעלה' הוא לא תיאור טוב. שפת תרגום לספק תיאור מדויק יותר, תוכלו לשנות אותו:

Kotlin

findViewById<View>(R.id.custom_actionable_view).accessibilityDelegate = object : View.AccessibilityDelegate() {
  override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) {
    super.onInitializeAccessibilityNodeInfo(host, info)
    info.addAction(
      AccessibilityAction(
        AccessibilityAction.ACTION_CLICK.id,
        getString(R.string.custom_label)
      )
    )
  }
}

Java

findViewById(R.id.custom_actionable_view).setAccessibilityDelegate(new AccessibilityDelegate() {
  @Override
  public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(host, info);
    AccessibilityAction action = new AccessibilityAction(
        AccessibilityAction.ACTION_CLICK.getId(), getString(R.string.custom_label));
    info.addAction(action);
  }
});

הוספת תמיכה בפסי הזזה

התכונה TalkBack בטלוויזיה כוללת תמיכה מיוחדת בפסי הזזה. כדי להפעיל את מצב פס ההזזה, צריך להוסיף ACTION_SET_PROGRESS לתצוגה יחד עם אובייקט RangeInfo.

המשתמשים נכנסים למצב פס ההזזה באמצעות לחיצה על הלחצן המרכזי של השלט הרחוק של הטלוויזיה. במצב הזה, לחצני החיצים יוצרים ACTION_SCROLL_FORWARD ACTION_SCROLL_BACKWARD פעולות בנושא נגישות.

הדוגמה הבאה מטמיעה פס הזזה של עוצמת קול עם רמות מ-1 עד 10:

Kotlin

/**
 *   This example only provides slider functionality for TalkBack users. Additional logic should
 *   be added for other users. Such logic may reuse the increase and decrease methods.
 */
class VolumeSlider(context: Context?, attrs: AttributeSet?) : LinearLayout(context, attrs) {
  private val min = 1
  private val max = 10
  private var current = 5
  private var textView: TextView? = null

  init {
    isFocusable = true
    isFocusableInTouchMode = true
    val rangeInfo =
      AccessibilityNodeInfo.RangeInfo(
        AccessibilityNodeInfo.RangeInfo.RANGE_TYPE_INT,
        min.toFloat(),
        max.toFloat(),
        current.toFloat()
      )
    accessibilityDelegate =
      object : AccessibilityDelegate() {
        override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) {
          super.onInitializeAccessibilityNodeInfo(host, info)
          info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_PROGRESS)
          info.rangeInfo = rangeInfo
        }

        override fun performAccessibilityAction(host: View, action: Int, args: Bundle?): Boolean {
          if (action == AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD.id) {
            increase()
            return true
          }
          if (action == AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD.id) {
            decrease()
            return true
          }
          return super.performAccessibilityAction(host, action, args)
        }
      }
  }

  override fun onFinishInflate() {
    super.onFinishInflate()
    textView = findViewById(R.id.text)
    textView!!.text = context.getString(R.string.level, current)
  }

  private fun increase() {
    update((current + 1).coerceAtMost(max))
  }

  private fun decrease() {
    update((current - 1).coerceAtLeast(min))
  }

  private fun update(newLevel: Int) {
    if (textView == null) {
      return
    }
    val newText = context.getString(R.string.level, newLevel)
    // Update the user interface with the new volume.
    textView!!.text = newText
    // Announce the new volume.
    announceForAccessibility(newText)
    current = newLevel
  }
}

Java

/**
 *   This example only provides slider functionality for TalkBack users. Additional logic should
 *   be added for other users. Such logic can reuse the increase and decrease methods.
 */
public class VolumeSlider extends LinearLayout {
  private final int min = 1;
  private final int max = 10;
  private int current = 5;
  private TextView textView;

  public VolumeSlider(Context context, AttributeSet attrs) {
    super(context, attrs);
    setFocusable(true);
    setFocusableInTouchMode(true);
    RangeInfo rangeInfo = new RangeInfo(RangeInfo.RANGE_TYPE_INT, min, max, current);
    setAccessibilityDelegate(
        new AccessibilityDelegate() {
          @Override
          public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
            super.onInitializeAccessibilityNodeInfo(host, info);
            info.addAction(AccessibilityAction.ACTION_SET_PROGRESS);
            info.setRangeInfo(rangeInfo);
          }

          @Override
          public boolean performAccessibilityAction(View host, int action, Bundle args) {
            if (action == AccessibilityAction.ACTION_SCROLL_FORWARD.getId()) {
              increase();
              return true;
            }
            if (action == AccessibilityAction.ACTION_SCROLL_BACKWARD.getId()) {
              decrease();
              return true;
            }
            return super.performAccessibilityAction(host, action, args);
          }
        });
  }

  @Override
  protected void onFinishInflate() {
    super.onFinishInflate();
    textView = findViewById(R.id.text);
    textView.setText(getContext().getString(R.string.level, current));
  }

  private void increase() {
    update(Math.min(current + 1, max));
  }

  private void decrease() {
    update(Math.max(current - 1, min));
  }

  private void update(int newLevel) {
    if (textView == null) {
      return;
    }
    String newText = getContext().getString(R.string.level, newLevel);
    // Update the user interface with the new volume.
    textView.setText(newText);
    // Announce the new volume.
    announceForAccessibility(newText);
    current = newLevel;
  }
}