WebView con pixel perfetti

Data di pubblicazione: 28 febbraio 2014

Esistono diverse opzioni che puoi utilizzare per creare l'interfaccia perfetta per la tua WebView.

Impostare il meta tag viewport

Il meta tag viewport è uno dei tag più importanti da aggiungere alla tua app web. Senza questo tag, WebView potrebbe comportarsi come se il tuo sito fosse progettato per browser di computer. In questo modo, alla pagina web viene assegnata una larghezza maggiore (in genere 980 pixel) e viene ridimensionata in base alla larghezza di WebView. Nella maggior parte dei casi, si ottiene una versione di panoramica molto piccola della pagina che richiede all'utente di eseguire la panoramica e lo zoom per poter leggere i contenuti.

Se vuoi che la larghezza del tuo sito corrisponda al 100% della larghezza di WebView, imposta il meta tag viewport:

<meta name="viewport" content="width=device-width, initial-scale=1">

Imposta la larghezza sul valore speciale larghezza-dispositivo per avere un maggiore controllo sul layout della pagina.

Per impostazione predefinita, WebView imposta l'area visibile su device-width, anziché su un'area visibile per computer. Tuttavia, per un comportamento affidabile e controllato, è buona prassi includere il meta tag viewport.

Visualizzare i siti desktop

In alcuni casi, potrebbe essere necessario mostrare contenuti non progettati per i dispositivi mobili. Ad esempio, potresti mostrare contenuti che non controlli. In questo caso, puoi forzare WebView a utilizzare un'area visibile delle dimensioni di un computer:

Se questi metodi non sono impostati e non viene specificato alcun viewport, WebView tenta di impostare la larghezza del viewport in base alle dimensioni dei contenuti.

Inoltre, ti consigliamo di utilizzare l'algoritmo di layout TEXT_AUTOSIZING, che aumenta le dimensioni dei caratteri per renderli più leggibili su un dispositivo mobile. Vedi setLayoutAlgorithm.

Utilizza il responsive design

Il responsive design è un approccio alla progettazione di un'interfaccia che cambia in base alle dimensioni dello schermo.

Esistono diversi modi per implementare il design responsive. Una delle più comuni è la query @media, che applica il CSS agli elementi in base alle caratteristiche di un dispositivo.

Ad esempio, supponiamo che tu voglia passare da un layout verticale a uno orizzontale in base all'orientamento. Imposta le proprietà CSS in modo che il formato predefinito sia Ritratto:

.page-container {
    display: -webkit-box;
    display: flex;

    -webkit-box-orient: vertical;
    flex-direction: column;

    padding: 20px;
    box-sizing: border-box;
}

Per passare a un layout orizzontale, imposta la proprietà flex-direction in base all'orientamento:

@media screen and (orientation: landscape) {
  .page-container.notification-opened {
    -webkit-box-orient: horizontal;
    flex-direction: row;
  }

  .page-container.notification-opened > .notification-arrow {
    margin-right: 20px;
  }
}

Puoi anche modificare il layout in base alla larghezza dello schermo.

Ad esempio, puoi modificare la larghezza del pulsante dal 100% a un valore inferiore man mano che le dimensioni dello schermo fisico aumentano.

button {
  display: block;
  width: 100%;
  ...
}

@media screen and (min-width: 500px) {
  button {
    width: 60%;
  }
}

@media screen and (min-width: 750px) {
  button {
    width: 40%;
    max-width: 400px;
  }
}

Si tratta di modifiche minori, ma a seconda dell'interfaccia utente, le query sui media possono aiutarti a apportare modifiche molto più sostanziali all'aspetto della tua applicazione, mantenendo lo stesso codice HTML.

Immagini nitide

La varietà di dimensioni e densità degli schermi presenta anche delle sfide per le immagini. Le immagini più piccole richiedono meno memoria e vengono caricate più velocemente, ma si sfocano se le ridimensioni.

Ecco alcuni suggerimenti per assicurarti che le tue immagini siano nitide su qualsiasi schermo:

  • Utilizza CSS per effetti scalabili.
  • Utilizza immagini vettoriali.
  • Fornisci foto ad alta risoluzione.

Utilizzare CSS per effetti scalabili

Utilizza CSS anziché immagini, se possibile. È possibile che alcune combinazioni di proprietà CSS possano essere costose da eseguire. Testa sempre le combinazioni specifiche che utilizzi.

Scopri di più su First Contentful Paint (FCP), che misura il tempo trascorso tra la prima visita dell'utente alla pagina e la visualizzazione di qualsiasi parte dei contenuti della pagina sullo schermo. Per "contenuti" si intendono testo, immagini (incluse le immagini di sfondo), elementi <svg> ed elementi <svg> non bianchi.<canvas>

Utilizza grafica vettoriale

Gli SVG (Scalable Vector Graphics) sono un ottimo modo per fornire un'immagine scalabile. Per le immagini adatte alla grafica vettoriale, SVG fornisce immagini di alta qualità con dimensioni dei file molto ridotte.

Fornire foto ad alta risoluzione

Utilizza una foto adatta a un dispositivo ad alto DPI e ridimensiona l'immagine utilizzando il CSS. In questo modo, l'immagine può essere visualizzata in alta qualità su tutti i dispositivi. Se utilizzi una compressione elevata (impostazione di bassa qualità) durante la generazione dell'immagine, potresti ottenere buoni risultati visivi con dimensioni del file ragionevoli.

Questo approccio presenta alcuni potenziali svantaggi: le immagini altamente compresse possono mostrare alcuni artefatti visivi, quindi devi fare esperimenti per determinare il livello di compressione che ritieni accettabile. Inoltre, il ridimensionamento dell'immagine in CSS può essere un'operazione costosa.

Se la compressione elevata non è adatta alle tue esigenze, prova il formato WebP, che offre un'immagine di alta qualità con dimensioni del file relativamente ridotte. Ricorda di fornire un'opzione di riserva per le versioni di Android in cui WebP non è supportato.

Controllo granulare

In molti casi, non puoi utilizzare una singola immagine per tutti i dispositivi. In questo caso, puoi selezionare immagini diverse in base alle dimensioni e alla densità dello schermo. Utilizza le query sui media per selezionare le immagini di sfondo in base alle dimensioni e alla densità dello schermo.

Puoi utilizzare JavaScript per controllare il caricamento delle immagini, ma questo aumenta la complessità.

Query sui media e densità dello schermo

Per selezionare un'immagine in base alla densità dello schermo, devi utilizzare le unità dpi o dppx nella query sui media. L'unità dpi indica i punti per pollice CSS e dppx indica i punti per pixel CSS.

Nella tabella seguente puoi vedere la relazione tra dpi e dppx.

Rapporto pixel del dispositivo Densità dello schermo generalizzata Punti per pollice CSS (dpi) Punti per pixel CSS (dppx)
1x MDPI 96dpi 1dppx
1,5x HDPI 144dpi 1,5dppx
2 XHDPI 192dpi 2dppx

I bucket di densità dello schermo generalizzati sono definiti da Android e vengono utilizzati in altri luoghi per esprimere la densità dello schermo (ad esempio, https://screensiz.es).

Immagini di sfondo

Puoi utilizzare le query sui media per assegnare immagini di sfondo agli elementi. Ad esempio, se hai un'immagine del logo di dimensioni 256 x 256 px su un dispositivo con un rapporto pixel di 1,0, puoi utilizzare le seguenti regole CSS:

.welcome-header > h1 {
  flex: 1;

  width: 100%;

  max-height: 256px;
  max-width: 256px;

  background-image: url('../images/html5_256x256.png');
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

Per sostituire questa immagine con una più grande sui dispositivi con un rapporto dispositivo di 1,5 (hdpi) e 2,0 (xhdpi), puoi aggiungere le seguenti regole:

@media screen and (min-resolution: 1.5dppx) {
  .welcome-header > h1{
    background-image: url('../images/html5_384x384.png');
  }
}

@media screen and (min-resolution: 2dppx) {
  .welcome-header > h1{
    background-image: url('../images/html5_512x512.png');
  }
}

Puoi quindi unire questa tecnica con altre query sui media, ad esempio min-width, che è utile per tenere conto di diversi fattori di forma.

@media screen and (min-resolution: 2dppx) {
  .welcome-header > h1{
    background-image: url('../images/html5_512x512.png');
  }
}

@media screen and (min-resolution: 2dppx) and (min-width: 1000px) {
  .welcome-header > h1{
    background-image: url('../images/html5_1024x1024.png');

    max-height: 512px;
    max-width: 512px;
  }
}

Potresti notare che max-height e max-width sono impostati su 512 px per la risoluzioneddpx2, con un'immagine di 1024 x 1024 px. Questo perché un "pixel" CSS prende effettivamente in considerazione il rapporto pixel del dispositivo (512 px * 2 = 1024 px).

Che ne dici di <img/>?

Al momento il web non ha una soluzione a questo problema. Esistono alcune proposte, ma non sono disponibili nei browser attuali o in WebView.

Nel frattempo, se generi il DOM in JavaScript, puoi creare più risorse immagine in una struttura di directory ben organizzata:

images/
  mdpi/
    imagename.png
  hdpi/
    imagename.png
  xhdpi/
    imagename.png

Quindi utilizza il rapporto tra pixel per provare a recuperare l'immagine più appropriata:

function getDensityDirectoryName() {
  if(!window.devicePixelRatio) {
    return 'mdpi';
  }

  if(window.devicePixelRatio > 1.5) {
    return 'xhdpi';
  } else if(window.devicePixelRatio > 1.0) {
    return 'hdpi';
  }

  return 'mdpi';
}

In alternativa, puoi modificare l'URL base della pagina per definire gli URL relativi per le immagini.

<!doctype html>
<html class="no-js">
<head>
  <script>
    function getDensityDirectoryName() {
      if(!window.devicePixelRatio) {
          return 'mdpi';
      }

      if(window.devicePixelRatio > 1.5) {
          return 'xhdpi';
      } else if(window.devicePixelRatio > 1.0) {
          return 'hdpi';
      }

      return 'mdpi';
    }

    var baseUrl =
        'file:///android_asset/www/img-js-diff/ratiores/'+getDensityDirectoryName()+'/';
    document.write('<base href="'+baseUrl+'">');
  </script>

    ...
</head>
<body>
    ...
</body>
</html>

Questo approccio blocca il caricamento della pagina e forza l'utilizzo di percorsi assoluti per tutte le risorse, come immagini, script e file CSS, poiché l'URL base rimanda a una directory specifica per la densità.