Na Androidzie istnieje kilka sposobów przechwytywania zdarzeń związanych z interakcjami użytkownika z aplikacją. Podczas analizowania zdarzeń za pomocą interfejsu użytkownika celem jest przechwytywanie zdarzeń konkretny obiekt View, z którym użytkownik wchodzi w interakcję; Klasa View umożliwia wykonanie tego zadania.
W ramach różnych klas widoku danych, których użyjesz do stworzenia układu, możesz zauważyć kilka publicznych wywołań zwrotnych.
które są przydatne w zdarzeniach interfejsu użytkownika. Te metody są wywoływane przez platformę Androida, gdy
wykonywane na danym obiekcie odpowiednie działanie. Na przykład po dotknięciu widoku (takiego jak Przycisk)
metoda onTouchEvent()
jest wywoływana dla tego obiektu. Aby jednak je przechwycić, musisz rozszerzyć
i zastąpić metodę. Rozszerzenie każdego obiektu widoku danych
obsługi takich zdarzeń jest niepraktyczne. To dlatego klasa Widok zawiera też
zbiór zagnieżdżonych interfejsów z wywołaniami zwrotnymi, które możesz znacznie łatwiej zdefiniować. Te interfejsy
detektory zdarzeń to klucz do rejestrowania interakcji użytkownika z interfejsem.
Choć Częściej używa się detektorów zdarzeń do nasłuchiwania interakcji użytkownika, może
gdy zechcesz rozszerzyć klasę View w celu utworzenia komponentu niestandardowego.
Możesz zdecydować się na wydłużenie terminu: Button
aby stworzyć coś bardziej wymyślnego. W takim przypadku można określić domyślne zachowania zdarzeń w
za pomocą klasy modułów obsługi zdarzeń.
Detektory zdarzeń
Detektor zdarzeń to interfejs klasy View
, który zawiera pojedynczy
metody wywołania zwrotnego. Te metody będą wywoływane przez platformę Androida, gdy widok, do którego odbiornik
jest wywoływane przez interakcję użytkownika z elementem w interfejsie.
Interfejsy detektora zdarzeń obejmują te metody wywołań zwrotnych:
onClick()
- Od
View.OnClickListener
. Ta funkcja jest wywoływana, gdy użytkownik dotknie elementu. (w trybie dotykowym) albo przy użyciu klawiszy nawigacyjnych lub manipulatora kulkowego oraz naciska odpowiednie „Enter” lub naciśnij kulkę. onLongClick()
- Od
View.OnLongClickListener
. Ta funkcja jest wywoływana, gdy użytkownik dotknie i przytrzyma element (w trybie dotykowym). zaznacza element za pomocą klawiszy nawigacyjnych lub kulki oraz naciska i przytrzymuje odpowiedni klawisz „Enter” lub naciśnij i przytrzymaj kulkę (przez sekundę). onFocusChange()
- Od
View.OnFocusChangeListener
. Jest ona wywoływana, gdy użytkownik nawiguje do elementu lub z niego wychodzi, za pomocą klawiszy nawigacyjnych lub kulki. onKey()
- Od
View.OnKeyListener
. Ta funkcja jest wywoływana, gdy użytkownik skupia się na produkcie i naciska lub zwalnia klawisz sprzętowy na urządzeniu. onTouch()
- Od
View.OnTouchListener
. Jest ona wywoływana, gdy użytkownik wykona działanie sklasyfikowane jako zdarzenie dotknięcia, np. kliknięcie, lub dowolny gest ruchu na ekranie (w obrębie obiektu). onCreateContextMenu()
- Od
View.OnCreateContextMenuListener
. Ta funkcja jest wywoływana podczas tworzenia menu kontekstowego (w wyniku długotrwałego „długiego kliknięcia”). Zobacz dyskusję w menu kontekstowym w sekcji Menu przewodnik dla programistów.
Korzystanie z tych metod jest jedynym elementem ich interfejsu. Aby zdefiniować jedną z tych metod
i obsługiwać zdarzenia, zaimplementuj zagnieżdżony interfejs w sekcji Aktywność lub zdefiniuj ją jako anonimową klasę.
Następnie przekaż instancję implementacji
do odpowiedniej metody View.set...Listener()
. (Na przykład wywołaj
i przekaż mu swoją implementację tagu setOnClickListener()
OnClickListener
).
Przykład poniżej pokazuje, jak zarejestrować detektor kliknięcia przycisku.
Kotlin
protected void onCreate(savedValues: Bundle) { ... val button: Button = findViewById(R.id.corky) // Register the onClick listener with the implementation above button.setOnClickListener { view -> // do something when the button is clicked } ... }
Java
// Create an anonymous implementation of OnClickListener private OnClickListener corkyListener = new OnClickListener() { public void onClick(View v) { // do something when the button is clicked } }; protected void onCreate(Bundle savedValues) { ... // Capture our button from layout Button button = (Button)findViewById(R.id.corky); // Register the onClick listener with the implementation above button.setOnClickListener(corkyListener); ... }
Być może łatwiej będzie zaimplementować OnClickListener w ramach aktywności. Pozwoli to uniknąć dodatkowego obciążenia klas i przydziału obiektów. Na przykład:
Kotlin
class ExampleActivity : Activity(), OnClickListener { protected fun onCreate(savedValues: Bundle) { val button: Button = findViewById(R.id.corky) button.setOnClickListener(this) } // Implement the OnClickListener callback fun onClick(v: View) { // do something when the button is clicked } }
Java
public class ExampleActivity extends Activity implements OnClickListener { protected void onCreate(Bundle savedValues) { ... Button button = (Button)findViewById(R.id.corky); button.setOnClickListener(this); } // Implement the OnClickListener callback public void onClick(View v) { // do something when the button is clicked } ... }
Zwróć uwagę, że wywołanie zwrotne onClick()
w przykładzie powyżej
nie zwraca żadnej wartości, ale niektóre inne metody detektora zdarzeń muszą zwracać wartość logiczną. Powód
zależy od zdarzenia. Oto kilka powodów, dla których:
– Zwraca wartość logiczną wskazującą, czy zdarzenie zostało wykorzystane i nie powinno się ono dalej przenosić. Oznacza to, że zwróć wartość true, aby wskazać, że zdarzenie zostało już przez Ciebie obsługiwane i powinno ono kończyć się na tym etapie. zwróci wartość false, jeśli nie było obsługiwane i/lub zdarzenie powinno przejść do innego detektorów kliknięć.onLongClick()
– Zwraca wartość logiczną wskazującą, czy zdarzenie zostało wykorzystane i nie powinno się ono dalej przenosić. Oznacza to, że zwróć wartość true, aby wskazać, że zdarzenie zostało już przez Ciebie obsługiwane i powinno ono kończyć się na tym etapie. zwróci wartość false, jeśli nie było obsługiwane i/lub zdarzenie powinno przejść do innego na detektorach klawiszy.onKey()
– Zwraca wartość logiczną wskazującą, czy detektor przetwarza to zdarzenie. Ważne jest to, to zdarzenie może zawierać wiele działań, które następują po sobie. Jeśli więc zwrócisz wartość false, gdy gdy użytkownik zrezygnuje ze zdarzenia, oznacza to, że nie został on wykorzystany ani nie są zainteresowani dalszymi działaniami w ramach tego wydarzenia. Oznacza to, że nie będziemy Cię wezwać do żadnych innych działań. w ramach zdarzenia, na przykład gestu palca lub wywołanego przez niego działania.onTouch()
Pamiętaj, że kluczowe zdarzenia sprzętowe są zawsze wyświetlane w aktualnie widocznym widoku. Są wysyłane, zaczynając od góry
hierarchii widoków, a później w dół, aż dotrzesz do odpowiedniego miejsca docelowego. Jeśli Twój widok danych (lub jego element podrzędny)
jest obecnie zaznaczony, możesz wyświetlić podróż zdarzenia za pomocą metody
. Zamiast rejestrować kluczowe zdarzenia w widoku danych, możesz też przesyłać
wszystkie zdarzenia w ramach Twojej aktywności z dispatchKeyEvent()
i onKeyDown()
.onKeyUp()
Jeśli chodzi o wprowadzanie tekstu w aplikacji, pamiętaj, że wiele urządzeń ma tylko interfejs programowy
. Takie metody nie muszą być oparte na kluczu. niektóre mogą używać rozpoznawania mowy, pisma odręcznego itd. Nawet jeśli
jeśli metoda wprowadzania ma interfejs podobny do klawiatury, zasadniczo nie wywoła
Rodzina zdarzeń:
. Nigdy nie
stworzyć interfejs użytkownika, który wymaga kontrolowania naciśnięć klawiszy, chyba że chcesz ograniczyć dostęp do aplikacji tylko na urządzeniach.
dzięki klawiaturze sprzętowej. W szczególności nie używaj tych metod do weryfikowania danych wejściowych, gdy użytkownik naciśnie
Return key (klucz zwrotny); użyj działań takich jak onKeyDown()
IME_ACTION_DONE
, aby zasygnalizować
jak aplikacja ma zareagować, może więc istotnie zmienić swój interfejs użytkownika. Unikaj założeń
jak powinna działać
oprogramowana metoda wprowadzania danych, i ufaj, że dostarcza do aplikacji sformatowany tekst.
Uwaga: Android wywoła najpierw moduły obsługi zdarzeń, a następnie odpowiednie domyślne modułów obsługi z definicji klasy. W związku z tym zwracanie wartości true przez te detektory zdarzeń zostanie zatrzymane propagacji zdarzenia do innych detektorów zdarzeń i zablokuje wywołanie zwrotne do domyślny moduł obsługi zdarzeń w widoku danych. Upewnij się więc, że chcesz zakończyć wydarzenie, kiedy zwrócisz wartość true.
Moduły obsługi zdarzeń
Jeśli tworzysz komponent niestandardowy z poziomu widoku, możesz zdefiniować kilka metod wywołania zwrotnego są używane jako domyślne moduły obsługi zdarzeń. W dokumencie na temat opcji Niestandardowe wyświetl komponenty, poznasz niektóre typowe wywołania zwrotne do obsługi zdarzeń, w tym:
– wywoływane po wystąpieniu nowego kluczowego zdarzenia.onKeyDown(int, KeyEvent)
– wywołanie po wystąpieniu kluczowego zdarzenia.onKeyUp(int, KeyEvent)
– wywoływane po wystąpieniu zdarzenia ruchu kulki.onTrackballEvent(MotionEvent)
– wywoływane po wystąpieniu zdarzenia ruchu na ekranie dotykowym.onTouchEvent(MotionEvent)
– wywoływana, gdy widok zyskuje lub traci ostrość.onFocusChanged(boolean, int, Rect)
Istnieją też inne metody, o których warto wiedzieć, które nie należą do klasy widoku danych, ale też mieć bezpośredni wpływ na sposób obsługi zdarzeń. Podczas zarządzania złożonymi wydarzeniami w układzie graficznym, możesz zastosować następujące metody:
– umożliwiaActivity.dispatchTouchEvent(MotionEvent)
Activity
przechwytywanie wszystkich zdarzeń dotknięcia, zanim zostaną wysłane do okna.
– umożliwia użytkownikowiViewGroup.onInterceptTouchEvent(MotionEvent)
ViewGroup
śledzenie zdarzeń wysyłanych do wyświetleń podrzędnych.
– nazywaj to w Widoku nadrzędnym, aby wskazać, że nie powinien on przechwytywać zdarzeń dotknięcia za pomocą funkcjiViewParent.requestDisallowInterceptTouchEvent(boolean)
.onInterceptTouchEvent(MotionEvent)
Tryb dotykowy
Gdy użytkownik porusza się po interfejsie za pomocą klawiszy kierunkowych lub kulki, jest niezbędny do wyróżnienia aktywnych elementów (takich jak przyciski), tak aby użytkownik widział co akceptuje dane wejściowe. Jeśli urządzenie ma funkcje dotykowe, rozpoczyna interakcję z interfejsem przez dotknięcie go, nie trzeba już możesz wyróżnić elementy lub wybrać konkretny widok. Umożliwia to w przypadku interakcji o nazwie „tryb dotykowy”.
W przypadku urządzenia dotykowego, gdy użytkownik dotknie ekranu,
przejdzie w tryb dotykowy. Od tej pory tylko widoki, dla których
isFocusableInTouchMode()
ma wartość Prawda, co umożliwia zaznaczanie, tak jak widżety do edycji tekstu.
Inne Widoki, które są dotykowe, np. przyciski, nie zabierają ostrości po dotknięciu. będą
po prostu uruchamiają detektory aktywne po kliknięciu.
Po każdym naciśnięciu klawisza kierunkowego lub przewijaniu kulki urządzenie wyjdź z trybu dotykowego i znajdź widok, na którym chcesz się skupić. Teraz użytkownik może wznowić interakcję za pomocą interfejsu użytkownika bez dotykania ekranu.
Stan trybu dotykowego jest utrzymywany w całym systemie (we wszystkich oknach i czynnościach).
Aby przesłać zapytanie o bieżący stan, wywołaj
isInTouchMode()
, by sprawdzić, czy urządzenie jest obecnie w trybie dotykowym.
Koncentracja na radzeniu sobie z problemem
Platforma obsługuje rutynowe ruchy skupione w odpowiedzi na dane wejściowe użytkownika.
Obejmuje to zmienianie zaznaczenia po usunięciu lub ukryciu albo gdy wyświetlenia są nowe.
Widoki staną się dostępne. Wyświetlenia świadczą o chęci skupienia się na skupieniu
za pomocą metody
. Aby określić, czy Widok może
skupienie, wywołaj isFocusable()
. W trybie dotykowym
możesz zapytać, czy widok umożliwia zaznaczanie za pomocą funkcji setFocusable()
.
Możesz to zmienić w isFocusableInTouchMode()
.
setFocusableInTouchMode()
Na urządzeniach z Androidem 9 (poziom interfejsu API 28) lub nowszym działania nie powodują przypisania i pierwszy punkt skupienia. Zamiast tego w razie potrzeby musisz wyraźnie poprosić o początkowe zaznaczenie.
Ruch skupienia opiera się na algorytmie, który znajduje najbliższego sąsiada w w wybranym kierunku. W rzadkich przypadkach domyślny algorytm może nie odpowiadać zamierzone działanie dewelopera. W takiej sytuacji możesz podać jawne zastąpienia z tymi atrybutami XML w pliku układu: nextFocusDown, nextFocusLeft, nextFocusRight i nextFocusUp Dodaj do widoku z tych atrybutów, i staje się w centrum uwagi. Określ wartość atrybutu, która będzie identyfikatorem widoku. do którego elementu należy się skupić. Na przykład:
<LinearLayout android:orientation="vertical" ... > <Button android:id="@+id/top" android:nextFocusUp="@+id/bottom" ... /> <Button android:id="@+id/bottom" android:nextFocusDown="@+id/top" ... /> </LinearLayout>
W układzie pionowym przechodzenie od pierwszego przycisku nie byłoby możliwe. ani przejście z drugiego przycisku. Teraz, gdy górny przycisk tę dolną zdefiniowano jako nextFocusUp (i na odwrót), zaznaczenie zostanie przeniesione od góry do dołu i od dołu do góry.
Jeśli chcesz zadeklarować widok w interfejsie jako możliwy do zaznaczenia (gdy tradycyjnie nie jest to możliwe):
dodaj atrybut XML android:focusable
do widoku w deklaracji układu.
Ustaw wartość true. Możesz też zadeklarować widok,
można zaznaczyć w trybie dotykowym z urządzeniem android:focusableInTouchMode
.
Aby poprosić o konkretny widok danych, zadzwoń pod numer
.requestFocus()
Aby wykrywać zdarzenia skupienia (otrzymywać powiadomienia, gdy widok danych stanie się lub przestanie być fokus), użyj
,
jak omówiono w sekcji Detektory zdarzeń.onFocusChange()