Aplikacje na telewizory czasami mają przypadki użycia, które utrudniają korzystanie z nich użytkownikom polegającym na TalkBack. Aby zapewnić tym użytkownikom lepsze wrażenia z TalkBack, zapoznaj się z każdą sekcją tego przewodnika i w razie potrzeby wprowadź zmiany w aplikacji. Jeśli Twoja aplikacja korzysta z widoków niestandardowych, zapoznaj się też z odpowiednim przewodnikiem, który opisuje, jak obsługiwać ułatwienia dostępu w widokach niestandardowych.
Obsługa widoków zagnieżdżonych
Poruszanie się po widokach zagnieżdżonych może być trudne dla użytkowników TalkBack. Jeśli to możliwe, ustaw, aby TalkBack mógł skupić się na widoku nadrzędnym lub widoku dziecka, ale nie na obu.
Aby TalkBack mógł skupić się na widoku, ustaw atrybuty focusable i
focusableInTouchMode na true. Ten krok jest konieczny, ponieważ niektóre urządzenia z Androidem TV mogą włączać i wyłączać tryb dotykowy, gdy TalkBack jest aktywny.
Aby widok nie był widoczny, wystarczy ustawić focusable
atrybut na false. Jeśli jednak widok jest interaktywny (tzn. jego
odpowiedni element AccessibilityNodeInfo ma ACTION_CLICK), może być nadal
widoczny.
Zmienianie opisów działań
Domyślnie TalkBack ogłasza „Naciśnij przycisk wyboru, aby aktywować” w przypadku widoków interaktywnych. W przypadku niektórych działań termin „aktywuj” może nie być dobrym opisem. Aby podać dokładniejszy opis, możesz go zmienić:
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);
}
});
Dodawanie obsługi suwaków
TalkBack na telewizorze ma specjalną obsługę suwaków. Aby włączyć tryb suwaka, dodaj
ACTION_SET_PROGRESS do widoku wraz z obiektem RangeInfo.
Użytkownik wchodzi w tryb suwaka, naciskając środkowy przycisk pilota do telewizora.
W tym trybie przyciski strzałek generują ACTION_SCROLL_FORWARD i
ACTION_SCROLL_BACKWARD działania ułatwień dostępu.
Poniższy przykład implementuje suwak głośności z poziomami od 1 do 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;
}
}