Introduzione

In questo tutorial costruiremo un'app per iOS, Android e Web che ti permetterà di condividere le foto. Utilizzeremo il framework Expo, una piattaforma open source per la creazione di app native universali per Android, iOS e Web con JavaScript e React.

Per maggiori informazioni sul framework Expo leggere la seguente guida:

Prerequisiti

Per proseguire con questo tutorial si presume che sia stata installata l'interfaccia da riga di comando di Expo e l'app client di Expo.

Inizializzare una nuova App

All'interno della tua directory preferita per l'archiviazione dei tuoi progetti software, esegui expo init ImageShare e seleziona blank per creare un nuovo progetto per la nostra app che chiameremo "Image Share".

expo init ImageShare

Entrare alla directory del progetto con il comando cd ed esegui expo start:

cd ImageShare
expo start

Aprire il progetto sul dispositivo e aprire il codice nell'editor di codice desiderato.

In caso di problemi, fare riferimento all tutorial Come creare un App React con Expo Cli su Linux.

Modificare il testo

Cambiamo il testo che vediamo al centro dello schermo del nostro smartphone "Open up App.js to start working on your app!". Cambia il codice all'interno del tag <Text> in questo modo:

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Per condivedere una foto premi il tasto sotto!</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Aggiungere stile

Il nostro testo è in bianco e nero. Vediamo di seguito come modificare lo style del testo, in questo caso il colore. Aumenteremo anche la dimensione del carattere per semplificare la lettura.

Aggiungiamo lo style al tag <Text>:

..
<Text style={{color: '#888', fontSize: 18}}> 
   Per condivedere una foto premi il tasto sotto!
</Text>
..

Quindi modifica il codice in questo modo:

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text style={{color: '#888', fontSize: 18}}> 
 		Per condivedere una foto premi il tasto sotto!
      </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Nel paragrafo successivo vedremo come aggiungere un immagine.

Aggiungere un'immagine

Aggiungi un immagine qualsiasi nella directory assets all'interno del tuo progetto e chiamala logo.png.

Una "assets" è qualsiasi file utilizzato dal progetto che non sia un codice. Immagini, video, suoni e caratteri sono tutti considerati assets.

Visualizzare l'immagine nell'app

Abbiamo visualizzato il testo utilizzando il componente di React Native Text e possiamo visualizzare l'immagine utilizzando il componente Image.

Quindi aggiungere e modificare le seguenti righe in questo modo:

..
import { Image,  StyleSheet, Text, View } from 'react-native';
import logo from './assets/logo.png'; 
..
<Image source={logo} style={{ width: 305, height: 159 }} />
..

Il risultato sarà il seguente:

import React from 'react';
import { Image,  StyleSheet, Text, View } from 'react-native';
import logo from './assets/logo.png'; 

export default function App() {
  return (
    <View style={styles.container}>
      <Image source={logo} style={{ width: 305, height: 159 }} /> 

      <Text style={{color: '#888', fontSize: 18}}> 
        Per condivedere una foto premi il tasto sotto!
      </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
L'unità di misura di larghezza e altezza è il pixel. Se la risoluzione dello schermo è 640x480, un'immagine 320x240 sarà la metà della larghezza e dell'altezza. Sul web, React Native's width: 305 viene tradotto direttamente in 305px.

Caricare le immagini da un URL

A volte vorrai caricare immagini dal Web piuttosto che dalla directory del tuo progetto. Possiamo sostituire il source logo dell'immagine con il seguente formato { uri: 'http://path-to-your-image' }.

Quindi:

..
 <Image source={{ uri: "https://i.imgur.com/PUltcct.png" }} style={{ width: 305, height: 159 }} />
..

Il risultato sarà il seguente:

import React from 'react';
import { Image, StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Image source={{ uri: "https://i.imgur.com/PUltcct.png" }} style={{ width: 305, height: 159 }} />
    
      <Text style={{color: '#888', fontSize: 18}}> 
        Per condivedere una foto premi il tasto sotto!
      </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Ottimizzare il codice

Ottimizzare il codice è sempre consigliato, per la performance dell'app, per te stesso e per chi potrebbe leggere il tuo codice. Spostiamo lo stile dei tag in modo che il nostro codice sia più facile da leggere:

import React from 'react';
import { Image, StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Image source={{ uri: "https://i.imgur.com/PUltcct.png" }} style={styles.logo} />

      <Text style={styles.instructions} >
        Per condivedere una foto premi il tasto sotto!
      </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  logo: {
    width: 305,
    height: 159,
    marginBottom: 10,
  },
  instructions: {
    color: '#888',
    fontSize: 18,
    marginHorizontal: 15,
  }, 
});

Potresti notare che abbiamo anche aggiunto alcuni nuovi stili qui per rendere le cose un più chiare. Abbiamo usato marginBottom nello style del logo per distanziare il logo e il testo e abbiamo aggiunto marginHorizontal per dare al testo una spaziatura attorno ai bordi dello schermo.

Creare un pulsante

Creeremo il nostro pulsante personalizzato usando il componente TouchableOpacity e alcuni stili Text all'interno di esso.

Aggiungere TouchableOpacity nell'importazione dei componenti:

..
 import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
..

Quindi utilizzarlo in questo modo:

..
       <TouchableOpacity
        onPress={() => alert('Hello, world!')}
        style={{ backgroundColor: 'blue' }}>
        <Text style={{ fontSize: 20, color: '#fff' }}>Pick a photo</Text>
      </TouchableOpacity>
..

Il risultato finale della nostra app sarà il seguente:

import React from 'react';
import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Image source={{ uri: "https://i.imgur.com/PUltcct.png" }} style={styles.logo} />

      <Text style={styles.instructions} >
        Per condivedere una foto premi il tasto sotto!
      </Text>

      <TouchableOpacity
        onPress={() => alert('Hello, world!')}
        style={{ backgroundColor: 'blue' }}>
        <Text style={{ fontSize: 20, color: '#fff' }}>Pick a photo</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  logo: {
    width: 305,
    height: 159,
    marginBottom: 20,
  },
  instructions: {
    color: '#888',
    fontSize: 18,
    marginHorizontal: 15,
    marginBottom: 10,
  },
});

Notare che quando si preme il pulsante, questo cambia colore perché il nostro sfondo è bianco e il pulsante diventa leggermente traslucido. Quando rilasci, vedrai una finestra di avviso. Puoi mostrare questa finestra di dialogo in qualsiasi momento nelle tue app chiamando la funzione alert.

Modificare il pulsante

Il pulsante deve essere abbastanza grande da essere facile da premere per le persone con diversi livelli di destrezza e un assortimento di dimensioni delle dita. Possiamo ingrandire il nostro pulsante aggiungendone alcuni padding al nostro componente TouchableOpacity. Abbiamo già visto width, height e vari margin, padding è nella stessa famiglia di questi stili. Il sistema di layout si chiama flexbox, ma per ora non preoccuparti di questo, in questo tutorial ti diremo esattamente quali stili usare e potrai conoscere il flexbox in seguito.

Modificare il componente TouchableOpacity in questo modo:

..
<TouchableOpacity onPress={() => alert('Hello, world!')} style={styles.button}>
  <Text style={styles.buttonText}>Pick a photo</Text>
</TouchableOpacity>
..

Aggiungere il seguente style verso fine del file:

..
  button: {
    backgroundColor: "blue",
    padding: 20,
    borderRadius: 5,
  },
  buttonText: {
    fontSize: 20,
    color: '#fff',
  }, 
..

Questo è il risultato:

import React from 'react';
import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
       <Image source={{ uri: "https://i.imgur.com/PUltcct.png" }} style={styles.logo} />
      <Text style={styles.instructions} >
        Per condivedere una foto premi il tasto sotto!
      </Text>

      <TouchableOpacity onPress={() => alert('Hello, world!')} style={styles.button}>
        <Text style={styles.buttonText}>Pick a photo</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  logo: {
    width: 305,
    height: 159,
    marginBottom: 20,
  },
  instructions: {
    color: '#888',
    fontSize: 18,
    marginHorizontal: 15,
    marginBottom: 10,
  },
  button: {
    backgroundColor: "blue",
    padding: 20,
    borderRadius: 5,
  },
  buttonText: {
    fontSize: 20,
    color: '#fff',
  }, 
});

Scegliere un'immagine

Finora abbiamo utilizzato il codice di React e React Native nella nostra app. React Native non ci fornisce un selettore di immagini. Per questo, possiamo usare una libreria Expo chiamata expo-image-picker.

expo-image-picker fornisce l'accesso all'interfaccia utente del sistema per selezionare immagini e video dalla libreria del telefono o scattare una foto con la fotocamera.

Installare expo-image-picker

Per utilizzare expo-image-picker nel nostro progetto, dobbiamo prima installarlo. Nella directory del progetto, esegui expo install expo-image-picker. Questo dirà a npm (o thread) di installare una versione della libreria expo-image-picker compatibile con il tuo progetto:

expo install expo-image-picker

Scegliere un'immagine

Abbiamo installato la libreria expo-image-picker nel nostro progetto. Vediamo come utilizzarla. Aggiungere le seguenti righe di codice:

..
import * as ImagePicker from 'expo-image-picker';

..

  let openImagePickerAsync = async () => {
    let permissionResult = await ImagePicker.requestCameraRollPermissionsAsync();

    if (permissionResult.granted === false) {
      alert("Permission to access camera roll is required!");
      return;
    }

    let pickerResult = await ImagePicker.launchImageLibraryAsync();
    console.log(pickerResult);
  }
  
..

Bisogna modificare anche il componente TouchableOpacity:

..
<TouchableOpacity onPress={openImagePickerAsync} style={styles.button}>
   <Text style={styles.buttonText}>Pick a photo</Text>
</TouchableOpacity>
..

Questo è il risultato finale:

import React from 'react';
import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import * as ImagePicker from 'expo-image-picker';

export default function App() {
  let openImagePickerAsync = async () => {
    let permissionResult = await ImagePicker.requestCameraRollPermissionsAsync();

    if (permissionResult.granted === false) {
      alert('È richiesta l\'autorizzazione ad accedere al rullino fotografico!');
      return;
    }

    let pickerResult = await ImagePicker.launchImageLibraryAsync();
    console.log(pickerResult);
  };

  return (
    <View style={styles.container}>
       <Image source={{ uri: "https://i.imgur.com/PUltcct.png" }} style={styles.logo} />
      <Text style={styles.instructions}>
        Per condivedere una foto premi il tasto sotto!
      </Text>

      <TouchableOpacity onPress={openImagePickerAsync} style={styles.button}>
        <Text style={styles.buttonText}>Pick a photo</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  logo: {
    width: 305,
    height: 159,
    marginBottom: 20,
  },
  instructions: {
    color: '#888',
    fontSize: 18,
    marginHorizontal: 15,
    marginBottom: 10,
  },
  button: {
    backgroundColor: 'blue',
    padding: 20,
    borderRadius: 5,
  },
  buttonText: {
    fontSize: 20,
    color: '#fff',
  },
});

Utilizzare l'immagine selezionata

Ora prenderemo i dati che otteniamo dal selettore di immagini e li useremo per mostrare l'immagine selezionata nell'app.

Aggiungere e modificare le seguenti righe di codice:

..

const [selectedImage, setSelectedImage] = React.useState(null);

..

    if (pickerResult.cancelled === true) {
      return;
    }

    setSelectedImage({ localUri: pickerResult.uri });
  };

  if (selectedImage !== null) {
    return (
      <View style={styles.container}>
        <Image
          source={{ uri: selectedImage.localUri }}
          style={styles.thumbnail}
        />
      </View>
    );
  }
  
..

Il risultato finale è il seguente:

import React from 'react';
import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import * as ImagePicker from 'expo-image-picker';

export default function App() {
  let [selectedImage, setSelectedImage] = React.useState(null);

  let openImagePickerAsync = async () => {
    let permissionResult = await ImagePicker.requestCameraRollPermissionsAsync();

    if (permissionResult.granted === false) {
      alert('È richiesta l\'autorizzazione ad accedere al rullino fotografico!');
      return;
    }

    let pickerResult = await ImagePicker.launchImageLibraryAsync();
    if (pickerResult.cancelled === true) {
      return;
    }

    setSelectedImage({ localUri: pickerResult.uri });
  };

  if (selectedImage !== null) {
    return (
      <View style={styles.container}>
        <Image source={{ uri: selectedImage.localUri }} style={styles.thumbnail} />
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <Image source={{ uri: 'https://i.imgur.com/PUltcct.png' }} style={styles.logo} />
      <Text style={styles.instructions}>
        Per condivedere una foto premi il tasto sotto!
      </Text>

      <TouchableOpacity onPress={openImagePickerAsync} style={styles.button}>
        <Text style={styles.buttonText}>Pick a photo</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  logo: {
    width: 305,
    height: 159,
    marginBottom: 20,
  },
  instructions: {
    color: '#888',
    fontSize: 18,
    marginHorizontal: 15,
    marginBottom: 10,
  },
  button: {
    backgroundColor: 'blue',
    padding: 20,
    borderRadius: 5,
  },
  buttonText: {
    fontSize: 20,
    color: '#fff',
  },
  thumbnail: {
    width: 300,
    height: 300,
    resizeMode: 'stretch',
  },
});

Potresti aspettarti che, dato che abbiamo dato alla nostra immagine uguale larghezza e altezza, sarebbe un quadrato, ma invece è rettangolare. Ciò è dovuto a resizeMode una proprietà di stile immagine che ci consente di controllare il modo in cui l'immagine viene ridimensionata per adattarsi alle dimensioni indicate. Provare a passare da contain a stretch o cover per vedere altri comportamenti. Abbiamo fatto grandi progressi!

Successivamente, vediamo come condividere l'immagine.

Condividere l'immagine

Simile a expo-image-picker, la funzionalità che dobbiamo utilizzare è disponibile in una libreria di Expo chiamata expo-sharing.

Installare di expo-sharing

Puoi installare expo-sharing allo stesso modo in cui hai installato expo-image-picker, da terminle digita il seguente comando nella directory del progetto:

expo install expo-sharing

Utilizzare la condivisione Expo per condividere un'immagine

Aggiungere o modificare le seguenti righe di codice:

..
import * as Sharing from 'expo-sharing';

..

  let openShareDialogAsync = async () => {
    if (!(await Sharing.isAvailableAsync())) {
      alert(`Sharing isn't available on your platform`);
      return;
    }

    Sharing.shareAsync(selectedImage.localUri);
  };

..

 <TouchableOpacity onPress={openShareDialogAsync} style={styles.button}>
     <Text style={styles.buttonText}>Share this photo</Text>
 </TouchableOpacity>

Il risultato dovrebbe essere simile al seguente:

import React from 'react';
import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import * as Sharing from 'expo-sharing';

export default function App() {
  let [selectedImage, setSelectedImage] = React.useState(null);

  let openImagePickerAsync = async () => {
    let permissionResult = await ImagePicker.requestCameraRollPermissionsAsync();

    if (permissionResult.granted === false) {
      alert('È richiesta l\'autorizzazione ad accedere al rullino fotografico!');
      return;
    }

    let pickerResult = await ImagePicker.launchImageLibraryAsync();
    if (pickerResult.cancelled === true) {
      return;
    }

    setSelectedImage({ localUri: pickerResult.uri });
  };

  let openShareDialogAsync = async () => {
  if (!(await Sharing.isAvailableAsync())) {
    alert(`Sharing isn't available on your platform`);
    return;
  }

  Sharing.shareAsync(selectedImage.localUri);
};

  if (selectedImage !== null) {
    return (
      <View style={styles.container}>
        <Image source={{ uri: selectedImage.localUri }} style={styles.thumbnail} />

        <TouchableOpacity onPress={openShareDialogAsync} style={styles.button}>
          <Text style={styles.buttonText}>Share this photo</Text>
        </TouchableOpacity>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <Image source={{ uri: 'https://i.imgur.com/PUltcct.png' }} style={styles.logo} />
      <Text style={styles.instructions}>
        Per condivedere una foto premi il tasto sotto!
      </Text>

      <TouchableOpacity onPress={openImagePickerAsync} style={styles.button}>
        <Text style={styles.buttonText}>Pick a photo</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  logo: {
    width: 305,
    height: 159,
    marginBottom: 20,
  },
  instructions: {
    color: '#888',
    fontSize: 18,
    marginHorizontal: 15,
    marginBottom: 10,
  },
  button: {
    backgroundColor: 'blue',
    padding: 20,
    borderRadius: 5,
  },
  buttonText: {
    fontSize: 20,
    color: '#fff',
  },
  thumbnail: {
    width: 300,
    height: 300,
    resizeMode: 'stretch',
  },
});

Adesso è possibile condividere un immagine selezionata con il picker.

expo-sharing non funziona su Chrome

La condivisione non funziona sul browser Chrome desktop poichè non implementa ancora l'API di condivisione Web. Non è sempre possibile tradurre dalla lingua di Expo alla piattaforma con cui stai lavorando. In altre parole, se la piattaforma non implementa una funzione, Expo non può dirle di invocare tale funzione. In alcuni casi Expo può tentare di eseguire il polyfill della funzione per te, ma questo non è sempre possibile. Il richiamo della finestra di dialogo di condivisione integrata del tuo sistema operativo per condividere contenuti con altre applicazioni deve essere implementato dalla piattaforma stessa, in questo caso Chrome.

Gestione differenze delle piattaforme

Vogliamo scrivere codice per eseguire il nostro compito una sola volta e farlo funzionare allo stesso modo su ogni piattaforma. Anche sul Web, dove questo è un obiettivo di progettazione esplicito, è spesso necessario considerare le differenze tra i browser Web. Gli strumenti di Expo cercano di ovviare a queste differenze tra iOS, Android, Web (e diversi browser Web) per noi, ma non è sempre possibile. Esistono due importanti differenze tra il funzionamento delle API di condivisione iOS e Android e il funzionamento dell'API di condivisione Web.

  1. Non è sempre disponibile sul web.
  2. Non possiamo condividere URI di file locali sul Web.
In realtà è tecnicamente possibile nelle ultime versioni di Chrome per Android condividere file, ma è un metodo nuovo e non ancora supportato da expo-sharing, quindi per ora lo ignoreremo.

Una soluzione alternativa per la condivisione sul Web

Lavoreremo intorno al supporto spotty per l'API di condivisione Web e alla mancanza di supporto per la condivisione di file dal nostro dispositivo caricando il file su alcuni servizi Web e quindi consentendo agli utenti di copiare l'URL. Esegui expo install anonymous-files per installare una libreria per gestire il caricamento del file per noi.

Quindi eseguire questo comando nella directory principale del progetto:

expo install anonymous-files

Apporta queste modifiche alla tua app:

..

import { Image, Platform, StyleSheet, Text, TouchableOpacity, View } from 'react-native';

..

import uploadToAnonymousFilesAsync from 'anonymous-files'; 

..

    if (Platform.OS === 'web') {
      let remoteUri = await uploadToAnonymousFilesAsync(pickerResult.uri);
      setSelectedImage({ localUri: pickerResult.uri, remoteUri });
    } else {
      setSelectedImage({ localUri: pickerResult.uri, remoteUri: null });
    }

..

alert(`The image is available for sharing at: ${selectedImage.remoteUri}`);

..

Quindi il risultato finale sarà il seguente:

import React from 'react';
import { Image, Platform, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import * as Sharing from 'expo-sharing';
import uploadToAnonymousFilesAsync from 'anonymous-files';

export default function App() {
  let [selectedImage, setSelectedImage] = React.useState(null);

  let openImagePickerAsync = async () => {
    let permissionResult = await ImagePicker.requestCameraRollPermissionsAsync();

    if (permissionResult.granted === false) {
      alert('È richiesta l\'autorizzazione ad accedere al rullino fotografico!');
      return;
    }

    let pickerResult = await ImagePicker.launchImageLibraryAsync();
    if (pickerResult.cancelled === true) {
      return;
    }

    if (Platform.OS === 'web') {
      let remoteUri = await uploadToAnonymousFilesAsync(pickerResult.uri);
      setSelectedImage({ localUri: pickerResult.uri, remoteUri });
    } else {
      setSelectedImage({ localUri: pickerResult.uri, remoteUri: null });
    }
  };

  let openShareDialogAsync = async () => {
    if (!(await Sharing.isAvailableAsync())) {
      alert(`Sharing isn't available on your platform`);
      return;
    }

    Sharing.shareAsync(selectedImage.remoteUri || selectedImage.localUri);
  };

  if (selectedImage !== null) {
    return (
      <View style={styles.container}>
        <Image source={{ uri: selectedImage.localUri }} style={styles.thumbnail} />
        <TouchableOpacity onPress={openShareDialogAsync} style={styles.button}>
          <Text style={styles.buttonText}>Share this photo</Text>
        </TouchableOpacity>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <Image source={{ uri: 'https://i.imgur.com/PUltcct.png' }} style={styles.logo} />
      <Text style={styles.instructions}>
          Per condivedere una foto premi il tasto sotto!
      </Text>

      <TouchableOpacity onPress={openImagePickerAsync} style={styles.button}>
        <Text style={styles.buttonText}>Pick a photo</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  logo: {
    width: 305,
    height: 159,
    marginBottom: 20,
  },
  instructions: {
    color: '#888',
    fontSize: 18,
    marginHorizontal: 15,
    marginBottom: 10,
  },
  button: {
    backgroundColor: 'blue',
    padding: 20,
    borderRadius: 5,
  },
  buttonText: {
    fontSize: 20,
    color: '#fff',
  },
  thumbnail: {
    width: 300,
    height: 300,
    resizeMode: 'contain',
  },
});

Avanti il ​​prossimo

La nostra app fa tutto ciò che ci prefiggiamo di fare, quindi è tempo di spostare la nostra attenzione verso l'estetica puramente. Nel prossimo passaggio di questo tutorial personalizzeremo la nostra icona dell'app e la schermata iniziale.

Configurazione di una schermata iniziale e di un'icona dell'app

Prima di poter considerare la nostra app davvero completa, dobbiamo aggiungere una schermata iniziale e un'icona dell'app. Una schermata iniziale è ciò che gli utenti vedono all'avvio dell'app, prima che sia caricata. L'icona sarà visibile nella schermata principale dell'utente quando l'app è installata o all'interno dell'app Expo durante lo sviluppo.

Schermata iniziale

Prendiamo un immagine per la schermata iniziale di 1242px di larghezza per 2436px di altezza (ulteriori informazioni nella guida alla schermata iniziale).

Salva questa immagine nella directory assets all'interno del tuo progetto e chiamala splash.png (sostituisci il file esistente). Ricarica la tua app e dovresti vedere l'immagine che hai scelto prima dell'avvio dell'app.

Modificare il tempo di scomparsa della SplashScreen

Possiamo fare in modo che la schermata iniziale resti più a lungo controllando manualmente quando è nascosta, piuttosto che per impostazione predefinita nasconderla automaticamente non appena l'app è pronta. Nel codice seguente, ritardiamo a nascondere la schermata iniziale per cinque secondi.

import { SplashScreen } from 'expo';

SplashScreen.preventAutoHide();
setTimeout(SplashScreen.hide, 5000);

È stato abbastanza facile ma non abbiamo ancora finito qui. Nota che c'è una barra bianca nella parte superiore del nostro schermo (potresti non essere in grado di vederlo sul tuo dispositivo a seconda della sua risoluzione). Per ovviare a questo, dobbiamo impostare il backgroundColor della schermata iniziale. Il colore di sfondo viene applicato a qualsiasi area dello schermo non coperta dalla nostra immagine iniziale.

Configurazione del colore di sfondo della schermata iniziale

Finora abbiamo apportato tutte le nostre modifiche a App.js. Ci sono alcuni aspetti della nostra app che vogliamo configurare senza eseguire il codice JavaScipt della nostra app e la schermata iniziale è una di queste (è visibile prima che l'app abbia avuto la possibilità di caricarsi e viene nascosta quando l'app è pronta per l'uso, se non diversamente specificato). Aprire il file app.json dalla directory del progetto nell'editor di codice e apportare la seguente modifica al parametro backgroundColor nella sezione splash:

"splash": {
  "image": "./assets/splash.png",
  "resizeMode": "contain",
  "backgroundColor": "#000000"
},

Icona dell'app

Prendiamo adesso un immagine per l'icona dell'app 1024px larghezza e 1024px altezza.

Salva questa immagine nella directory assets all'interno del tuo progetto e chiamala icon.png (sostituisci il file esistente). Ricarica l'app.

Vedrai l'icona in vari punti del client Expo e quando esegui un'app standalone per l'invio ai negozi, verrà utilizzata come icona nelle schermate home degli utenti.

Conclusione

Abbiamo visto come creare un'app semplice ma significativa che gira su iOS, Android e Web dalla stessa base di codice.