รองรับ TalkBack ในแอปทีวี

บางครั้งแอปทีวีมีกรณีการใช้งานที่ทำให้ผู้ที่ใช้งานแอปทีวี TalkBack ในการใช้แอป เพื่อมอบประสบการณ์การใช้งาน TalkBack ที่ดียิ่งขึ้น โปรดอ่านข้อมูลในแต่ละส่วนในคู่มือนี้ และนำการเปลี่ยนแปลงไปใช้ใน หากจำเป็น หากแอปของคุณใช้มุมมองที่กำหนดเอง คุณควรอ้างอิง คู่มือที่เกี่ยวข้องซึ่งอธิบายวิธีสนับสนุนการช่วยเหลือพิเศษด้วย ครั้ง

จัดการมุมมองที่ซ้อนกัน

ผู้ใช้ TalkBack อาจไปยังส่วนต่างๆ ของมุมมองที่ซ้อนกันได้ยาก หากเป็นไปได้ พยายาม ผู้ปกครองหรือบุตรหลานสามารถโฟกัสได้ด้วย TalkBack แต่จะโฟกัสทั้ง 2 อย่างไม่ได้

หากต้องการให้ TalkBack โฟกัสมุมมองได้ ให้ตั้งค่า focusable และ focusableInTouchMode เป็น true ขั้นตอนนี้จำเป็นเนื่องจาก อุปกรณ์ทีวีบางรุ่นอาจเข้าและออกจากโหมดสัมผัสขณะที่ TalkBack ทำงานอยู่

หากต้องการทำให้มุมมองเป็นแบบโฟกัสไม่ได้ แค่ตั้งค่า focusable ก็พอแล้ว เป็น false อย่างไรก็ตาม หากมุมมองนั้นสามารถดำเนินการได้ (กล่าวคือ AccessibilityNodeInfo ที่ตรงกันมี ACTION_CLICK) ก็อาจยังคง โฟกัสได้

เปลี่ยนคำอธิบายสำหรับการดำเนินการ

โดยค่าเริ่มต้น TalkBack จะบอกว่า "กดเลือกเพื่อเปิดใช้งาน" สำหรับมุมมองที่นำไปใช้ได้จริง สำหรับการกระทำบางอย่าง คำว่า "เปิดใช้งาน" อาจไม่ใช่คำอธิบายที่ดี ถึง ให้คำอธิบายที่ถูกต้องมากขึ้น คุณสามารถเปลี่ยนคำอธิบายได้โดยทำดังนี้

KotlinJava
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)
     
)
   
)
 
}
}
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

KotlinJava
/**
 *   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
 
}
}
/**
 *   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;
 
}
}