Panoramica degli eventi di input

Prova il metodo Scrivi
Jetpack Compose è il toolkit consigliato per la UI per Android. Scopri come utilizzare il tocco e l'input in Compose.

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 setOnClickListener() e passarla all'implementazione del 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é:

  • 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 listener al clic.
  • onKey() - 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.
  • onTouch() - 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.

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 dispatchKeyEvent(). In alternativa all'acquisizione di eventi chiave tramite la Vista, puoi anche ricevere tutti gli eventi nella tua Attività con onKeyDown() e 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 onKeyDown(). 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 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:

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:

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 isFocusable(). Per modificare se una visualizzazione può focus, chiama setFocusable(). In modalità tocco, puoi eseguire una query se una vista consente lo stato attivo con isFocusableInTouchMode(). Puoi modificare questa impostazione con 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 onFocusChange(), come descritto nella sezione Listener di eventi.