Compatibilità degli input con schermi di grandi dimensioni

Sui dispositivi con schermi di grandi dimensioni, gli utenti interagiscono spesso con le app utilizzando una tastiera, un mouse, un trackpad, uno stilo o una tastiera da gioco. Per consentire all'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 messa in pausa con la barra spaziatrice nelle app multimediali.
  • Esegui test di interazioni di base con il mouse, tra cui clic con il tasto destro del mouse per il menu contestuale, modifiche delle icone al passaggio del mouse e eventi di scorrimento della rotellina del mouse o del trackpad sui componenti personalizzati.
  • Testare dispositivi di input specifici per l'app, come stili, controller per videogiochi e controller MIDI per app musicali.
  • Valuta la possibilità di supportare input avanzati che potrebbero far risaltare l'app negli ambienti desktop, ad esempio il touchpad come cross-fader per le app di DJ, il rilevamento del mouse per i giochi e le scorciatoie da tastiera per gli utenti che utilizzano molto la tastiera.

Tastiera

Il modo in cui la tua app risponde all'input della tastiera contribuisce all'esperienza utente sullo schermo di grandi dimensioni. Esistono tre tipi di input da tastiera: navigazione, pressioni dei tasti e scorciatoie.

La navigazione con tastiera viene implementata raramente nelle app incentrate sul tocco, ma gli utenti se lo aspettano quando utilizzano un'app e hanno le mani sulla tastiera. La navigazione con la 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 la navigazione con le schede vengono gestite automaticamente dal framework Android. Ad esempio, un Button è acquisibile per impostazione predefinita e la navigazione con tastiera in genere dovrebbe funzionare senza alcun codice aggiuntivo. Per attivare la navigazione da tastiera per le visualizzazioni che non sono attivabili per impostazione predefinita, contrassegnale come attivabili, il che può essere fatto 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 della messa a fuoco.

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 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 dell'interfaccia utente della tua app utilizzando solo la tastiera. Gli elementi utilizzati frequentemente devono essere accessibili senza input del 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), come per un EditText , le app dovrebbero comportarsi come previsto sui dispositivi con schermi di grandi dimensioni senza ulteriore sviluppo. Per le sequenze di tasti che non possono essere anticipate 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 il movimento con i tasti w, a, s e d.

La maggior parte delle app sostituisce il callback onKeyUp() e aggiunge il comportamento previsto per ogni codice chiave ricevuto:

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 rilasciata una chiave. L'utilizzo del callback impedisce alle app di dover elaborare più eventi onKeyDown se un tasto viene premuto a lungo 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 ulteriori informazioni, 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 le scorciatoie, l'esperienza può risultare frustrante per gli utenti. Gli utenti avanzati apprezzano anche le scorciatoie per le attività specifiche dell'app usate di frequente. Le scorciatoie semplificano l'utilizzo di un'app e la distinguono da quelle che non ne hanno.

Alcune scorciatoie comuni includono Ctrl+S (salva), Ctrl+Z (annulla) e Ctrl+Maiusc+Z (ripristina). Per un elenco delle scorciatoie predefinite, consulta 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 a tasti. Per verificare la presenza di un tasto di modifica specifico, utilizza:

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);
}

Se separi il codice della scorciatoia dall'altra gestione delle battute (ad esempio onKeyUp() e onKeyDown()), per impostazione predefinita vengono accettati i tasti di modifica senza doverli implementare manualmente in ogni caso. Consentire tutte le combinazioni di tasti modificatori può essere più pratico anche per gli utenti abituati a diversi layout di tastiera e sistemi operativi.

Tuttavia, puoi anche implementare le scorciatoie in onKeyUp() controllando la presenza di KeyEvent.isCtrlPressed(), KeyEvent.isShiftPressed() o KeyEvent.isAltPressed(). Questo può essere più facile da gestire se il comportamento della chiave modificata è più una modifica al comportamento di un'app che una scorciatoia. Ad esempio, nei giochi W significa "avanza" e Maiusc+W significa "corri".

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);
}

Consulta anche la Guida alle scorciatoie da tastiera.

Stilo

Molti dispositivi con schermo grande sono dotati di uno stilo. Le app Android gestiscono gli stili come input touchscreen. Alcuni dispositivi potrebbero avere anche una tavoletta da disegno USB o Bluetooth, come Wacom Intuos. Le app per Android possono ricevere input Bluetooth, ma non input USB.

Un evento con il tocco di uno stilo viene registrato come evento tocco sullo schermo da View#onTouchEvent() o View#onGenericMotionEvent() e contiene un MotionEvent#getSource() di tipo SOURCE_STYLUS.

L'oggetto MotionEvent contiene informazioni sull'evento:

Punti storici

Android raggruppa gli eventi di input e li invia una volta per frame. Uno stilo può registrare gli eventi a frequenze molto più elevate rispetto al display. Quando crei app di disegno, controlla la presenza di eventi che potrebbero risalire al passato recente utilizzando le API getHistorical:

Rifiuto della palma

Quando gli utenti disegnano, scrivono o interagiscono con la tua app utilizzando uno stilo, a volte toccano lo schermo con il palmo delle mani. L'evento tocco (impostato su ACTION_DOWN o ACTION_POINTER_DOWN) può essere segnalato all'app prima che il sistema riconosca e ignori il tocco involontario con il palmo.

Android annulla gli eventi tocco con il 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 cursore. Se l'unico puntatore è il tocco del palmo, il sistema annulla l'evento impostando ACTION_CANCEL sull'oggetto dell'evento di movimento. Se gli altri cursori sono disattivati, il sistema imposta ACTION_POINTER_UP, che è insufficiente 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 cursore, il sistema annulla l'evento impostando ACTION_CANCEL e FLAG_CANCELED sull'oggetto evento di movimento. Se gli altri indicatori 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 se è presente FLAG_CANCELED per determinare se l'evento indica il rifiuto del palmo (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 di note, 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 è registrata nel sistema, l'utente può selezionarla come app predefinita per la presa di appunti. Quando viene richiesta una nuova nota, l'app deve creare una nota vuota pronta per l'inserimento con lo stilo. Quando l'utente vuole annotare un'immagine (ad esempio uno screenshot o un'immagine scaricata), l'app si avvia con ClipData contenente uno o più elementi con URI content://. L'app deve creare un'annotazione 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.

Testare le intent di scrittura di note senza uno stilo

[TBD remove section.]

Per verificare se un'app risponde correttamente agli intent di presa di appunti senza un attivo, usa il seguente metodo per visualizzare le opzioni di presa di appunti su ChromeOS:

  1. Passare alla modalità sviluppatore e rendere il dispositivo scrivibile
  2. Premi Ctrl+Alt+F2 per aprire un terminale
  3. Esegui il comando sudo vi /etc/chrome_dev.conf
  4. Premi i per modificare e aggiungere --ash-enable-palette a una nuova riga alla fine del file
  5. Salva premendo Esc, quindi digita :, w, q e premi Invio.
  6. Premi Ctrl+Alt+F1 per tornare alla normale interfaccia utente di ChromeOS
  7. Esci e accedi di nuovo

Sullo scaffale dovrebbe essere visualizzato un menu per lo stilo:

  • Tocca il pulsante dello stilo nella sezione App e scegli Nuova nota. Dovrebbe aprirsi una nota di disegno vuota.
  • Acquisisci uno screenshot. Dalla sezione, seleziona pulsante dello stilo > Acquisisci schermata o scarica un'immagine. Nella notifica dovrebbe essere presente l'opzione Aggiungi annotazioni all'immagine. L'app dovrebbe essere avviata con l'immagine pronta per essere annotata.

Supporto di 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 tasto destro del mouse

Eventuali azioni che causano la visualizzazione di un menu contestuale in un'app, ad esempio toccare e tenere premuto un elemento dell'elenco, devono 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 maggiori dettagli 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 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 cursore del mouse
  • Aggiunta di feedback visivo agli elementi di un elenco o una griglia di grandi dimensioni quando il cursore li passa sopra

Trascina

In un ambiente con più finestre, gli utenti si aspettano di poter trascinare gli elementi tra le app. Questo vale per i computer, nonché per tablet, smartphone e dispositivi pieghevoli in modalità schermo diviso.

Valuta se è probabile che gli utenti trascinino elementi nella tua app. Ad esempio, gli editor di foto devono aspettarsi di ricevere foto, i lettori audio devono aspettarsi di ricevere file audio e i programmi di disegno devono aspettarsi di ricevere foto.

Per aggiungere il supporto del trascinamento, consulta Attivare il trascinamento e dai un'occhiata al post del blog Android su ChromeOS - Implementazione del trascinamento.

Considerazioni speciali per ChromeOS

Supporto avanzato del cursore

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 ACTION_HOVER_MOVE eventi.
  • I pulsanti generano eventi ACTION_BUTTON_PRESS e ACTION_BUTTON_RELEASE. Puoi anche controllare lo stato attuale di tutti i pulsanti del mouse e del trackpad utilizzando getButtonState().
  • Lo scorrimento della 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 di controller per giochi Android standard per gestire i controller per giochi (vedi Supportare i controller per giochi).

I pulsanti del controller di gioco sono mappati a valori comuni seguendo una mappatura comune. Tuttavia, non tutti i produttori di controller per giochi seguono le stesse convenzioni di mappatura. Puoi offrire un'esperienza molto migliore se consenti agli utenti di selezionare diverse mappature dei controller comuni. Per ulteriori informazioni, consulta la pagina Elaborare pressioni dei pulsanti del gamepad.

Modalità di immissione della traduzione

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 personalmente nessuno di questi comportamenti.

Se un'app implementa un comportamento di immissione 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 Android manifest:

<uses-feature
    android:name="android.hardware.type.pc"
    android:required="false" />

Risorse aggiuntive