Effetti glassmorphism in Flutter con BackdropFilter e ImageFilter
GuideIntermedio25 min Flutter 3.x

Effetti glassmorphism in Flutter con BackdropFilter e ImageFilter

Il glassmorphism è uno stile di design molto diffuso che simula superfici in vetro smerigliato: sfondi sfocati, trasparenze e bordi luminosi. In Flutter possiamo ottenere questo effetto senza pacchetti esterni, sfruttando i widget nativi BackdropFilter, ImageFilter.blur e ClipRRect.

In questo tutorial costruiremo passo dopo passo una card in vetro sovrapposta a un'immagine di sfondo colorata, curando dettagli come sfocatura, opacità e bordi luminosi per un risultato professionale.

  1. 1

    Preparare lo sfondo colorato

    L'effetto glassmorphism ha bisogno di uno sfondo interessante dietro cui applicare la sfocatura: senza dettagli visivi il blur non si nota. Creiamo uno Scaffold con uno sfondo composto da forme colorate (o un'immagine) usando uno Stack.

    Qui usiamo un gradiente e due cerchi colorati come base.

    import 'package:flutter/material.dart';
    
    class GlassDemoPage extends StatelessWidget {
      const GlassDemoPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Stack(
            children: [
              // Sfondo con gradiente
              Container(
                decoration: const BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                    colors: [Color(0xFF6A11CB), Color(0xFF2575FC)],
                  ),
                ),
              ),
              // Cerchio decorativo 1
              Positioned(
                top: 80,
                left: -40,
                child: _circle(180, Colors.pinkAccent.withOpacity(0.6)),
              ),
              // Cerchio decorativo 2
              Positioned(
                bottom: 120,
                right: -30,
                child: _circle(220, Colors.orangeAccent.withOpacity(0.6)),
              ),
            ],
          ),
        );
      }
    
      Widget _circle(double size, Color color) => Container(
            width: size,
            height: size,
            decoration: BoxDecoration(shape: BoxShape.circle, color: color),
          );
    }

    Risultato atteso

    Una schermata con sfondo a gradiente viola-blu e due cerchi colorati sfumati.

  2. 2

    Applicare la sfocatura con BackdropFilter

    Il cuore dell'effetto è BackdropFilter, che applica un filtro (in questo caso ImageFilter.blur) a tutto ciò che sta dietro al suo child.

    È fondamentale racchiudere il BackdropFilter in un ClipRRect (o ClipRect): senza clipping la sfocatura si estenderebbe oltre i bordi del widget, causando artefatti visivi.

    import 'dart:ui';
    
    Widget buildGlass() {
      return ClipRRect(
        borderRadius: BorderRadius.circular(24),
        child: BackdropFilter(
          filter: ImageFilter.blur(sigmaX: 12, sigmaY: 12),
          child: Container(
            width: 300,
            height: 200,
            color: Colors.white.withOpacity(0.15),
          ),
        ),
      );
    }

    Risultato atteso

    Un rettangolo semitrasparente che sfoca lo sfondo sottostante, con angoli arrotondati.

  3. 3

    Aggiungere bordi luminosi e opacità corretta

    Per un vero effetto vetro servono tre ingredienti:

    • un colore bianco a bassa opacità (0.1–0.2) come riempimento
    • un bordo sottile bianco semitrasparente che simula il riflesso del vetro
    • un borderRadius coerente con il ClipRRect

    Risistemiamo la card usando un Container con BoxDecoration completa.

    Widget glassCard({required Widget child}) {
      return ClipRRect(
        borderRadius: BorderRadius.circular(24),
        child: BackdropFilter(
          filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15),
          child: Container(
            padding: const EdgeInsets.all(24),
            decoration: BoxDecoration(
              color: Colors.white.withOpacity(0.15),
              borderRadius: BorderRadius.circular(24),
              border: Border.all(
                color: Colors.white.withOpacity(0.3),
                width: 1.5,
              ),
            ),
            child: child,
          ),
        ),
      );
    }

    Risultato atteso

    Una card in vetro con bordo luminoso e leggera trasparenza bianca.

  4. 4

    Inserire contenuti dentro la card

    Ora aggiungiamo del contenuto testuale e iconografico all'interno della card. Usiamo testo bianco per garantire il contrasto sopra lo sfondo colorato e centriamo la card nello Stack.

    Widget centeredCard() {
      return Center(
        child: SizedBox(
          width: 320,
          child: glassCard(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: const [
                Icon(Icons.lock_outline, color: Colors.white, size: 40),
                SizedBox(height: 16),
                Text(
                  'Accesso sicuro',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 22,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                SizedBox(height: 8),
                Text(
                  'I tuoi dati sono protetti con crittografia end-to-end.',
                  style: TextStyle(color: Colors.white70, fontSize: 14),
                ),
              ],
            ),
          ),
        ),
      );
    }

    Risultato atteso

    La card in vetro mostra un'icona, un titolo e una descrizione ben leggibili.

  5. 5

    Comporre il tutto nella pagina

    Uniamo lo sfondo del primo passo con la card centrale. Ricorda di importare dart:ui per ImageFilter. Aggiungiamo la card come ultimo figlio dello Stack così da sfocare tutto ciò che sta sotto.

    import 'dart:ui';
    import 'package:flutter/material.dart';
    
    class GlassDemoPage extends StatelessWidget {
      const GlassDemoPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Stack(
            children: [
              Container(
                decoration: const BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                    colors: [Color(0xFF6A11CB), Color(0xFF2575FC)],
                  ),
                ),
              ),
              Positioned(top: 80, left: -40, child: _circle(180, Colors.pinkAccent.withOpacity(0.6))),
              Positioned(bottom: 120, right: -30, child: _circle(220, Colors.orangeAccent.withOpacity(0.6))),
              centeredCard(),
            ],
          ),
        );
      }
    
      Widget _circle(double size, Color color) => Container(
            width: size,
            height: size,
            decoration: BoxDecoration(shape: BoxShape.circle, color: color),
          );
    }

    Risultato atteso

    La pagina completa mostra la card in vetro che sfoca lo sfondo colorato dietro di sé.

  6. 6

    Ottimizzare le prestazioni

    BackdropFilter è costoso: forza la GPU a ricalcolare la sfocatura ad ogni frame. Alcune buone pratiche:

    • Limita l'area sfocata: sfoca solo la card, non l'intero schermo, mantenendo il ClipRRect stretto.
    • Evita blur animati continui su widget grandi; se necessari, riduci il sigma.
    • Su liste, non applicare BackdropFilter a decine di elementi visibili contemporaneamente.
    • Valuta RepaintBoundary per isolare i ridisegni.
    • Testa sempre su dispositivi reali di fascia bassa, non solo sull'emulatore.

    Seguendo queste accortezze otterrai un glassmorphism elegante senza penalizzare la fluidità dell'app.

    // Esempio: isolare il ridisegno della card
    RepaintBoundary(
      child: glassCard(child: /* ... */ const SizedBox()),
    );

    Risultato atteso

    L'effetto vetro rimane fluido anche su dispositivi meno potenti.

CondividiXLinkedInFacebookWhatsApp

Commenti (0)

Ancora nessun commento. Inizia tu!