Su Android, esistono più modi per intercettare gli eventi dall'interazione di un utente con la tua applicazione. Quando si considerano gli eventi nell'interfaccia utente, l'approccio è acquisire gli eventi dalla l'oggetto View specifico con cui interagisce l'utente. La classe View fornisce i mezzi per farlo.
Tra le varie classi View che utilizzerai per comporre il layout, potresti notare diverse
metodi che sembrano utili per gli eventi dell'interfaccia utente. Questi metodi vengono chiamati dal framework Android quando
la rispettiva azione si verifica su quell'oggetto. Ad esempio, quando viene toccata una Vista (come un pulsante),
il metodo onTouchEvent()
viene chiamato su quell'oggetto. Tuttavia, per intercettarlo, devi estendere
la classe e sostituire il metodo. Tuttavia, l'estensione di ogni oggetto View
per gestire un evento del genere non sarebbe pratico. Per questo motivo la classe View contiene anche
una raccolta di interfacce nidificate con callback che puoi definire molto più facilmente. Queste interfacce,
chiamati ascoltatori di eventi, sono la soluzione ideale per acquisire l'interazione dell'utente con la UI.
Anche se utilizzerai più comunemente i listener di eventi per ascoltare le interazioni degli utenti, potrebbero
quando vuoi estendere una classe View, per creare un componente personalizzato.
Potresti voler estendere Button
per rendere qualcosa di più elegante. In questo caso, sarai in grado di definire i comportamenti predefiniti degli eventi per il tuo
utilizzando i gestori di eventi della classe.
Listener di eventi
Un listener di eventi è un'interfaccia della classe View
che contiene un singolo
di callback di Google. Questi metodi verranno chiamati dal framework Android quando la vista a cui il listener ha
registrato viene attivato dall'interazione dell'utente con l'elemento nell'interfaccia utente.
Le interfacce del listener di eventi includono i seguenti metodi di callback:
onClick()
- Da
View.OnClickListener
. Questo viene chiamato quando l'utente tocca l'elemento. (in modalità touch) o si concentra sull'elemento con i tasti di navigazione o la trackball e preme il tasto "Invio" adatto o premi la trackball. onLongClick()
- Da
View.OnLongClickListener
. Questo viene chiamato quando l'utente tocca e tiene premuto l'elemento (in modalità tocco) o si concentra sull'elemento con i tasti di navigazione o la trackball e tiene premuto il pulsante "Invio" o tenere premuto sulla trackball (per un secondo). onFocusChange()
- Da
View.OnFocusChangeListener
. Questo viene chiamato quando l'utente si avvicina o si allontana dall'elemento utilizzando i tasti di navigazione o la trackball. onKey()
- Da
View.OnKeyListener
. Viene chiamato quando l'utente si concentra sull'elemento e preme o rilascia un tasto hardware sul dispositivo. onTouch()
- Da
View.OnTouchListener
. Questo nome viene chiamato quando l'utente esegue un'azione qualificata come evento touch, ad esempio una stampa, un comunicato stampa o qualsiasi gesto di movimento sullo schermo (entro i limiti dell'elemento). onCreateContextMenu()
- Da
View.OnCreateContextMenuListener
. Questa operazione viene chiamata quando viene creato un menu contestuale (in seguito a un "clic lungo") prolungato. Visualizza la discussione sui menu contestuali nella sezione Menu guida per gli sviluppatori.
Questi metodi sono gli unici abitanti della rispettiva interfaccia. Per definire uno di questi metodi
e gestire i tuoi eventi, implementa l'interfaccia nidificata nella tua attività o definiscila come classe anonima.
Quindi, passa un'istanza della tua implementazione
al rispettivo metodo View.set...Listener()
. (ad es., richiama
e passarla all'implementazione del setOnClickListener()
OnClickListener
.
L'esempio seguente mostra come registrare un listener al clic per un pulsante.
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); ... }
Potresti anche trovare più pratico implementare OnClickListener nella tua Attività. In questo modo eviterai il carico della classe e l'allocazione degli oggetti aggiuntivi. Ad esempio:
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 } ... }
Nota che il callback onClick()
nell'esempio precedente ha
nessun valore restituito, ma alcuni altri metodi listener di eventi devono restituire un valore booleano. Il motivo
dipende dall'evento. Per i pochi che li supportano, ecco perché:
- Questo restituisce un valore booleano che indica se hai usufruito dell'evento e che non deve essere mantenuto. In altre parole, restituisce true per indicare che hai gestito l'evento, che deve interrompersi qui. restituisce false se non lo hai gestito e/o se l'evento deve continuare in qualsiasi altro listener al clic.onLongClick()
- Questo restituisce un valore booleano che indica se hai usufruito dell'evento e che non deve essere mantenuto. In altre parole, restituisce true per indicare che hai gestito l'evento, che deve interrompersi qui. restituisce false se non lo hai gestito e/o se l'evento deve continuare in qualsiasi altro ascoltatori discreti.onKey()
- Questo restituisce un valore booleano per indicare se il listener utilizza questo evento. L'importante è che questo evento può avere più azioni che si susseguono. Pertanto, se restituisci false quando evento di chiusura, indichi di non aver usufruito dell’evento e che non mi interessa le azioni successive di questo evento. Pertanto, non ti verrà richiesto di intraprendere altre azioni all'interno dell'evento, ad esempio il gesto di un dito o l'eventuale evento di azione verso l'alto.onTouch()
Ricorda che gli eventi chiave hardware vengono sempre inviati alla vista attualmente in primo piano. Vengono spediti partendo dall'alto
della gerarchia di visualizzazione e poi verso il basso, fino a raggiungere la destinazione appropriata. Se la tua Vista (o un elemento secondario della tua Vista)
attualmente è attivo, puoi vedere come si svolge l'evento tramite il metodo
. In alternativa all'acquisizione di eventi chiave tramite la Vista, puoi anche ricevere
tutti gli eventi nella tua Attività con dispatchKeyEvent()
e onKeyDown()
.onKeyUp()
Inoltre, quando pensi all'input di testo per la tua applicazione, ricorda che molti dispositivi dispongono solo di input software
di machine learning. Questi metodi non devono essere basati su chiavi. alcuni potrebbero utilizzare input vocale, scrittura a mano libera e così via. Anche se
un metodo di immissione presenta un'interfaccia simile a una tastiera, in genere non attiva il metodo
Famiglia di eventi
. Non dovresti mai
Creare una UI che richieda il controllo di pressioni di tasti specifiche, a meno che tu non voglia limitare la tua applicazione ai dispositivi
con una tastiera hardware. In particolare, non fare affidamento su questi metodi per convalidare l'input quando l'utente preme il
chiave restituito; utilizza invece azioni come onKeyDown()
IME_ACTION_DONE
per segnalare
il metodo di input in cui la tua applicazione prevede di reagire, quindi potrebbe modificare la sua UI in modo significativo. Evita ipotesi
sul funzionamento di un metodo di immissione software e affidarsi a quest'ultimo per fornire testo già formattato alla tua applicazione.
Nota: Android chiama prima i gestori di eventi e poi il valore predefinito appropriato dalla definizione della classe. Di conseguenza, la restituzione di true dai listener di eventi verrà interrotta la propagazione dell'evento ad altri listener di eventi e bloccherà anche il callback al gestore di eventi predefinito nella vista. Assicurati quindi di voler terminare l'evento quando restituisci true.
Gestori di eventi
Se stai creando un componente personalizzato da View, puoi definire diversi metodi di callback utilizzati come gestori di eventi predefiniti. Nel documento sulle impostazioni personalizzate Visualizza i componenti, scoprirai alcuni dei callback più comuni utilizzati per la gestione degli eventi. tra cui:
: viene chiamato quando si verifica un nuovo evento chiave.onKeyDown(int, KeyEvent)
- Richiamato quando si verifica un evento di key-up.onKeyUp(int, KeyEvent)
- Richiamato quando si verifica un evento di movimento della trackball.onTrackballEvent(MotionEvent)
- Richiamato quando si verifica un evento di movimento touchscreen.onTouchEvent(MotionEvent)
: viene chiamato quando la visualizzazione acquisisce o perde l'attenzione.onFocusChanged(boolean, int, Rect)
Esistono altri metodi che dovresti conoscere, che non fanno parte della classe View. ma possono influire direttamente sulla gestione degli eventi. Quindi, quando si gestiscono eventi più complessi un layout, prendi in considerazione altri metodi:
: consente aActivity.dispatchTouchEvent(MotionEvent)
Activity
di intercettare tutti gli eventi di tocco prima che vengano inviati alla finestra.
: consente aViewGroup.onInterceptTouchEvent(MotionEvent)
ViewGroup
di guardare gli eventi quando vengono inviati alle viste secondarie.
- Chiama su una vista principale per indicare che non deve intercettare gli eventi di tocco conViewParent.requestDisallowInterceptTouchEvent(boolean)
.onInterceptTouchEvent(MotionEvent)
Modalità touch
Quando un utente naviga in un'interfaccia utente con i tasti direzionali o una trackball, necessari per focalizzare gli elementi su cui è possibile eseguire azioni (come i pulsanti) in modo che l'utente possa cosa accetterà l'input. Se invece il dispositivo è dotato di funzionalità touch e l'utente inizia a interagire con l'interfaccia toccandola, non è più necessario evidenziare elementi o concentrarti su una particolare Vista. Esiste quindi una modalità per le interazioni denominate "modalità tocco".
Per un dispositivo con funzionalità touch, dopo che l'utente tocca lo schermo, il dispositivo
entrerà in modalità tocco. Da questo momento in poi, solo le viste per cui
Il valore true per isFocusableInTouchMode()
sarà attivabile, ad esempio i widget di modifica del testo.
Le altre visualizzazioni toccabili, come i pulsanti, non vengono messe in evidenza quando vengono toccate. lo faranno
basta attivare i listener al clic quando viene premuto.
Ogni volta che un utente preme un tasto direzionale o scorre con una trackball, il dispositivo esci dalla modalità tocco e trova una visualizzazione per mettere a fuoco. Ora l'utente può riprendere a interagire con l'interfaccia utente senza toccare lo schermo.
Lo stato della modalità touch viene mantenuto in tutto il sistema (tutte le finestre e le attività).
Per eseguire una query sullo stato attuale, puoi chiamare
isInTouchMode()
per vedere se il dispositivo è attualmente in modalità tocco.
Gestione dell'attenzione
Il framework gestirà il movimento di routine dello stato attivo in risposta all'input dell'utente.
Ciò include la modifica dell'elemento attivo quando le visualizzazioni vengono rimosse o nascoste oppure come nuove.
Le visualizzazioni diventano disponibili. Le visualizzazioni indicano la loro disponibilità a concentrarsi
tramite il metodo
. Per modificare se una visualizzazione può
focus, chiama isFocusable()
. In modalità tocco,
puoi eseguire una query se una vista consente lo stato attivo con setFocusable()
.
Puoi modificare questa impostazione con isFocusableInTouchMode()
.
setFocusableInTouchMode()
Sui dispositivi con Android 9 (livello API 28) o versioni successive, le attività non assegnano focus iniziale. Devi invece richiedere esplicitamente lo stato attivo iniziale, se vuoi.
Il movimento di messa a fuoco si basa su un algoritmo che trova il vicino più prossimo in una una data direzione. In rari casi, l'algoritmo predefinito potrebbe non corrispondere comportamento previsto dello sviluppatore. In questi casi, puoi fornire override espliciti con i seguenti attributi XML nel file di layout: nextFocusDown, nextFocusLeft, nextFocusRight e nextFocusUp. Aggiungi uno di questi attributi alla vista da che l'obiettivo si sta allontanando. Definisci il valore dell'attributo come ID della vista a quale obiettivo dare priorità. Ad esempio:
<LinearLayout android:orientation="vertical" ... > <Button android:id="@+id/top" android:nextFocusUp="@+id/bottom" ... /> <Button android:id="@+id/bottom" android:nextFocusDown="@+id/top" ... /> </LinearLayout>
In questo layout verticale, la navigazione verso l'alto dal primo pulsante non consente da nessuna parte né scendere dal secondo pulsante. Ora che il pulsante in alto definita quella inferiore nextFocusUp (e viceversa), lo stato attivo della navigazione dall'alto verso il basso e dal basso verso l'alto.
Se vuoi dichiarare una vista come attivabile nella tua UI (quando tradizionalmente non lo è),
aggiungi l'attributo XML android:focusable
alla vista nella dichiarazione relativa al layout.
Imposta il valore true. Puoi anche dichiarare una vista
in modalità tocco con android:focusableInTouchMode
.
Per richiedere che una determinata Vista diventi attiva, chiama
.requestFocus()
Per ascoltare gli eventi relativi allo stato attivo (per ricevere una notifica quando una vista riceve o perde lo stato attivo), utilizza
,
come descritto nella sezione Listener di eventi.onFocusChange()