Caricare immagini e file in Flutter con image_picker e file_picker
GuideIntermedio35 min Flutter 3.x

Caricare immagini e file in Flutter con image_picker e file_picker

Selezione di immagini e file in Flutter

Molte applicazioni hanno bisogno di accedere a contenuti multimediali o documenti presenti sul dispositivo dell'utente: pensa a un avatar del profilo, all'allegato di un messaggio o al caricamento di un PDF.

In questo tutorial vedremo come usare due pacchetti molto diffusi:

  • image_picker per scegliere immagini dalla galleria o scattarle con la fotocamera;
  • file_picker per selezionare file di qualsiasi tipo (PDF, documenti, ecc.).

Affronteremo anche la configurazione dei permessi su Android e iOS e la gestione corretta degli stati (caricamento, errore, annullamento).

  1. 1

    Aggiungere le dipendenze

    Aggiungi i pacchetti image_picker e file_picker al tuo progetto.

    Puoi farlo da terminale con i comandi seguenti, oppure modificando manualmente il pubspec.yaml.

    flutter pub add image_picker
    flutter pub add file_picker

    Risultato atteso

    Le dipendenze compaiono nel file pubspec.yaml e `flutter pub get` viene eseguito senza errori.

  2. 2

    Configurare i permessi nativi

    Su iOS devi dichiarare gli usi della fotocamera e della libreria foto nel file ios/Runner/Info.plist, altrimenti l'app va in crash al primo accesso.

    Su Android image_picker (versioni recenti) e file_picker generalmente non richiedono permessi runtime aggiuntivi per la galleria, ma assicurati che compileSdkVersion sia aggiornato.

    <!-- ios/Runner/Info.plist -->
    <key>NSCameraUsageDescription</key>
    <string>L'app usa la fotocamera per scattare foto del profilo.</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>L'app accede alla galleria per selezionare le immagini.</string>

    Risultato atteso

    Le chiavi sono presenti nell'Info.plist; l'app non crasha quando apre fotocamera o galleria su iOS.

  3. 3

    Selezionare un'immagine dalla galleria

    Creiamo un metodo che usa ImagePicker per scegliere un'immagine. Il risultato è un XFile (può essere null se l'utente annulla).

    Manteniamo il file selezionato in una variabile di stato per poterlo mostrare.

    import 'dart:io';
    import 'package:flutter/material.dart';
    import 'package:image_picker/image_picker.dart';
    
    class MediaPage extends StatefulWidget {
      const MediaPage({super.key});
    
      @override
      State<MediaPage> createState() => _MediaPageState();
    }
    
    class _MediaPageState extends State<MediaPage> {
      final ImagePicker _picker = ImagePicker();
      File? _immagine;
    
      Future<void> _scegliDallaGalleria() async {
        final XFile? file = await _picker.pickImage(
          source: ImageSource.gallery,
          imageQuality: 80,
          maxWidth: 1080,
        );
        if (file != null) {
          setState(() => _immagine = File(file.path));
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return const Placeholder();
      }
    }

    Risultato atteso

    Chiamando `_scegliDallaGalleria` si apre la galleria e l'immagine scelta viene salvata in `_immagine`.

  4. 4

    Scattare una foto con la fotocamera

    Per scattare una foto basta cambiare il source in ImageSource.camera. Il flusso di gestione del risultato è identico a quello della galleria.

    È buona pratica gestire eventuali eccezioni (ad esempio se la fotocamera non è disponibile).

    Future<void> _scattaFoto() async {
      try {
        final XFile? file = await _picker.pickImage(
          source: ImageSource.camera,
          imageQuality: 80,
        );
        if (file != null) {
          setState(() => _immagine = File(file.path));
        }
      } catch (e) {
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('Errore fotocamera: $e')),
          );
        }
      }
    }

    Risultato atteso

    Premendo il pulsante si apre la fotocamera; la foto scattata viene mostrata o un messaggio di errore appare in caso di problemi.

  5. 5

    Selezionare un file con file_picker

    Per file generici (PDF, documenti, ecc.) usiamo FilePicker. Possiamo limitare i tipi accettati con FileType.custom e l'elenco delle estensioni.

    Il risultato è un FilePickerResult con la lista dei file selezionati.

    import 'package:file_picker/file_picker.dart';
    
    String? _nomeFile;
    
    Future<void> _scegliFile() async {
      final FilePickerResult? result = await FilePicker.platform.pickFiles(
        type: FileType.custom,
        allowedExtensions: ['pdf', 'doc', 'docx'],
      );
    
      if (result != null && result.files.isNotEmpty) {
        final file = result.files.single;
        setState(() => _nomeFile = file.name);
        // file.path -> percorso, file.size -> dimensione in byte
      } else {
        // L'utente ha annullato la selezione
      }
    }

    Risultato atteso

    Si apre il selettore di file di sistema filtrato sulle estensioni indicate; il nome del file scelto viene salvato in `_nomeFile`.

  6. 6

    Costruire l'interfaccia completa

    Mettiamo insieme tutto in un'unica schermata con i pulsanti per le tre azioni e l'anteprima dell'immagine o del nome del file selezionato.

    Usiamo un'anteprima condizionale: se è presente un'immagine la mostriamo, altrimenti mostriamo un placeholder.

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(title: const Text('Upload media')),
        body: Padding(
          padding: const EdgeInsets.all(16),
          child: Column(
            children: [
              if (_immagine != null)
                Image.file(_immagine!, height: 200, fit: BoxFit.cover)
              else
                Container(
                  height: 200,
                  alignment: Alignment.center,
                  color: Colors.grey.shade200,
                  child: const Text('Nessuna immagine selezionata'),
                ),
              const SizedBox(height: 16),
              if (_nomeFile != null)
                Text('File: $_nomeFile'),
              const SizedBox(height: 16),
              Wrap(
                spacing: 12,
                children: [
                  ElevatedButton.icon(
                    onPressed: _scegliDallaGalleria,
                    icon: const Icon(Icons.photo_library),
                    label: const Text('Galleria'),
                  ),
                  ElevatedButton.icon(
                    onPressed: _scattaFoto,
                    icon: const Icon(Icons.camera_alt),
                    label: const Text('Fotocamera'),
                  ),
                  ElevatedButton.icon(
                    onPressed: _scegliFile,
                    icon: const Icon(Icons.attach_file),
                    label: const Text('File'),
                  ),
                ],
              ),
            ],
          ),
        ),
      );
    }

    Risultato atteso

    L'app mostra tre pulsanti funzionanti e visualizza l'anteprima dell'immagine o il nome del file selezionato.

CondividiXLinkedInFacebookWhatsApp

Commenti (0)

Ancora nessun commento. Inizia tu!