Supportare i display collegati

I display connessi estendono l'esperienza delle finestre delle app agli smartphone standard, offrendo agli utenti l'accesso a schermi di grandi dimensioni dai loro dispositivi mobili. Questa funzionalità apre nuove possibilità per l'interazione con le app e la produttività degli utenti.

Tutte le funzionalità uniche delle finestre delle app si applicano ai display collegati. Quando colleghi uno smartphone a un display, lo stato dello smartphone rimane invariato e sul display collegato viene avviata una sessione desktop vuota. Il dispositivo e il display fungono da due sistemi individuali, con app specifiche per ogni display.

Figura 1. Smartphone connesso a un display esterno, con una sessione desktop sul display mentre lo smartphone mantiene il proprio stato.

Se colleghi un dispositivo con le finestre delle app attivate, ad esempio un tablet, a un monitor esterno, la sessione desktop si estende su entrambi i display. I due display funzionano quindi come un unico sistema continuo. Questa configurazione consente a finestre, contenuti e cursore di spostarsi liberamente tra i due display.

Figura 2. Tablet collegato a un monitor esterno, che estende la sessione desktop su entrambi i display.

Per supportare efficacemente i display connessi, è necessario prestare attenzione a diversi aspetti della progettazione e dell'implementazione dell'app. Le seguenti best practice garantiscono un'esperienza utente fluida e produttiva.

Gestire le modifiche dinamiche del display

Molte app vengono create partendo dal presupposto che l'oggetto Display e le sue caratteristiche non cambieranno durante il ciclo di vita dell'app. Tuttavia, quando un utente collega o scollega un monitor esterno o addirittura sposta una finestra dell'app tra i display, l'oggetto Display sottostante associato al contesto o alla finestra dell'app può cambiare. Le proprietà del display, come dimensioni, risoluzione, frequenza di aggiornamento, supporto HDR e densità, possono essere tutte diverse. Ad esempio, se imposti come hardcoded i valori in base allo schermo dello smartphone, è probabile che i layout non funzionino su un display esterno.

Anche i display esterni possono avere densità di pixel molto diverse. Devi assicurarti che l'app risponda correttamente alle modifiche della densità. Ciò comporta l'utilizzo di pixel indipendenti dalla densità (dp) per i layout, la fornitura di risorse specifiche per la densità e la garanzia che la UI venga ridimensionata in modo appropriato.

Se un'attività è in esecuzione su un display esterno quando questo viene scollegato, il sistema la sposta sul display principale. Il passaggio attiva modifiche alla configurazione, come le modifiche alle dimensioni e alla densità dello schermo, che possono causare la ricreazione dell'attività. L'app deve gestire la modifica della configurazione salvando e ripristinando lo stato della UI per evitare la perdita di dati o un'esperienza utente confusa.

Usa il contesto giusto

L'utilizzo del contesto giusto è fondamentale negli ambienti con più display. Quando accedi alle risorse, il contesto dell'attività (che viene visualizzato) è diverso dal contesto dell'applicazione (che non viene visualizzato).

Il contesto dell'attività contiene informazioni sul display ed è sempre adattato all'area di visualizzazione in cui viene visualizzata l'attività. In questo modo, puoi ottenere le informazioni corrette sulla densità di visualizzazione o sulle metriche della finestra della tua app. Utilizza sempre il contesto dell'attività (o un altro contesto basato sulla UI) per ottenere informazioni sulla finestra o sul display corrente. Ciò influisce anche su alcune API di sistema che utilizzano informazioni del contesto.

In Jetpack Compose, puoi accedere alle informazioni specifiche del display utilizzando gli oggetti CompositionLocal come LocalConfiguration.current e LocalDensity.current. Quando un'attività o una finestra si sposta tra i display, la configurazione del dispositivo cambia, attivando la ricomposizione con nuove metriche del display. Gli oggetti CompositionLocal consentono alla UI di adattarsi senza problemi.

Ottieni informazioni sul display

Puoi utilizzare la classe Display per ottenere informazioni come le dimensioni, la densità o i flag del display. Utilizza il servizio di sistema DisplayManager per ottenere i display disponibili. Per identificare i display esterni, filtra Display.DEFAULT_DISPLAY, che in genere è lo schermo integrato dello smartphone o del tablet:

val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val displays = displayManager.getDisplays()
// The default display is 0. External displays have other IDs.
val externalDisplays = displays.filter { it.displayId != Display.DEFAULT_DISPLAY }

Gestisci l'avvio e la configurazione delle attività

Con i display connessi, le app possono specificare su quale display devono essere eseguite quando vengono avviate o quando creano un'altra attività. Questo comportamento dipende dalla modalità di lancio dell'attività definita nel file manifest e dai flag e dalle opzioni dell'intent impostati dall'entità che lancia l'attività.

Quando un'attività viene spostata su un display secondario, la tua app può subire un aggiornamento del contesto, un ridimensionamento della finestra e modifiche alla configurazione e alle risorse. Se l'attività gestisce la modifica della configurazione, riceve una notifica in onConfigurationChanged(). In caso contrario, l'attività viene rilanciata.

Se la modalità di lancio selezionata per un'attività consente più istanze, il lancio su uno schermo secondario può creare una nuova istanza dell'attività. Entrambe le attività vengono riprese contemporaneamente, il che può essere utile per determinati scenari di multitasking.

Puoi avviare un'attività su un display specifico utilizzando ActivityOptions. Tieni presente che launchDisplayId richiede Android 8 (livello API 26) o versioni successive.

// Get DisplayManager and find the first external display.
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val externalDisplayId = displayManager.displays
    .firstOrNull { it.displayId != Display.DEFAULT_DISPLAY }
    ?.displayId

// If an external display is found, launch the activity on it.
if (externalDisplayId != null) {
    val intent = Intent(this, MySecondaryActivity::class.java)
    val options = ActivityOptions.makeBasic()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        options.launchDisplayId = externalDisplayId
    }
    startActivity(intent, options.toBundle())
} else {
    // Optionally, handle the case where no external display is connected.
}

Evita le liste consentite dei dispositivi

A volte le app limitano l'UI e le funzionalità per schermi di grandi dimensioni a dispositivi selezionati tramite una lista consentita o controllando BUILD.MODEL e le dimensioni del display integrato. Questo approccio non è efficace per i display connessi perché praticamente qualsiasi dispositivo può essere collegato a uno schermo di grandi dimensioni e il modello del dispositivo non cambia quando viene collegato un display esterno.

Anziché utilizzare le liste consentite o controllare BUILD.MODEL e le dimensioni del display integrate, controlla le metriche della finestra o le funzionalità del dispositivo in fase di runtime per prendere decisioni relative alla UI. Utilizza le API Jetpack WindowManager o le classi di dimensioni della finestra per creare layout adattabili e reattivi per schermi di varie dimensioni e densità.

Supporto delle periferiche esterne

Quando gli utenti si connettono a un display esterno, spesso creano un ambiente più simile a quello di un computer desktop. Spesso questo comporta l'utilizzo di tastiere, mouse, trackpad, webcam, microfoni e altoparlanti esterni. Devi assicurarti che la tua app funzioni perfettamente con queste periferiche. Ciò include la gestione delle scorciatoie da tastiera, la gestione delle interazioni con il puntatore del mouse, il supporto corretto di fotocamere o microfoni esterni e il rispetto del routing dell'output audio. Per maggiori dettagli, consulta Compatibilità degli input su schermi di grandi dimensioni.

Migliora la produttività degli utenti

I display connessi offrono un'opportunità significativa per migliorare la produttività degli utenti. Ora hai gli strumenti per creare app mobile che possono offrire esperienze paragonabili alle applicazioni desktop. Valuta la possibilità di implementare le seguenti funzionalità per aumentare la produttività degli utenti:

  • Consenti agli utenti di aprire più istanze della stessa app. Questa funzionalità è fondamentale per attività come il confronto di documenti, la gestione di conversazioni diverse o la visualizzazione di più file contemporaneamente.
  • Consenti agli utenti di condividere informazioni aggiuntive all'interno e all'esterno della tua app con il trascinamento.
  • Aiuta gli utenti a mantenere il loro flusso di lavoro durante le modifiche alla configurazione implementando un solido sistema di gestione dello stato.

Seguendo queste linee guida e utilizzando gli esempi di codice forniti, puoi creare app che si adattano perfettamente ai display connessi, offrendo agli utenti un'esperienza più ricca e produttiva.