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, segui questi passaggi:
- Testa il supporto di base della tastiera, ad esempio Ctrl+Z per annullare, Ctrl+C per copiare e Ctrl+S per salvare. Consulta Gestisci le azioni della tastiera per un elenco delle scorciatoie da tastiera predefinite.
- Testa il supporto avanzato della tastiera, ad esempio la navigazione da tastiera con i tasti Tab e le frecce, la conferma dell'inserimento di testo con il tasto Invio e la riproduzione e la messa in pausa con la barra spaziatrice nelle app multimediali.
- Testa le interazioni di base con il mouse, tra cui il clic con il tasto destro del mouse per il menu contestuale, le modifiche alle icone al passaggio del mouse e gli eventi di scorrimento con la rotellina del mouse o il trackpad sui componenti personalizzati.
- Testa i dispositivi di input specifici per l'app, come stilo, controller di gioco e controller MIDI per app musicali.
- Prendi in considerazione il supporto di input avanzati che potrebbero 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 l'app risponde all'input da tastiera contribuisce all'esperienza utente su schermi di grandi dimensioni. Esistono tre tipi di input da tastiera: navigazione, pressioni di tasti e scorciatoie.
Navigazione
La navigazione da tastiera viene implementata raramente nelle app incentrate sul tocco, ma gli utenti se l'aspettano quando utilizzano un'app e hanno le mani su una tastiera. La navigazione da tastiera può essere essenziale su smartphone, tablet, pieghevoli e computer per gli utenti con esigenze di accessibilità.
Per molte app, la navigazione con i tasti Freccia e Tab viene gestita automaticamente dal framework Android. Ad esempio, un Button è attivabile per impostazione predefinita e la navigazione da tastiera dovrebbe funzionare in genere senza 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 tramite 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 dello stato attivo.
Quando lo stato attivo è abilitato, il framework Android crea una mappatura di navigazione per tutte le visualizzazioni attivabili in base alla loro posizione. In genere, questo funziona come previsto e non è necessario alcun ulteriore sviluppo. Quando la mappatura predefinita non è corretta per le esigenze di un'app, 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 UI della tua app utilizzando solo la tastiera. Gli elementi utilizzati di frequente devono essere accessibili senza input tramite mouse o tocco.
Ricorda che il supporto della tastiera potrebbe essere essenziale per gli utenti con esigenze di accessibilità.
Sequenze di tasti
Per l'inserimento 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 pressioni dei tasti che non possono essere previste dal framework,
le app devono gestire il comportamento autonomamente. Questo è particolarmente vero per le app
con visualizzazioni 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 i movimenti 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 keycode 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 un tasto viene rilasciato. L'utilizzo del callback
evita che le app debbano 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 tiene premuto un tasto possono ascoltare l'evento onKeyDown e gestire autonomamente gli eventi onKeyDown ripetuti.
Per saperne di più, consulta Gestisci le azioni della tastiera.
Scorciatoie
Quando utilizzi una tastiera hardware, sono previste scorciatoie da tastiera comuni che includono i tasti Ctrl, Alt, Maiusc e Meta. Se un'app non implementa le scorciatoie, l'esperienza può risultare frustrante per gli utenti. Gli utenti esperti apprezzano anche le scorciatoie per le attività specifiche dell'app utilizzate di frequente. Le scorciatoie rendono un'app più facile da usare e la differenziano dalle app che non ne hanno.
Alcune scorciatoie comuni includono Ctrl+S (salva), Ctrl+Z (annulla) e Ctrl+Maiusc+Z (ripeti). Per un elenco delle scorciatoie predefinite, consulta Gestisci 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 delle scorciatoie da un'altra gestione della pressione dei tasti (come 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 di modifica può anche essere più comodo per gli utenti abituati a layout della tastiera e sistemi operativi diversi.
Tuttavia, puoi anche implementare le scorciatoie in onKeyUp() controllando
KeyEvent.isCtrlPressed(), KeyEvent.isShiftPressed() o
KeyEvent.isAltPressed(). Questo può essere più facile da gestire se il comportamento del tasto modificato è più una modifica al comportamento di un'app che una scorciatoia. Ad esempio, nei giochi in cui W significa "cammina in avanti" e Maiusc + 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 Strumento per le scorciatoie da tastiera.
Stilo
Molti dispositivi con schermo grande sono dotati di uno stilo. Le app per Android gestiscono gli stilo come input touchscreen. Alcuni dispositivi potrebbero anche avere una tavoletta grafica USB o Bluetooth, come Wacom Intuos. Le app per Android possono ricevere input Bluetooth, ma non input USB.
Un evento dello stilo viene segnalato come evento del 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 toccato il displayMotionEvent#getPressure()segnala la pressione fisica applicata alla 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. Uno stilo può
segnalare eventi a frequenze molto più elevate rispetto al display. Quando crei app di disegno, controlla gli eventi che potrebbero essersi verificati nel recente passato 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 touch (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 touch 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 FLAG_CANCELED è impostato. 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 di Android precedenti.
Android 12
Su Android 12 (livello API 32) e versioni precedenti, il rilevamento della funzionalità di palm rejection è possibile solo per gli eventi touch con un singolo puntatore. Se il tocco con il palmo è l'unico puntatore,
il sistema annulla l'evento impostando ACTION_CANCEL sull'oggetto
evento di movimento. Se altri puntatori sono in basso, 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 con il palmo è l'unico puntatore, il sistema annulla l'evento impostando ACTION_CANCEL e FLAG_CANCELED sull'oggetto dell'evento di movimento. Se altri puntatori sono in basso, 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 palm rejection (o
un altro annullamento dell'evento).
App per prendere appunti
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 richiesto un nuovo appunto, l'app deve creare un appunto vuoto pronto 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 utilizzi la prima immagine allegata come immagine di sfondo e attivare una modalità in cui l'utente può disegnare sullo schermo con uno stilo.
Testa gli intent per prendere appunti senza uno stilo
Per verificare se un'app risponde correttamente agli intent di scrittura di note senza uno stilo attivo, utilizza il seguente metodo per visualizzare le opzioni di scrittura di note su ChromeOS:
- Passa alla modalità sviluppatore e rendi il dispositivo scrivibile
- Premi Ctrl+Alt+F2 per aprire un terminale.
- Esegui il comando
sudo vi /etc/chrome_dev.conf - Premi
iper modificare e aggiungi--ash-enable-palettein una nuova riga alla fine del file - Salva premendo Esc, quindi digita :, w, q e premi 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 sulla barra delle app e scegli Nuova nota. Dovrebbe aprirsi una nota di disegno vuota.
- Fai uno screenshot. Dalla barra delle app, 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
In genere, la maggior parte delle app deve gestire solo tre eventi incentrati sugli schermi di grandi dimensioni: clic con il tasto destro del mouse, passaggio del mouse e trascinamento.
Fare clic con il pulsante destro del mouse
Tutte le azioni che fanno sì che un'app mostri un menu contestuale, come toccare e tenere premuto un elemento dell'elenco, devono anche reagire 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 maggiori dettagli sulla creazione di menu contestuali, vedi Crea un menu contestuale.
Passaci il mouse sopra
Puoi rendere i layout della tua app più rifiniti e facili da usare gestendo gli eventi di passaggio del mouse. Questo vale in particolare 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 si trova sopra di essi
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 i tablet, gli smartphone e i pieghevoli in modalità schermo diviso.
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, consulta Attiva il trascinamento e dai un'occhiata al blog post Android su ChromeOS - Implementazione del trascinamento.
Considerazioni speciali per ChromeOS
- Ricordati 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 di puntatori avanzati
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 gli eventi
ACTION_BUTTON_PRESSeACTION_BUTTON_RELEASE. Puoi anche controllare lo stato attuale di tutti i pulsanti del mouse e del trackpad utilizzandogetButtonState(). - Lo scorrimento con la rotellina del mouse genera eventi
ACTION_SCROLL.
Controller di gioco
Alcuni dispositivi Android con schermo grande supportano fino a quattro controller di gioco. Utilizza le API standard dei controller di gioco Android per gestire i controller di gioco (consulta Supporta i controller di gioco).
I pulsanti del controller di gioco sono associati a valori comuni seguendo una mappatura comune. Tuttavia, non tutti i produttori di controller per videogiochi 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à Traduzione input
ChromeOS attiva una modalità 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 di visualizzazione non elaborate alle coordinate della finestra. In genere, gli sviluppatori di app non devono implementare nessuno di questi comportamenti.
Se un'app implementa un comportamento di input personalizzato, ad esempio definendo un'azione di pizzicamento del touchpad con due dita personalizzata, 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 file manifest Android:
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />