[{"data":1,"prerenderedAt":22},["ShallowReactive",2],{"articolo-slivers-in-flutter-creare-scroll-personalizzati-con-customscrollview":3,"comments-article-slivers-in-flutter-creare-scroll-personalizzati-con-customscrollview":21},{"id":4,"title":5,"slug":6,"excerpt":7,"body":8,"cover_image":9,"video_url":10,"status":11,"published_at":12,"meta_title":13,"meta_description":14,"category":15,"author":19},16,"Slivers in Flutter: creare scroll personalizzati con CustomScrollView","slivers-in-flutter-creare-scroll-personalizzati-con-customscrollview","Scopri come usare i Sliver in Flutter per costruire interfacce con scorrimento avanzato: app bar collassabili, liste e griglie combinate, header agganciati e molto altro con CustomScrollView.","## Cosa sono i Sliver\n\nIn Flutter, un **Sliver** è una porzione di un'area scorrevole. Il termine inglese significa letteralmente \"scheggia\" o \"fettina\": ogni Sliver rappresenta infatti una sezione che può comportarsi in modo diverso durante lo scorrimento. Mentre widget come `ListView` o `GridView` coprono i casi più comuni, quando hai bisogno di combinare più elementi scorrevoli con effetti sofisticati (app bar che si comprime, header che restano agganciati, liste e griglie nella stessa vista) i Sliver diventano lo strumento giusto.\n\nIl cuore di tutto è il widget **`CustomScrollView`**, che accetta una lista di Sliver e li dispone lungo un unico asse di scorrimento condiviso.\n\n## Il primo CustomScrollView\n\nVediamo un esempio base che combina un'app bar collassabile e una lista:\n\n```dart\nCustomScrollView(\n  slivers: [\n    SliverAppBar(\n      expandedHeight: 200,\n      pinned: true,\n      flexibleSpace: FlexibleSpaceBar(\n        title: const Text('Esplora'),\n        background: Image.network(\n          'https:\u002F\u002Fpicsum.photos\u002F600\u002F300',\n          fit: BoxFit.cover,\n        ),\n      ),\n    ),\n    SliverList(\n      delegate: SliverChildBuilderDelegate(\n        (context, index) => ListTile(\n          leading: const Icon(Icons.star),\n          title: Text('Elemento $index'),\n        ),\n        childCount: 30,\n      ),\n    ),\n  ],\n)\n```\n\nNota le proprietà di `SliverAppBar`:\n\n- **`expandedHeight`**: l'altezza massima quando è completamente espansa.\n- **`pinned`**: se `true`, l'app bar resta visibile (agganciata) in alto anche dopo il collasso.\n- **`floating`**: se `true`, l'app bar riappare appena scorri verso l'alto, senza dover arrivare in cima.\n- **`snap`** (usabile con `floating: true`): completa automaticamente l'animazione di apertura\u002Fchiusura.\n\n## SliverList e SliverGrid\n\nI due Sliver più usati per i contenuti sono `SliverList` e `SliverGrid`. Entrambi accettano un **delegate** che descrive come costruire i figli.\n\nPer una griglia:\n\n```dart\nSliverGrid(\n  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(\n    crossAxisCount: 3,\n    mainAxisSpacing: 8,\n    crossAxisSpacing: 8,\n    childAspectRatio: 1,\n  ),\n  delegate: SliverChildBuilderDelegate(\n    (context, index) => Container(\n      color: Colors.teal[(index % 9 + 1) * 100],\n      alignment: Alignment.center,\n      child: Text('$index'),\n    ),\n    childCount: 24,\n  ),\n)\n```\n\nEsiste anche il pratico costruttore **`SliverList.builder`** e **`SliverGrid.builder`** introdotti per semplificare la sintassi, evitando di scrivere esplicitamente il delegate:\n\n```dart\nSliverList.builder(\n  itemCount: 30,\n  itemBuilder: (context, index) => ListTile(\n    title: Text('Voce $index'),\n  ),\n)\n```\n\n## Inserire widget non scorrevoli con SliverToBoxAdapter\n\nSpesso vuoi inserire un widget normale (non un Sliver) all'interno di un `CustomScrollView`, ad esempio un banner o un titolo di sezione. Per farlo si usa **`SliverToBoxAdapter`**:\n\n```dart\nSliverToBoxAdapter(\n  child: Padding(\n    padding: const EdgeInsets.all(16),\n    child: Text(\n      'In evidenza',\n      style: Theme.of(context).textTheme.headlineSmall,\n    ),\n  ),\n)\n```\n\nFai attenzione: `SliverToBoxAdapter` costruisce il suo figlio tutto in una volta, quindi non è adatto a liste lunghe. Per quelle usa sempre `SliverList`.\n\n## Header agganciati con SliverPersistentHeader\n\nUno degli effetti più richiesti è l'header di sezione che resta \"appiccicato\" in cima mentre scorri (il classico *sticky header*). Si ottiene con **`SliverPersistentHeader`** e un delegate personalizzato:\n\n```dart\nclass _SezioneHeader extends SliverPersistentHeaderDelegate {\n  final String titolo;\n  _SezioneHeader(this.titolo);\n\n  @override\n  Widget build(\n    BuildContext context,\n    double shrinkOffset,\n    bool overlapsContent,\n  ) {\n    return Container(\n      color: Theme.of(context).colorScheme.surface,\n      alignment: Alignment.centerLeft,\n      padding: const EdgeInsets.symmetric(horizontal: 16),\n      child: Text(\n        titolo,\n        style: Theme.of(context).textTheme.titleMedium,\n      ),\n    );\n  }\n\n  @override\n  double get maxExtent => 48;\n\n  @override\n  double get minExtent => 48;\n\n  @override\n  bool shouldRebuild(_SezioneHeader oldDelegate) =>\n      oldDelegate.titolo != titolo;\n}\n```\n\nE poi nel `CustomScrollView`:\n\n```dart\nSliverPersistentHeader(\n  pinned: true,\n  delegate: _SezioneHeader('Categoria A'),\n)\n```\n\nCon `pinned: true` l'header rimane agganciato in cima; con `floating: true` ricompare allo scroll verso l'alto.\n\n## Aggiungere padding ai Sliver\n\nNon puoi avvolgere un Sliver in un normale `Padding`: ti serve **`SliverPadding`**:\n\n```dart\nSliverPadding(\n  padding: const EdgeInsets.all(16),\n  sliver: SliverList.builder(\n    itemCount: 10,\n    itemBuilder: (context, i) => Text('Riga $i'),\n  ),\n)\n```\n\n## Riempire lo spazio rimanente\n\nQuando una lista è più corta dello schermo e vuoi che un widget occupi lo spazio residuo (utile per stati vuoti), usa **`SliverFillRemaining`**:\n\n```dart\nSliverFillRemaining(\n  hasScrollBody: false,\n  child: Center(\n    child: Text('Non ci sono altri elementi'),\n  ),\n)\n```\n\n## Best practice\n\n- **Usa i builder**: con `SliverChildBuilderDelegate` o i costruttori `.builder` i figli vengono creati pigramente (lazy), risparmiando memoria.\n- **Evita `SliverToBoxAdapter` per le liste**: rende inutile la costruzione lazy.\n- **Un solo asse di scorrimento**: tutti i Sliver in un `CustomScrollView` condividono lo stesso `ScrollController`. Per scroll annidati su assi diversi valuta `NestedScrollView`.\n- **Definisci bene min\u002FmaxExtent** nei delegate persistenti: valori errati causano errori di layout.\n\n## Conclusioni\n\nI Sliver sono la chiave per costruire interfacce di scorrimento veramente flessibili in Flutter. Con `CustomScrollView` puoi combinare app bar collassabili, header agganciati, liste, griglie e widget statici in un'unica esperienza fluida. Una volta compreso il meccanismo di delegate e extent, avrai a disposizione un sistema potente per dare carattere alle tue schermate scorrevoli.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002F7b4ba529-c231-4e66-97f4-77e091b5160d.jpg",null,"published","2026-06-20T04:00:41+00:00","Sliver in Flutter: scroll avanzato con CustomScrollView","Guida pratica ai Sliver di Flutter: app bar collassabili, sticky header, liste e griglie combinate con CustomScrollView ed esempi di codice.",{"id":16,"name":17,"slug":18},1,"Guide","guide",{"id":16,"name":20},"Flutter Bot",[],1785219605395]