Jeśli Twoja aplikacja wymaga komponent widoku niestandardowego, musisz zwiększyć dostępność widoku. Wykonując te czynności, możesz poprawić o ułatwieniach dostępu opisanych na tej stronie:
- Obsługuj kliknięcia kontrolera kierunkowego.
- Wdrażanie metod interfejsu Accessibility API.
- Wyślij
AccessibilityEvent
typowe obiekty widoku niestandardowego. - Wypełnij pola
AccessibilityEvent
iAccessibilityNodeInfo
z punktu widzenia Twojej firmy.
Obsługa kliknięć kontrolera kierunkowego
Na większości urządzeń kliknięcie widoku za pomocą kontrolera kierunkowego powoduje wysłanie
KeyEvent
z
KEYCODE_DPAD_CENTER
do bieżącego widoku. Wszystkie standardowe uchwyty widoków danych na Androidzie
KEYCODE_DPAD_CENTER
. Podczas tworzenia niestandardowego
View
upewnij się, że to zdarzenie ma taki sam skutek jak dotknięcie widoku na ekranie dotykowym.
Twój niestandardowy element sterujący musi traktować element
KEYCODE_ENTER
tym samym co KEYCODE_DPAD_CENTER
. Umożliwia korzystanie z pełnej klawiatury
dla użytkowników.
Wdrażanie metod interfejsu Accessibility API
Zdarzenia ułatwień dostępu to wiadomości na temat interakcje z interfejsem wizualnym aplikacji;
Te wiadomości są obsługiwane przez usługi ułatwień dostępu, które obsługują
wykorzystać informacje z tych zdarzeń do wygenerowania dodatkowych informacji zwrotnych i promptów. Ułatwienia dostępu
metody są częścią View
i
View.AccessibilityDelegate
zajęcia. Dostępne metody:
dispatchPopulateAccessibilityEvent()
onPopulateAccessibilityEvent()
dla tego widoku danych
a potem metodę dispatchPopulateAccessibilityEvent()
dla każdego elementu podrzędnego
widok. onInitializeAccessibilityEvent()
TextView
lub
Button
, zastąp tę metodę
i ustawić dodatkowe informacje o widoku, takie jak typ pola hasła, pole wyboru
typu lub stany, które zawierają interakcję użytkownika z wydarzeniem lub związane z nim opinie – za pomocą tego
. Jeśli zastąpisz tę metodę, wywołaj jej superimplementację i zmodyfikuj tylko właściwości
które nie są ustawione przez klasę nadrzędną.onInitializeAccessibilityNodeInfo()
View
ma standardowy zestaw właściwości widoku, ale jeśli
widok niestandardowy zapewnia interaktywną kontrolę wykraczającą poza prosty widok TextView
lub
Button
, zastąp tę metodę i ustaw dodatkowe informacje o widoku
do obiektu AccessibilityNodeInfo
obsługiwanego przez tę metodę.onPopulateAccessibilityEvent()
AccessibilityEvent
) na urządzeniu
widok. Nazywa się ją też, jeśli widok jest elementem podrzędnym widoku, który generuje ułatwienia dostępu.
.
onRequestSendAccessibilityEvent()
AccessibilityEvent
Ten krok pozwala rodzicowi wyświetlać informacje o zmianach w ułatwieniach dostępu
wydarzenie z dodatkowymi informacjami. Zastosuj tę metodę tylko wtedy, gdy widok niestandardowy może zawierać
czy widok nadrzędny może zawierać informacje kontekstowe do ułatwień dostępu,
zdarzenie, które jest przydatne w usługach ułatwień dostępu.sendAccessibilityEvent()
- System wywołuje tę metodę, gdy użytkownik wykonuje działanie związane z wyświetleniem. Zdarzenie jest sklasyfikowane jako
typ działania użytkownika, np.
TYPE_VIEW_CLICKED
. Ogólnie rzecz biorąc,AccessibilityEvent
, gdy zmieni się zawartość widoku niestandardowego. sendAccessibilityEventUnchecked()
- Ta metoda jest używana, gdy kod kierunkowy musi bezpośrednio kontrolować sprawdzanie
włączone ułatwienia dostępu na urządzeniu
(
AccessibilityManager.isEnabled()
). Jeśli wdrożysz tę metodę, wykonaj wywołanie tak, jakby były włączone ułatwienia dostępu, niezależnie od ustawienia systemu. Zwykle nie musisz implementować tej metody w przypadku widoku niestandardowego. dispatchPopulateAccessibilityEvent()
onInitializeAccessibilityEvent()
onInitializeAccessibilityNodeInfo()
onPopulateAccessibilityEvent()
TYPE_VIEW_CLICKED
TYPE_VIEW_FOCUSED
TYPE_VIEW_HOVER_ENTER
TYPE_VIEW_HOVER_EXIT
TYPE_VIEW_LONG_CLICKED
TYPE_VIEW_SCROLLED
- Wygeneruj odpowiedni
AccessibilityEvent
dla zinterpretowanego działania kliknięcia. - Włącz usługi ułatwień dostępu, aby wykonywać niestandardowe kliknięcia w przypadku użytkowników, którzy nie mogą tego zrobić. użyj ekranu dotykowego.
Aby zapewnić obsługę ułatwień dostępu, zastąp i wdróż powyższe metody ułatwień dostępu bezpośrednio w do klasy widoku niestandardowego.
W przypadku klasy widoku niestandardowego zaimplementuj przynajmniej te metody ułatwień dostępu:
Więcej informacji o wdrażaniu tych metod znajdziesz w sekcji wypełnianie zdarzeń ułatwień dostępu.
Wysyłaj zdarzenia dotyczące ułatwień dostępu
W zależności od specyfiki widoku niestandardowego konieczne może być przesłanie
AccessibilityEvent
obiektów w różnych momentach lub w przypadku zdarzeń, które nie są obsługiwane domyślnie
implementacji. Klasa View
udostępnia domyślną implementację tych zdarzeń.
typy:
Ogólnie rzecz biorąc, musisz wysyłać AccessibilityEvent
za każdym razem, gdy treść Twojego dostosowania
zobacz zmiany. Jeśli na przykład wdrażasz niestandardowy pasek z suwakiem, który umożliwia użytkownikowi wybranie
po naciśnięciu klawisza strzałki w lewo lub w prawo, widok niestandardowy musi emitować zdarzenie
TYPE_VIEW_TEXT_CHANGED
za każdym razem, gdy zmienia się wartość suwaka. Poniższa próbka kodu pokazuje, jak można wykorzystać
Metoda sendAccessibilityEvent()
, aby zgłosić to zdarzenie.
Kotlin
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return when(keyCode) { KeyEvent.KEYCODE_DPAD_LEFT -> { currentValue-- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) true } ... } }
Java
@Override public boolean onKeyUp (int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { currentValue--; sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED); return true; } ... }
Wypełnianie zdarzeń ułatwień dostępu
Każdy element AccessibilityEvent
ma zestaw wymaganych właściwości opisujących bieżącą
stanu widoku. Właściwości te obejmują nazwę klasy widoku, zawartość
opis i stan zaznaczenia. Opisujemy właściwości wymagane w przypadku poszczególnych typów zdarzeń.
w
AccessibilityEvent
dokumentacji referencyjnej.
Implementacja View
podaje wartości domyślne dla tych
właściwości wymagane. Wiele z tych wartości, w tym nazwa klasy i sygnatura czasowa zdarzenia, jest
jest podawany automatycznie. Jeśli tworzysz komponent widoku niestandardowego, musisz podać informacje
dotyczące treści i cech danego widoku. Te informacje wystarczy umieścić na przycisku
i mogą zawierać dodatkowe informacje o stanie, które chcesz dodać do zdarzenia.
Użyj
onPopulateAccessibilityEvent()
oraz
onInitializeAccessibilityEvent()
do wypełniania lub modyfikowania informacji w AccessibilityEvent
. Użyj
Metoda onPopulateAccessibilityEvent()
służąca do dodawania lub modyfikowania tekstu
treść wydarzenia, która jest przekształcana w dźwiękowe prompty przez usługi ułatwień dostępu takie jak
TalkBack. Aby wypełnić dodatkowe pola, użyj metody onInitializeAccessibilityEvent()
informacje o zdarzeniu, np. stan wyboru widoku.
Dodatkowo zaimplementuj
onInitializeAccessibilityNodeInfo()
. Usługi ułatwień dostępu używają obiektów AccessibilityNodeInfo
wypełnianych przez ten atrybut
metoda badania hierarchii widoków, która generuje zdarzenie ułatwień dostępu po jego otrzymaniu.
i przekazywać użytkownikom odpowiednie opinie.
Poniższy przykładowy kod pokazuje, jak zastąpić te 3 metody w widoku:
Kotlin
override fun onPopulateAccessibilityEvent(event: AccessibilityEvent?) { super.onPopulateAccessibilityEvent(event) // Call the super implementation to populate its text for the // event. Then, add text not present in a super class. // You typically only need to add the text for the custom view. if (text?.isNotEmpty() == true) { event?.text?.add(text) } } override fun onInitializeAccessibilityEvent(event: AccessibilityEvent?) { super.onInitializeAccessibilityEvent(event) // Call the super implementation to let super classes // set appropriate event properties. Then, add the new checked // property that is not supported by a super class. event?.isChecked = isChecked() } override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo?) { super.onInitializeAccessibilityNodeInfo(info) // Call the super implementation to let super classes set // appropriate info properties. Then, add the checkable and checked // properties that are not supported by a super class. info?.isCheckable = true info?.isChecked = isChecked() // You typically only need to add the text for the custom view. if (text?.isNotEmpty() == true) { info?.text = text } }
Java
@Override public void onPopulateAccessibilityEvent(AccessibilityEvent event) { super.onPopulateAccessibilityEvent(event); // Call the super implementation to populate its text for the // event. Then, add the text not present in a super class. // You typically only need to add the text for the custom view. CharSequence text = getText(); if (!TextUtils.isEmpty(text)) { event.getText().add(text); } } @Override public void onInitializeAccessibilityEvent(AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); // Call the super implementation to let super classes // set appropriate event properties. Then, add the new checked // property that is not supported by a super class. event.setChecked(isChecked()); } @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); // Call the super implementation to let super classes set // appropriate info properties. Then, add the checkable and checked // properties that are not supported by a super class. info.setCheckable(true); info.setChecked(isChecked()); // You typically only need to add the text for the custom view. CharSequence text = getText(); if (!TextUtils.isEmpty(text)) { info.setText(text); } }
Te metody możesz wdrożyć bezpośrednio w klasie widoku niestandardowego.
Zadbaj o niestandardowy kontekst ułatwień dostępu
Usługi ułatwień dostępu mogą sprawdzać hierarchię widoku, który zawiera komponent interfejsu użytkownika które generuje zdarzenie ułatwień dostępu. Dzięki temu usługi ułatwień dostępu mogą zapewniać które pomagają użytkownikom.
W niektórych przypadkach usługi ułatwień dostępu nie mogą uzyskać odpowiednich informacji z widoku. w hierarchii. Przykładem może być niestandardowy element sterujący interfejsu, który zawiera co najmniej 2 osobne klikalne obszary, takie jak elementy sterujące kalendarza. W takim przypadku usługi nie są w stanie zapewnić wystarczająco bo klikalne podsekcje nie należą do hierarchii widoków.
W przykładzie na rys. 1 cały kalendarz jest zaimplementowany jako jeden widok, więc ułatwienia dostępu usługi otrzymują za mało informacji o zawartości wyświetlenia i wyborze użytkownika w widoku, chyba że deweloper poda dodatkowe informacje. Jeśli na przykład użytkownik kliknie w dniu oznaczonym etykietą 17 system ułatwień dostępu otrzymuje tylko informacje o opisie. i mają pełną kontrolę nad kalendarzem. W takim przypadku usługa ułatwień dostępu TalkBack informuje „Kalendarz” lub „Kalendarz kwietniowy”, a użytkownik nie wie, jaki dzień zostaje wybrany.
Aby zapewnić odpowiednie informacje kontekstowe dla usług ułatwień dostępu w takich sytuacjach, pozwala określić hierarchię widoku wirtualnego. Hierarchia widoków wirtualnych to zapewniają deweloperom aplikacji uzupełniającą hierarchię widoków usług ułatwień dostępu, ściśle pasuje do informacji na ekranie. Dzięki temu usługi ułatwień dostępu przydatne informacje kontekstowe.
Inną sytuacją, w której może być potrzebna hierarchia widoków wirtualnych, jest interfejs użytkownika zawierający
zestawu funkcji View
, które mają ściśle powiązane funkcje, gdzie działanie na jednym
wpływa na zawartość jednego lub większej liczby elementów, np. selektora liczb z osobnymi
i w dół. W takim przypadku usługi ułatwień dostępu nie mogą uzyskać wystarczających informacji, ponieważ
działanie na jednym elemencie sterującym zmienia treść w drugim, a relacja tych ustawień może nie być
być widoczny dla usługi.
Aby sobie z tym poradzić, pogrupuj powiązane elementy sterujące z widokiem zawierającym i podaj widok wirtualny hierarchię tego kontenera, aby jasno przedstawić informacje i zachowania dostarczane przez elementów sterujących.
Aby udostępnić hierarchię widoku wirtualnego dla danego widoku, zastąp parametr
getAccessibilityNodeProvider()
w widoku niestandardowym lub grupie widoków i zwracają implementację
AccessibilityNodeProvider
Hierarchię widoku wirtualnego możesz wdrożyć, używając biblioteki pomocy z komponentem
ViewCompat.getAccessibilityNodeProvider()
i zapewnić implementację
AccessibilityNodeProviderCompat
Aby uprościć zadanie udostępniania informacji usługom ułatwień dostępu i zarządzania
na ułatwieniach dostępu, warto wdrożyć
ExploreByTouchHelper
Zapewnia on AccessibilityNodeProviderCompat
i można go dołączyć jako widok danych
AccessibilityDelegateCompat
przez połączenie
setAccessibilityDelegate
.
Na przykład zobacz
ExploreByTouchHelperActivity
Z ExploreByTouchHelper
korzystają też widżety platformy, takie jak
CalendarView
, dzięki swojej
widok dziecka
SimpleMonthView
Obsługa niestandardowych zdarzeń dotknięcia
Elementy sterujące widokiem niestandardowym mogą wymagać niestandardowego działania zdarzeń dotyku, co pokazuje z poniższych przykładów.
Zdefiniuj działania związane z kliknięciem
Jeśli widżet używa funkcji
OnClickListener
lub
OnLongClickListener
system obsługuje
ACTION_CLICK
oraz
ACTION_LONG_CLICK
za Ciebie. Jeśli Twoja aplikacja korzysta z bardziej niestandardowego widżetu, który korzysta
interfejsu OnTouchListener
.
definiować niestandardowe moduły obsługi działań związanych z ułatwieniami dostępu związanymi z kliknięciami. W tym celu wywołaj metodę
replaceAccessibilityAction()
dla każdego działania, jak widać w tym fragmencie kodu:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { ... // Assumes that the widget is designed to select text when tapped, and selects // all text when tapped and held. In its strings.xml file, this app sets // "select" to "Select" and "select_all" to "Select all". ViewCompat.replaceAccessibilityAction( binding.textSelectWidget, ACTION_CLICK, getString(R.string.select) ) { view, commandArguments -> selectText() } ViewCompat.replaceAccessibilityAction( binding.textSelectWidget, ACTION_LONG_CLICK, getString(R.string.select_all) ) { view, commandArguments -> selectAllText() } }
Java
@Override protected void onCreate(Bundle savedInstanceState) { ... // Assumes that the widget is designed to select text when tapped, and select // all text when tapped and held. In its strings.xml file, this app sets // "select" to "Select" and "select_all" to "Select all". ViewCompat.replaceAccessibilityAction( binding.textSelectWidget, ACTION_CLICK, getString(R.string.select), (view, commandArguments) -> selectText()); ViewCompat.replaceAccessibilityAction( binding.textSelectWidget, ACTION_LONG_CLICK, getString(R.string.select_all), (view, commandArguments) -> selectAllText()); }
Tworzenie niestandardowych zdarzeń kliknięcia
Niestandardowy element sterujący może używać interfejsu onTouchEvent(MotionEvent)
detektor do wykrywania
ACTION_DOWN
i
Wydarzenia: ACTION_UP
i
wywołać specjalne zdarzenie kliknięcia. Aby zachować zgodność z usługami ułatwień dostępu, kod
obsługuje to zdarzenie kliknięcia niestandardowego, musi:
Aby skutecznie spełnić te wymagania, Twój kod musi zastąpić
performClick()
,
który musi wywoływać superimplementację tej metody i wykonać dowolne
wymagane przez zdarzenie kliknięcia. Po wykryciu niestandardowego działania kliknięcia kod ten musi wywołać metodę
Metoda performClick()
. Następujący przykładowy kod ilustruje ten wzorzec.
Kotlin
class CustomTouchView(context: Context) : View(context) { var downTouch = false override fun onTouchEvent(event: MotionEvent): Boolean { super.onTouchEvent(event) // Listening for the down and up touch events. return when (event.action) { MotionEvent.ACTION_DOWN -> { downTouch = true true } MotionEvent.ACTION_UP -> if (downTouch) { downTouch = false performClick() // Call this method to handle the response and // enable accessibility services to // perform this action for a user who can't // tap the touchscreen. true } else { false } else -> false // Return false for other touch events. } } override fun performClick(): Boolean { // Calls the super implementation, which generates an AccessibilityEvent // and calls the onClick() listener on the view, if any. super.performClick() // Handle the action for the custom click here. return true } }
Java
class CustomTouchView extends View { public CustomTouchView(Context context) { super(context); } boolean downTouch = false; @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); // Listening for the down and up touch events switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downTouch = true; return true; case MotionEvent.ACTION_UP: if (downTouch) { downTouch = false; performClick(); // Call this method to handle the response and // enable accessibility services to // perform this action for a user who can't // tap the touchscreen. return true; } } return false; // Return false for other touch events. } @Override public boolean performClick() { // Calls the super implementation, which generates an AccessibilityEvent // and calls the onClick() listener on the view, if any. super.performClick(); // Handle the action for the custom click here. return true; } }
Poprzedni wzorzec pomaga zagwarantować zgodność niestandardowego zdarzenia kliknięcia z ułatwieniami dostępu
za pomocą metody performClick()
do generowania zdarzeń ułatwień dostępu oraz
udostępnić punkt wejścia dla usług ułatwień dostępu, które będą działać w imieniu użytkownika wykonującego niestandardową
zdarzenie kliknięcia.