[{"data":1,"prerenderedAt":27},["ShallowReactive",2],{"articolo-effetti-blur-e-glassmorphism-in-flutter-guida-a-backdropfilter-imagefiltered-e-backdropgroup":3,"comments-article-effetti-blur-e-glassmorphism-in-flutter-guida-a-backdropfilter-imagefiltered-e-backdropgroup":26},{"id":4,"title":5,"slug":6,"excerpt":7,"body":8,"cover_image":9,"cover_remote_url":10,"cover_credit":11,"video_url":15,"status":16,"published_at":17,"meta_title":18,"meta_description":19,"category":20,"author":24},145,"Effetti blur e glassmorphism in Flutter: guida a BackdropFilter, ImageFiltered e BackdropGroup","effetti-blur-e-glassmorphism-in-flutter-guida-a-backdropfilter-imagefiltered-e-backdropgroup","Come realizzare superfici in vetro smerigliato, barre traslucide e sfocature animate in Flutter senza distruggere il frame rate: differenze tra BackdropFilter e ImageFiltered, clipping corretto e la nuova ottimizzazione BackdropGroup.","Il vetro smerigliato è tornato di moda: barre di navigazione traslucide, card che lasciano intravedere lo sfondo, dialog con il contenuto sottostante sfocato. In Flutter tutto questo si ottiene con due widget apparentemente simili ma profondamente diversi — `BackdropFilter` e `ImageFiltered` — e con una buona dose di attenzione alle performance, perché la sfocatura è uno degli effetti più costosi che possiamo chiedere alla GPU.\n\nIn questa guida vediamo come usarli correttamente, quali errori evitare e come sfruttare `BackdropGroup`, l'ottimizzazione introdotta in Flutter 3.35 per i blur multipli.\n\n## BackdropFilter vs ImageFiltered: la differenza fondamentale\n\nEntrambi applicano un `ImageFilter`, ma su soggetti diversi:\n\n- **`ImageFiltered`** filtra **il proprio child**. È come applicare un effetto Photoshop al widget stesso: una foto sfocata, un'icona con un alone, un testo fuori fuoco.\n- **`BackdropFilter`** filtra **tutto ciò che è già stato disegnato dietro di lui** nello stesso layer, e poi disegna il proprio child *sopra*, nitido. È questo il widget del glassmorphism.\n\n```dart\n\u002F\u002F Sfoca l'immagine stessa\nImageFiltered(\n  imageFilter: ImageFilter.blur(sigmaX: 8, sigmaY: 8),\n  child: Image.asset('assets\u002Fcover.jpg'),\n)\n\n\u002F\u002F Sfoca ciò che sta sotto e ci appoggia sopra un testo nitido\nStack(\n  children: [\n    Image.asset('assets\u002Fcover.jpg', fit: BoxFit.cover),\n    BackdropFilter(\n      filter: ImageFilter.blur(sigmaX: 12, sigmaY: 12),\n      child: Container(\n        color: Colors.white.withValues(alpha: 0.12),\n        alignment: Alignment.center,\n        child: const Text('Vetro smerigliato'),\n      ),\n    ),\n  ],\n)\n```\n\nDue regole da ricordare subito:\n\n1. **`BackdropFilter` senza child (o con un child completamente trasparente) non si vede.** Il filtro viene applicato all'area coperta dal child: serve almeno un `Container` con un colore semi-trasparente o `SizedBox.expand`.\n2. **Per impostazione predefinita si espande fino a riempire il genitore.** Dentro uno `Stack` non vincolato, sfocherà l'intero schermo. Il confinamento si ottiene con il clipping.\n\n## Clipping: il passo che quasi tutti sbagliano\n\nPer ottenere una card di vetro con angoli arrotondati bisogna **ritagliare il BackdropFilter**, non il suo contenuto. Il modo corretto è avvolgerlo in un `ClipRRect` (o `ClipPath`), perché il filtro viene applicato al rettangolo di disegno e senza clip \"esce\" dai bordi.\n\n```dart\nclass GlassCard extends StatelessWidget {\n  const GlassCard({\n    super.key,\n    required this.child,\n    this.blur = 16,\n    this.borderRadius = const BorderRadius.all(Radius.circular(20)),\n  });\n\n  final Widget child;\n  final double blur;\n  final BorderRadius borderRadius;\n\n  @override\n  Widget build(BuildContext context) {\n    return ClipRRect(\n      borderRadius: borderRadius,\n      child: BackdropFilter(\n        filter: ImageFilter.blur(sigmaX: blur, sigmaY: blur),\n        child: DecoratedBox(\n          decoration: BoxDecoration(\n            color: Colors.white.withValues(alpha: 0.15),\n            borderRadius: borderRadius,\n            border: Border.all(\n              color: Colors.white.withValues(alpha: 0.25),\n              width: 1,\n            ),\n          ),\n          child: Padding(\n            padding: const EdgeInsets.all(16),\n            child: child,\n          ),\n        ),\n      ),\n    );\n  }\n}\n```\n\nIl bordo chiaro a 1px non è un vezzo estetico: è ciò che dà l'impressione dello spessore del vetro e separa la superficie dallo sfondo.\n\n### TileMode: eliminare gli aloni ai bordi\n\n`ImageFilter.blur` accetta un parametro `tileMode` che decide come viene campionato il contenuto oltre i limiti dell'area filtrata. Il default è `TileMode.clamp`, che replica i pixel di bordo e può creare strisciate visibili quando il blur è vicino al margine dello schermo. `TileMode.decal` tratta l'esterno come trasparente, risultato spesso più pulito:\n\n```dart\nImageFilter.blur(sigmaX: 20, sigmaY: 20, tileMode: TileMode.decal)\n```\n\n## Una app bar traslucida\n\nUn classico: la barra superiore che sfoca il contenuto che le scorre sotto. Si usa `flexibleSpace` perché è il livello che riempie l'intera area della `AppBar`, inclusa la status bar.\n\n```dart\nAppBar(\n  title: const Text('Esplora'),\n  backgroundColor: Colors.transparent,\n  elevation: 0,\n  scrolledUnderElevation: 0,\n  flexibleSpace: ClipRect(\n    child: BackdropFilter(\n      filter: ImageFilter.blur(sigmaX: 18, sigmaY: 18),\n      child: Container(\n        color: Theme.of(context)\n            .colorScheme\n            .surface\n            .withValues(alpha: 0.6),\n      ),\n    ),\n  ),\n)\n```\n\nPerché il contenuto scorra realmente *sotto* la barra, lo `Scaffold` deve avere `extendBodyBehindAppBar: true` (e `extendBody: true` per la bottom bar). Ricordate poi di compensare il padding con `MediaQuery.paddingOf(context).top` o con un `SliverAppBar` appropriato.\n\n## Sfocare lo sfondo di un dialog\n\nUn pattern molto efficace è sostituire il barrier scuro standard con un barrier sfocato animato:\n\n```dart\nFuture\u003CT?> showBlurredDialog\u003CT>(BuildContext context, Widget child) {\n  return showGeneralDialog\u003CT>(\n    context: context,\n    barrierDismissible: true,\n    barrierLabel: 'Chiudi',\n    barrierColor: Colors.black.withValues(alpha: 0.25),\n    transitionDuration: const Duration(milliseconds: 220),\n    pageBuilder: (_, __, ___) => child,\n    transitionBuilder: (context, animation, _, child) {\n      final curved = CurvedAnimation(\n        parent: animation,\n        curve: Curves.easeOutCubic,\n      );\n      return AnimatedBuilder(\n        animation: curved,\n        builder: (context, _) => BackdropFilter(\n          filter: ImageFilter.blur(\n            sigmaX: 10 * curved.value,\n            sigmaY: 10 * curved.value,\n          ),\n          child: Opacity(opacity: curved.value, child: child),\n        ),\n        child: child,\n      );\n    },\n  );\n}\n```\n\nAttenzione: un sigma pari a 0 con Impeller è comunque un'operazione di layer. Se volete davvero azzerare il costo quando l'animazione è ferma a zero, restituite il child senza `BackdropFilter`.\n\n## BackdropGroup: blur multipli senza moltiplicare il costo\n\nOgni `BackdropFilter` forza il motore a leggere il contenuto già renderizzato, applicare la sfocatura e ricomporre: internamente equivale a un `saveLayer`. Se in una schermata ne avete cinque (una barra, tre card e un bottone flottante), il costo si somma, perché ciascuno ricalcola la propria sfocatura in modo indipendente.\n\nDa **Flutter 3.35** esiste `BackdropGroup`, che permette ai filtri discendenti di **condividere il risultato della sfocatura**. Basta avvolgere il sottoalbero e usare il costruttore `BackdropFilter.grouped`:\n\n```dart\nBackdropGroup(\n  child: Column(\n    children: [\n      BackdropFilter.grouped(\n        filter: ImageFilter.blur(sigmaX: 14, sigmaY: 14),\n        child: const GlassPanel(title: 'Meteo'),\n      ),\n      BackdropFilter.grouped(\n        filter: ImageFilter.blur(sigmaX: 14, sigmaY: 14),\n        child: const GlassPanel(title: 'Agenda'),\n      ),\n    ],\n  ),\n)\n```\n\nIl guadagno è tangibile quando i filtri usano lo stesso sigma e insistono sullo stesso sfondo: invece di N passate di blur se ne paga sostanzialmente una. Se usate ancora una versione precedente, la soluzione alternativa è ridurre il numero di filtri accorpando le superfici di vetro in un unico widget.\n\n## Strategie per non perdere frame\n\n- **Evitate i blur dentro le liste scrollabili.** Un `BackdropFilter` per ogni elemento di una `ListView` significa ricalcolare la sfocatura a ogni frame di scroll. Se proprio serve, limitatelo agli elementi visibili o usate un'immagine pre-sfocata.\n- **Attenzione a `RepaintBoundary`.** Isolare il contenuto *dietro* al filtro aiuta, ma mettere un `RepaintBoundary` fra lo sfondo e il `BackdropFilter` può spezzare il layer e far sì che il filtro non \"veda\" più nulla da sfocare.\n- **Il sigma conta.** Con Impeller il costo cresce con il raggio: valori fra 8 e 20 sono quasi sempre sufficienti. Non serve arrivare a 50.\n- **Preferite `ImageFiltered` quando lo sfondo è statico.** Se dovete sfocare una foto che non cambia, filtratela una volta sola invece di filtrare il backdrop a ogni frame. Ancora meglio: generate la versione sfocata lato server o a build time.\n- **Misurate.** Attivate l'overlay delle performance (`flutter run --profile` + DevTools, oppure `showPerformanceOverlay: true`) e osservate la barra GPU: i blur si manifestano quasi sempre lì, non nella barra UI.\n- **Occhio al Web.** Su Flutter Web il `BackdropFilter` è supportato ma può essere nettamente più costoso rispetto al mobile, soprattutto con il renderer HTML dei canali meno recenti. Testate sempre sul target reale.\n\n## Oltre il blur: comporre filtri\n\n`ImageFilter` non fa solo sfocature. Potete combinare più filtri con `ImageFilter.compose` per ottenere, ad esempio, un vetro desaturato e leggermente più luminoso:\n\n```dart\nfinal saturate = ColorFilter.mode(\n  Colors.white.withValues(alpha: 0.08),\n  BlendMode.overlay,\n);\n\nBackdropFilter(\n  filter: ImageFilter.compose(\n    outer: ImageFilter.matrix(\n      (Matrix4.identity()..scale(1.04, 1.04)).storage,\n    ),\n    inner: ImageFilter.blur(sigmaX: 18, sigmaY: 18),\n  ),\n  child: ColorFiltered(\n    colorFilter: saturate,\n    child: const SizedBox.expand(),\n  ),\n)\n```\n\nIl leggero ingrandimento (`ImageFilter.matrix`) nasconde i bordi trasparenti che il blur può lasciare ed è un trucco usato spesso nelle UI di sistema.\n\n## Leggibilità e accessibilità\n\nIl vetro è bello ma pericoloso per il contrasto: un testo bianco su un pannello traslucido può diventare illeggibile quando dietro passa un'immagine chiara. Qualche accorgimento:\n\n- aggiungete sempre un **colore di tinta** sotto il testo (`surface.withValues(alpha: 0.6)`), non affidatevi solo alla sfocatura;\n- verificate il rapporto di contrasto nel caso peggiore, non su uno sfondo di comodo;\n- rispettate `MediaQuery.of(context).disableAnimations` e, su iOS, considerate di ridurre la trasparenza quando l'utente ha attivato le relative impostazioni di accessibilità, offrendo un fallback a superficie piena.\n\n## In sintesi\n\n`ImageFiltered` filtra il contenuto, `BackdropFilter` filtra lo sfondo: scegliere il widget giusto è metà del lavoro. L'altra metà è il contenimento (clip corretto, `TileMode` adeguato) e il controllo del costo: pochi filtri, sigma ragionevoli, nessun blur dentro le liste e, su Flutter 3.35 o superiore, `BackdropGroup` per condividere il lavoro fra più superfici. Con queste regole il glassmorphism smette di essere un lusso da schermata statica e diventa un elemento utilizzabile nella UI di tutti i giorni.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002Fd844b8cd-3a38-467f-bd51-1d02a7acc267.jpg","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1752524722694-e0976575a993?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w5NzA2NTJ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3OTM1MDU3MDR8&ixlib=rb-4.1.0&q=80&w=1080",{"name":12,"author_url":13,"photo_url":14},"Shubham Dhage","https:\u002F\u002Funsplash.com\u002F@theshubhamdhage","https:\u002F\u002Funsplash.com\u002Fphotos\u002Fflowers-and-reflections-bloom-on-a-sunny-day-o9NLhlvX3AQ",null,"published","2026-11-01T04:01:44+00:00","Glassmorphism in Flutter: BackdropFilter e blur efficienti","Guida pratica agli effetti blur in Flutter: differenze tra BackdropFilter e ImageFiltered, clipping corretto, app bar traslucide e ottimizzazione con BackdropGroup.",{"id":21,"name":22,"slug":23},1,"Guide","guide",{"id":21,"name":25},"Flutter Bot",[],1793534300204]