Sui dispositivi con schermi di grandi dimensioni, gli utenti spesso interagiscono con le app utilizzando una tastiera, un mouse, un trackpad, uno stilo o un gamepad. Per consentire alla tua app di accettare input da dispositivi esterni:
- Testa il supporto di base della tastiera, ad esempio Ctrl+Z per annullare, Ctrl+C per copiare e Ctrl+S per salvare. Consulta Gestire le azioni da tastiera per un elenco delle scorciatoie da tastiera predefinite.
- Testa il supporto avanzato della tastiera, ad esempio il tasto Tab e la navigazione con i tasti freccia, la conferma dell'inserimento di testo con il tasto Invio e la riproduzione e la pausa con la barra spaziatrice nelle app multimediali.
- Testa le interazioni di base del mouse, tra cui il clic con il tasto destro per il menu contestuale, le modifiche delle icone al passaggio del mouse e gli eventi di scorrimento della rotellina del mouse o del trackpad sui componenti personalizzati.
- Testa i dispositivi di input specifici dell'app, come stilo, controller di gioco e controller MIDI per app musicali.
- Valuta la possibilità di aggiungere il supporto di input avanzato che potrebbe far risaltare l'app negli ambienti desktop, ad esempio il touchpad come crossfader per le app per DJ, l'acquisizione del mouse per i giochi e le scorciatoie da tastiera per gli utenti che utilizzano principalmente la tastiera.
Tastiera
Il modo in cui la tua app risponde all'input da tastiera contribuisce all'esperienza utente su schermi di grandi dimensioni. Esistono tre tipi di input da tastiera: navigazione, sequenze di tasti e scorciatoie.
Navigazione
La navigazione da tastiera viene implementata raramente nelle app incentrate sul tocco, ma gli utenti se lo aspettano quando utilizzano un'app e hanno le mani su una tastiera. La navigazione da tastiera può essere essenziale su smartphone, tablet, dispositivi pieghevoli e computer per gli utenti con esigenze di accessibilità.
Per molte app, la navigazione con i tasti freccia e il tasto Tab viene gestita automaticamente dal
framework Android. Ad esempio, un Button è selezionabile per
impostazione predefinita e la navigazione da tastiera dovrebbe funzionare in genere senza alcun
codice aggiuntivo. Per attivare la navigazione da tastiera per le visualizzazioni che non sono attivabili per impostazione predefinita,
contrassegnale come attivabili, operazione che può essere eseguita a livello di programmazione o in XML:
Kotlin
yourView.isFocusable = true
Java
yourView.setFocusable(true);
In alternativa, puoi impostare l'attributo focusable nel file di layout:
android:focusable="true"
Per scoprire di più, consulta Gestione della messa a fuoco.
Quando lo stato attivo è abilitato, il framework Android crea una mappatura di navigazione per tutte le visualizzazioni selezionabili in base alla loro posizione. In genere funziona come previsto e non è necessario alcun ulteriore sviluppo. Quando la mappatura predefinita non è corretta per le esigenze di un'app, la mappatura può essere sostituita come segue:
Kotlin
// Arrow keys
yourView.nextFocusLeftId = R.id.view_to_left
yourView.nextFocusRightId = R.id.view_to_right
yourView.nextFocusTopId = R.id.view_above
yourView.nextFocusBottomId = R.id.view_below
// Tab key
yourView.nextFocusForwardId = R.id.next_view
Java
// Arrow keys
yourView.setNextFocusLeftId(R.id.view_to_left);
yourView.setNextFocusRightId(R.id.view_to_left);
yourView.setNextFocusTopId(R.id.view_to_left);
yourView.setNextFocusBottomId(R.id.view_to_left);
// Tab key
yourView.setNextFocusForwardId(R.id.next_view);
Testa l'accesso a ogni elemento dell'interfaccia utente della tua app utilizzando solo la tastiera. Gli elementi utilizzati di frequente devono essere accessibili senza input da mouse o tocco.
Ricorda che il supporto della tastiera potrebbe essere essenziale per gli utenti con esigenze di accessibilità.
Sequenze di tasti
Per l'input di testo che verrebbe gestito da una tastiera virtuale sullo schermo (IME),
ad esempio per
un EditText
, le app dovrebbero comportarsi come previsto sui dispositivi con schermi di grandi dimensioni senza ulteriori
interventi di sviluppo. Per le sequenze di tasti che non possono essere previste dal framework,
le app devono gestire il comportamento autonomamente. Ciò vale in particolare per le app
con viste personalizzate.
Alcuni esempi sono le app di chat che utilizzano il tasto Invio per inviare un messaggio, le app multimediali che avviano e interrompono la riproduzione con la barra spaziatrice e i giochi che controllano il movimento con i tasti W, A, S e D.
La maggior parte delle app esegue l'override del callback onKeyUp() e aggiunge il comportamento previsto
per ogni codice tasto ricevuto:
Kotlin
kotlin
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
return when (keyCode) {
KeyEvent.KEYCODE_ENTER -> {
sendChatMessage()
true
}
KeyEvent.KEYCODE_SPACE -> {
playOrPauseMedia()
true
}
else -> super.onKeyUp(keyCode, event)
}
}
Java
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
sendMessage();
return true;
} else if (KeyEvent.KEYCODE_SPACE){
playOrPauseMedia();
return true;
} else {
return super.onKeyUp(keyCode, event);
}
}
Un evento onKeyUp si verifica quando viene rilasciato un tasto. L'utilizzo del callback
impedisce alle app di dover elaborare più eventi onKeyDown se un tasto
viene tenuto premuto o rilasciato lentamente. I giochi e le app che devono rilevare il momento in cui viene premuto un tasto o se l'utente lo sta tenendo premuto possono ascoltare l'evento onKeyDown e gestire autonomamente gli eventi onKeyDown ripetuti.
Per saperne di più, consulta Gestire le azioni della tastiera.
Scorciatoie
Le scorciatoie da tastiera comuni che includono i tasti Ctrl, Alt, Maiusc e Meta sono previste quando si utilizza una tastiera hardware. Se un'app non implementa scorciatoie, l'esperienza può risultare frustrante per gli utenti. Anche gli utenti avanzati apprezzano le scorciatoie per le attività specifiche delle app utilizzate di frequente. Le scorciatoie rendono un'app più facile da usare e la distinguono dalle app che non le hanno.
Alcune scorciatoie comuni includono Ctrl+S (salva), Ctrl+Z (annulla) e Ctrl+Maiusc+Z (ripristina). Per un elenco delle scorciatoie predefinite, vedi Gestire le azioni da tastiera.
Le scorciatoie possono essere attivate implementando dispatchKeyShortcutEvent() per intercettare tutte le combinazioni di tasti (Alt, Ctrl, Maiusc e Meta) per un determinato codice tasto.
Per verificare la presenza di un tasto di modifica specifico, utilizza:
KeyEvent.isCtrlPressed(),KeyEvent.isShiftPressed(),KeyEvent.isAltPressed(),KeyEvent.isMetaPressed()o
Kotlin
override fun dispatchKeyShortcutEvent(event: KeyEvent): Boolean {
return when (event.keyCode) {
KeyEvent.KEYCODE_O -> {
openFile() // Ctrl+O, Shift+O, Alt+O
true
}
KeyEvent.KEYCODE_Z-> {
if (event.isCtrlPressed) {
if (event.isShiftPressed) {
redoLastAction() // Ctrl+Shift+Z pressed
true
} else {
undoLastAction() // Ctrl+Z pressed
true
}
}
}
else -> {
return super.dispatchKeyShortcutEvent(event)
}
}
}
Java
@Override
public boolean dispatchKeyShortcutEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_O) {
openFile(); // Ctrl+O, Shift+O, Alt+O
return true;
} else if(event.getKeyCode() == KeyEvent.KEYCODE_Z) {
if (event.isCtrlPressed()) {
if (event.isShiftPressed()) {
redoLastAction();
return true;
}
else {
undoLastAction();
return true;
}
}
}
return super.dispatchKeyShortcutEvent(event);
}
La separazione del codice della scorciatoia dalla gestione di altre sequenze di tasti (ad esempio onKeyUp() e
onKeyDown()) accetta i tasti di modifica per impostazione predefinita senza dover implementare manualmente
i controlli dei tasti di modifica in ogni caso. Consentire tutte le combinazioni di tasti modificatori
può essere più comodo anche per gli utenti abituati a
layout di tastiera e sistemi operativi diversi.
Tuttavia, puoi implementare scorciatoie anche in onKeyUp() controllando
KeyEvent.isCtrlPressed(), KeyEvent.isShiftPressed() o
KeyEvent.isAltPressed(). Questa opzione può essere più facile da gestire se il comportamento modificato della chiave
è più una modifica al comportamento di un'app che una scorciatoia. Ad esempio, nei
giochi quando W significa "cammina in avanti" e Shift+W significa "corri
in avanti".
Kotlin
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
return when(keyCode) {
KeyEvent.KEYCODE_W-> {
if (event.isShiftPressed) {
if (event.isCtrlPressed) {
flyForward() // Ctrl+Shift+W pressed
true
} else {
runForward() // Shift+W pressed
true
}
} else {
walkForward() // W pressed
true
}
}
else -> super.onKeyUp(keyCode, event)
}
}
Java
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_W) {
if (event.isShiftPressed()) {
if (event.isCtrlPressed()) {
flyForward(); // Ctrl+Shift+W pressed
return true;
} else {
runForward(); // Shift+W pressed
return true;
}
} else {
walkForward();
return true;
}
}
return super.onKeyUp(keyCode, event);
}
Vedi anche la Guida scorciatoie da tastiera.
Stilo
Molti dispositivi con schermo grande sono dotati di stilo. Le app Android gestiscono gli stili come input touchscreen. Alcuni dispositivi potrebbero avere anche un tablet da disegno USB o Bluetooth, come Wacom Intuos. Le app per Android possono ricevere input Bluetooth, ma non input USB.
Un evento stilo viene segnalato come evento touchscreen da View#onTouchEvent()
o View#onGenericMotionEvent() e contiene un
MotionEvent#getSource() di tipo SOURCE_STYLUS.
L'oggetto MotionEvent contiene informazioni sull'evento:
MotionEvent#getToolType()restituisceTOOL_TYPE_FINGER,TOOL_TYPE_STYLUSoTOOL_TYPE_ERASERa seconda dello strumento che ha contattato il displayMotionEvent#getPressure()segnala la pressione fisica applicata alla penna stilo (se supportata)MotionEvent#getAxisValue()conMotionEvent.AXIS_TILTeMotionEvent.AXIS_ORIENTATIONforniscono l'inclinazione e l'orientamento fisici dello stilo (se supportato)
Punti storici
Android raggruppa gli eventi di input e li invia una volta per frame. Una stilo può
segnalare eventi a frequenze molto più elevate rispetto al display. Quando crei app di disegno, controlla gli eventi che potrebbero essersi verificati di recente utilizzando le API getHistorical:
MotionEvent#getHistoricalX()MotionEvent#getHistoricalY()MotionEvent#getHistoricalPressure()MotionEvent#getHistoricalAxisValue()
Palm rejection
Quando gli utenti disegnano, scrivono o interagiscono con la tua app utilizzando uno stilo, a volte
toccano lo schermo con il palmo della mano. L'evento tocco (impostato su
ACTION_DOWN o ACTION_POINTER_DOWN) può essere segnalato alla tua app
prima che il sistema riconosca e ignori il tocco involontario del palmo.
Android annulla gli eventi di tocco del palmo inviando un MotionEvent. Se la tua
app riceve ACTION_CANCEL, annulla il gesto. Se la tua app riceve
ACTION_POINTER_UP, controlla se è impostato FLAG_CANCELED. In questo caso, annulla
il gesto.
Non controllare solo FLAG_CANCELED. Su Android 13 (livello API 33) e versioni successive,
il sistema imposta FLAG_CANCELED per gli eventi ACTION_CANCEL, ma non imposta il flag sulle versioni precedenti di Android.
Android 12
Su Android 12 (livello API 32) e versioni precedenti, il rilevamento del rifiuto del palmo è possibile
solo per gli eventi tocco con un solo puntatore. Se il tocco del palmo è l'unico puntatore,
il sistema annulla l'evento impostando ACTION_CANCEL sull'oggetto
dell'evento di movimento. Se gli altri puntatori sono inattivi, il sistema imposta ACTION_POINTER_UP, che
non è sufficiente per rilevare il rifiuto del palmo.
Android 13
Su Android 13 (livello API 33) e versioni successive, se il tocco del palmo è l'unico puntatore,
il sistema annulla l'evento impostando ACTION_CANCEL e FLAG_CANCELED sull'oggetto evento di movimento. Se gli altri indicatori sono abbassati, il sistema imposta
ACTION_POINTER_UP e FLAG_CANCELED.
Ogni volta che la tua app riceve un evento di movimento con ACTION_POINTER_UP, controlla
FLAG_CANCELED per determinare se l'evento indica il rifiuto del palmo (o
un altro annullamento dell'evento).
App per prendere note
ChromeOS ha un intent speciale che mostra agli utenti le app per prendere appunti registrate. Per registrare un'app come app per prendere appunti, aggiungi quanto segue al manifest dell'app:
<intent-filter>
<action android:name="org.chromium.arc.intent.action.CREATE_NOTE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Quando un'app viene registrata nel sistema, l'utente può selezionarla come app predefinita
per prendere appunti. Quando viene richiesta una nuova nota, l'app deve creare una
nota vuota pronta per l'input con lo stilo. Quando l'utente vuole annotare un'immagine
(ad esempio uno screenshot o un'immagine scaricata), l'app viene avviata con ClipData
contenente uno o più elementi con URI content://. L'app deve creare una nota che utilizza la prima immagine allegata come immagine di sfondo e attivare una modalità in cui l'utente può disegnare sullo schermo con uno stilo.
Testare gli intenti di scrittura di note senza uno stilo
Per verificare se un'app risponde correttamente agli intent di creazione di note senza uno stilo attivo, utilizza il seguente metodo per visualizzare le opzioni di creazione di note su ChromeOS:
- Passare alla modalità sviluppatore e rendere scrivibile il dispositivo
- Premi Ctrl+Alt+F2 per aprire un terminale.
- Esegui il comando
sudo vi /etc/chrome_dev.conf. - Premi
iper modificare e aggiungere--ash-enable-palettea una nuova riga alla fine del file - Salva premendo Esc, quindi digitando :, w, q e premendo Invio.
- Premi Ctrl+Alt+F1 per tornare alla normale UI di ChromeOS.
- Esci e accedi di nuovo.
Ora sullo scaffale dovrebbe essere presente un menu dello stilo:
- Tocca il pulsante dello stilo nella barra e scegli Nuova nota. Si dovrebbe aprire una nota di disegno vuota.
- Fai uno screenshot. Dalla barra, seleziona pulsante dello stilo > Acquisisci schermo o scarica un'immagine. Nella notifica dovrebbe essere presente l'opzione Annota immagine. In questo modo l'app dovrebbe avviarsi con l'immagine pronta per essere annotata.
Supporto per mouse e touchpad
La maggior parte delle app in genere deve gestire solo tre eventi incentrati sul grande schermo: clic con il tasto destro del mouse, passaggio del mouse e trascinamento e rilascio.
Fare clic con il pulsante destro del mouse
Qualsiasi azione che fa sì che un'app mostri un menu contestuale, ad esempio toccare e tenere premuto un elemento di elenco, deve reagire anche agli eventi di clic con il tasto destro del mouse.
Per gestire gli eventi di clic con il tasto destro del mouse, le app devono registrare un
View.OnContextClickListener:
Kotlin
yourView.setOnContextClickListener {
showContextMenu()
true
}
Java
yourView.setOnContextClickListener(v -> {
showContextMenu();
return true;
});
Per informazioni dettagliate sulla creazione di menu contestuali, vedi Creare un menu contestuale.
Passaci il mouse sopra
Puoi rendere i layout delle app più raffinati e facili da usare gestendo gli eventi al passaggio del mouse. Ciò vale soprattutto per i componenti visualizzazioni:
Kotlin
// Change the icon to a "hand" pointer on hover.
// Highlight the view by changing the background.
yourView.setOnHoverListener { view, _ ->
addVisualHighlighting(true)
view.pointerIcon =
PointerIcon.getSystemIcon(view.context, PointerIcon.TYPE_HAND)
true // Listener consumes the event.
}
Java
// Change the icon to a "hand" pointer on hover.
// Highlight the view by changing the background.
yourView.setOnHoverListener((view, event) -> {
addVisualHighlighting(true);
view.setPointerIcon(
PointerIcon.getSystemIcon(view.getContext(), PointerIcon.TYPE_HAND)
);
return true; // Listener consumes the event.
});
I due esempi più comuni sono:
- Indicare agli utenti se un elemento ha un comportamento interattivo, ad esempio se è cliccabile o modificabile, modificando l'icona del puntatore del mouse
- Aggiunta di un feedback visivo agli elementi di un elenco o di una griglia di grandi dimensioni quando il puntatore li sorvola
Trascina
In un ambiente multi-finestra, gli utenti si aspettano di poter trascinare gli elementi tra le app. Questo vale sia per i computer che per tablet, smartphone e dispositivi pieghevoli in modalità split-screen.
Valuta se è probabile che gli utenti trascinino elementi nella tua app. Ad esempio, gli editor di foto dovrebbero aspettarsi di ricevere foto, i lettori audio dovrebbero aspettarsi di ricevere file audio e i programmi di disegno dovrebbero aspettarsi di ricevere foto.
Per aggiungere il supporto del trascinamento, vedi Attivare il trascinamento e consulta il post del blog Android su ChromeOS: implementazione del trascinamento.
Considerazioni speciali per ChromeOS
- Ricorda di richiedere l'autorizzazione con
requestDragAndDropPermissions()per accedere agli elementi trascinati dall'esterno dell'app Un elemento deve avere il flag
View.DRAG_FLAG_GLOBALper poter essere trascinato in altre applicazioni
Supporto avanzato del puntatore
Le app che gestiscono in modo avanzato l'input del mouse e del touchpad devono implementare un modificatore
View#onGenericMotionEvent() e utilizza [MotionEvent.getSource()][] per
distinguere tra SOURCE_MOUSE e SOURCE_TOUCHSCREEN.
Esamina l'oggetto MotionEvent per implementare il comportamento richiesto:
- Il movimento genera eventi
ACTION_HOVER_MOVE. - I pulsanti generano eventi
ACTION_BUTTON_PRESSeACTION_BUTTON_RELEASE. Puoi anche controllare lo stato attuale di tutti i pulsanti del mouse e del trackpad utilizzandogetButtonState(). - Lo scorrimento della rotellina del mouse genera eventi
ACTION_SCROLL.
Controller di gioco
Alcuni dispositivi Android con schermo di grandi dimensioni supportano fino a quattro controller di gioco. Utilizza le API standard per i controller di gioco Android per gestire i controller di gioco (vedi Supporto dei controller di gioco).
I pulsanti del controller di gioco sono mappati su valori comuni seguendo una mappatura comune. Tuttavia, non tutti i produttori di controller di gioco seguono le stesse convenzioni di mappatura. Puoi offrire un'esperienza molto migliore se consenti agli utenti di selezionare diverse mappature dei controller più diffuse. Per maggiori informazioni, consulta la pagina Elaborare pressioni dei pulsanti del gamepad.
Modalità di traduzione dell'input
ChromeOS attiva una modalità di traduzione dell'input per impostazione predefinita. Per la maggior parte delle app per Android, questa modalità consente alle app di funzionare come previsto in un ambiente desktop. Alcuni esempi includono l'attivazione automatica dello scorrimento con due dita sul touchpad, lo scorrimento con la rotellina del mouse e la mappatura delle coordinate del display non elaborate con le coordinate della finestra. In genere, gli sviluppatori di app non devono implementare autonomamente nessuno di questi comportamenti.
Se un'app implementa un comportamento di input personalizzato, ad esempio definendo un'azione di pizzico personalizzata con due dita sul touchpad, o se queste traduzioni di input non forniscono gli eventi di input previsti dall'app, puoi disattivare la modalità di traduzione di input aggiungendo il seguente tag al manifest Android:
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />