إتاحة ميزة 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;
  }
}