Sui dispositivi ChromeOS, molti utenti interagiscono con le app utilizzando una tastiera, un mouse, un trackpad, uno stilo o un gamepad. Sebbene questi dispositivi di input vengano utilizzati anche sugli smartphone Android, non sono così comuni e spesso vengono trascurati dagli sviluppatori.
Gli sviluppatori che vogliono che la loro app funzioni bene con l'input su ChromeOS e altri dispositivi Android con schermi di grandi dimensioni devono esaminare i seguenti ottimizzazioni:
- Aggiungi e testa il supporto di base della tastiera, ad esempio la navigazione tramite i tasti Freccia e Tab, il tasto Invio per confermare l'inserimento di testo e la barra spaziatrice per riprodurre/mettere in pausa nelle app multimediali.
-
Aggiungi scorciatoie da tastiera standard, ove applicabile, ad esempio
ctrl+zper annullare ectrl+sper salvare. - Testa le interazioni di base del mouse, come il clic con il tasto destro del mouse per il menu contestuale, le modifiche delle icone al passaggio del mouse e gli eventi di scorrimento della rotellina del mouse/del trackpad nelle visualizzazioni personalizzate.
- Testa i dispositivi di input specifici per le app, come stilo per le app di disegno, controller di gioco per i giochi e controller MIDI per le app musicali.
- Valuta la possibilità di aggiungere il supporto di input avanzato che potrebbe far risaltare l'app negli ambienti desktop: il touchpad come crossfader per le app DJ, l'acquisizione del mouse per i giochi e le scorciatoie da tastiera estese per gli utenti esperti.
Tastiera
Il modo in cui la tua app risponde all'input da tastiera contribuisce a una buona esperienza desktop. 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 la aspettano quando utilizzano un'app con una tastiera. Può anche essere essenziale per gli utenti con esigenze di accessibilità sia su smartphone che su computer.
Per molte app, la navigazione con i tasti freccia e Tab è tutto ciò che serve e viene gestita automaticamente dal framework Android. Ad esempio, una visualizzazione di un Button è selezionabile 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, gli sviluppatori devono contrassegnarle come attivabili. Questa operazione può essere eseguita a livello di programmazione o in XML, come segue. Per saperne di più, consulta la documentazione relativa alla gestione della messa a fuoco.
yourView.isFocusable = true
In alternativa, puoi impostare l'attributo focusable nel file di layout:
android:focusable="true"
Una volta attivato lo stato attivo, il framework Android creerà una mappatura di navigazione per tutte le visualizzazioni selezionabili in base alla loro posizione. In genere, questa operazione funziona come previsto e non è necessario alcun lavoro aggiuntivo. Quando la mappatura predefinita non è corretta per le esigenze di un'app, può essere sostituita nel seguente modo:
// 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
È buona norma provare ad accedere a ogni parte della funzionalità della tua app prima di ogni release utilizzando solo la tastiera. Dovrebbe essere possibile accedere alle azioni più comuni senza input da mouse o tocco.
Nota: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 un EditText, le app dovrebbero comportarsi come previsto su ChromeOS senza alcun lavoro aggiuntivo da parte dello sviluppatore. Per le sequenze di tasti che non possono essere previste dal framework, le app dovranno gestire autonomamente il comportamento. Ciò è 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/interrompono la riproduzione con il tasto Spazio e i giochi che controllano il movimento con i tasti W, A, S e D.
La maggior parte delle app esegue l'override dell'evento onKeyUp e aggiunge il comportamento previsto per ogni codice tasto ricevuto, come segue.
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) } }
L'utilizzo di onKeyUp impedisce alle app di ricevere più eventi se un tasto viene tenuto premuto o rilasciato lentamente. I giochi e le app che richiedono agli utenti di tenere premuti i tasti della tastiera possono cercare l'evento onKeyDown.
A seconda delle esigenze di un'app, l'override di onKeyUp per l'intera attività in genere fornisce il comportamento necessario. Se necessario, puoi aggiungere un onKeyListener a una visualizzazione specifica. Ad esempio, un'app può ascoltare solo il tasto Invio in EditText specifico e non nell'attività, per implementare la funzionalità di invio solo quando l'utente sta digitando in una casella di chat.
Quando aggiungi il supporto della tastiera, segui la documentazione sulla gestione della tastiera di Android.
Scorciatoie
Le scorciatoie comuni basate su ctrl, alt e shift sono previste negli ambienti desktop. Se un'app non le implementa, l'esperienza può risultare frustrante e interrotta 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 Salva (ctrl+s), Annulla (ctrl+z) e Ripeti (ctrl+shift+z). Per un esempio di scorciatoie più avanzate, consulta l'elenco dei tasti di scelta rapida di VLC Media Player.
Le scorciatoie possono essere implementate utilizzando dispatchKeyShortcutEvent. In questo modo vengono intercettate tutte le combinazioni di meta-tasti (alt, ctrl e shift) per un determinato codice tasto. Per verificare la presenza di una meta-chiave specifica, utilizza KeyEvent.isCtrlPressed(), KeyEvent.isShiftPressed(), KeyEvent.isAltPressed() o KeyEvent.hasModifiers().
La separazione del codice della scorciatoia dalla gestione di altre sequenze di tasti (ad esempio onKeyUp o onKeyDown) può semplificare la manutenzione del codice e mantiene l'accettazione predefinita dei tasti meta senza dover implementare manualmente i controlli dei tasti meta in ogni caso. Consentire tutte le combinazioni di meta-tasti può anche essere più comodo per gli utenti abituati a layout di tastiera e sistemi operativi diversi.
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) } } }
Puoi anche implementare le scorciatoie in onKeyUp controllando KeyEvent.isCtrlPressed(), KeyEvent.isShiftPressed() o KeyEvent.isAltPressed() nello stesso modo. Può essere più facile da gestire se il meta-comportamento è più una modifica al comportamento di un'app che una scorciatoia. Ad esempio, quando w significa "cammina in avanti" e Maiusc+w significa "corri in avanti".
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 } } else -> super.onKeyUp(keyCode, event) } }
Supporto per mouse e touchpad
ChromeOS gestisce automaticamente la maggior parte degli eventi del mouse e del trackpad in modo che si comportino come eventi tocco su uno smartphone Android. Ciò include lo scorrimento con due dita sul touchpad/sulla rotellina del mouse. La maggior parte delle app in genere deve gestire solo tre eventi incentrati sul desktop: Fai clic con il tasto destro del mouse, Passaggio del mouse e Trascina e rilascia.
Fare clic con il pulsante destro del mouse
Qualsiasi azione che fa sì che un'app mostri un menu contestuale, ad esempio una pressione prolungata su 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. Per informazioni dettagliate sulla creazione di un menu contestuale, consulta la documentazione sul menu contestuale di Android.
yourView.setOnContextClickListener { view -> showContextMenu() true }
Nota:tutte le visualizzazioni registrate per un menu contestuale utilizzando Activity.registerForContextMenu() dovrebbero funzionare automaticamente sia con la pressione prolungata sia con il clic con il tasto destro del mouse senza la necessità di registrare un listener di clic contestuale.
Passaci il mouse sopra
Gli sviluppatori possono rendere i layout delle loro app più raffinati e facili da usare gestendo gli eventi al passaggio del mouse. Ciò vale in particolare per le visualizzazioni personalizzate. I due esempi più comuni sono:
- Indicare agli utenti se un elemento ha un comportamento interattivo, ad esempio se è selezionabile 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
// 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(applicationContext, PointerIcon.TYPE_HAND) false // listener did not consume the event. }
Trascina
In un ambiente multi-finestra, gli utenti si aspettano di poter trascinare gli elementi tra le app. Questo vale sia per i dispositivi ChromeOS sia per tablet, smartphone e pieghevoli in modalità split-screen.
Gli sviluppatori devono valutare se è probabile che gli utenti trascinino elementi nella loro app. Alcuni esempi comuni includono: 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, segui la documentazione sul trascinamento di Android e dai un'occhiata a questo post del blog di ChromeOS.
Considerazioni speciali per ChromeOS
-
Per gestire i file dall'app Files di ChromeOS, cerca il tipo MIME
application/x-arc-uri-list -
Ricorda di richiedere l'autorizzazione utilizzando
requestDragAndDropPermissionsper 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 della selezione multipla
Se la tua app contiene elenchi o griglie, valuta se i tuoi utenti trarrebbero vantaggio dal supporto della selezione multipla. Un'esperienza di selezione multipla di alta qualità con mouse e trackpad spesso include funzionalità come la selezione della band. L'implementazione autonoma può essere difficile, ma puoi utilizzare la libreria di selezione RecyclerView.
Supporto avanzato del puntatore
Le app che gestiscono in modo avanzato l'input del mouse e del touchpad devono seguire la documentazione di Android per View.onGenericMotionEvent() e utilizzare MotionEvent.getSource() per distinguere tra SOURCE_MOUSE e SOURCE_TOUCHSCREEN.
Esamina MotionEvent per implementare il comportamento richiesto:
-
Il movimento genera
ACTION_HOVER_MOVEeventi -
I pulsanti generano eventi
ACTION_BUTTON_PRESSeACTION_BUTTON_RELEASE. Puoi anche controllare lo stato attuale di tutti i pulsanti del mouse/trackpad utilizzandogetButtonState(). -
Lo scorrimento della rotellina del mouse genera eventi
ACTION_SCROLL
Stilo
Molti Chromebook sono dotati di uno stilo e le app per Android lo gestiscono 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 funzionano con l'input USB.
Un evento stilo viene segnalato come evento touchscreen utilizzando View.onTouchEvent() o View.onGenericMotionEvent() e contiene un MotionEvent.getSource() di tipo SOURCE_STYLUS. Il MotionEvent conterrà anche dati aggiuntivi:
-
MotionEvent.getToolType()restituiràTOOL_TYPE_FINGER,TOOL_TYPE_STYLUSoTOOL_TYPE_ERASERa seconda dell'utensile che è entrato in contatto con la superficie -
MotionEvent.getPressure()segnalerà la pressione fisica applicata allo stilo, se supportata -
MotionEvent.getAxisValue()conMotionEvent.AXIS_TILTeMotionEvent.AXIS_ORIENTATION, che possono essere utilizzati per leggere l'inclinazione e l'orientamento fisici dello stilo, se supportati
Punti storici
Android raggruppa gli eventi di input e li invia una volta per frame. Una penna stilo può segnalare eventi a frequenze molto più elevate rispetto al display. Quando crei app di disegno, è importante controllare gli eventi che potrebbero essersi verificati di recente utilizzando le API getHistorical:
-
MotionEvent.getHistoricalX() -
MotionEvent.getHistoricalY() -
MotionEvent.getHistoricalPressure() -
MotionEvent.getHistoricalAxisValue()
Palm rejection
ChromeOS tenta di riconoscere quando il palmo della mano di un utente è appoggiato sul touchscreen. Tuttavia, non è sempre possibile. A volte un evento tocco potrebbe essere segnalato all'app prima che il sistema operativo lo riconosca come tocco del palmo. In questo caso, i tocchi verranno annullati segnalando un evento ACTION_CANCEL.
Questo evento comunica all'app che alcuni tocchi non sono validi e che deve annullare tutte le interazioni causate da questi tocchi. Ad esempio, un'app di disegno potrebbe disegnare temporaneamente nuove linee non appena vengono ricevute per fornire la latenza più bassa, ma le aggiungerà in modo permanente alla tela solo una volta terminata la serie di tocchi. Se nel frattempo gli eventi tocco vengono annullati, le linee temporanee possono essere cancellate.
Nota:un modo per ridurre gli eventi estranei di palmo e dita nelle app di disegno e scrittura è fornire un'impostazione dell'interfaccia utente che disattivi il disegno tramite tocco e utilizzi solo gli eventi stilo per disegnare in questa modalità.
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 Android:
<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, l'utente può selezionarla come app per prendere appunti predefinita. 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 con uno stilo.
Test degli intent di scrittura di note senza stilo
Per verificare se un'app risponde correttamente agli intent di presa di appunti senza uno stilo attivo, utilizza il seguente metodo per visualizzare le opzioni di presa di appunti:
- Passare alla modalità sviluppatore e rendere scrivibile il dispositivo
-
Premi
ctrl+alt+f2per 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
Esce poi digitando:,w,qe premendoEnter. -
Premi
ctrl+alt+f1per tornare alla normale UI di ChromeOS
Ora nello scaffale dovrebbe essere presente un menu della stilo:
- Tocca il pulsante dello stilo nella barra e scegli Nuova nota. Si aprirà una nota di disegno vuota.
- Acquisisci 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.
Controller di gioco
I Chromebook supportano fino a quattro controller di gioco. Gli sviluppatori devono utilizzare le API Game Controller standard di Android per gestirli.
I pulsanti sono mappati a valori comuni seguendo una mappatura comune. Purtroppo, 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ù comuni.
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 della rotellina del mouse e la mappatura delle coordinate del display non elaborate alle 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 del touchpad a due dita, o se queste traduzioni dell'input non forniscono gli eventi di input previsti dall'app, puoi disattivare la modalità di traduzione dell'input aggiungendo il seguente tag al manifest Android:
<uses-feature android:name="android.hardware.type.pc" android:required="false" />