[{"data":1,"prerenderedAt":74},["ShallowReactive",2],{"tutorial-reagire-alla-scroll-in-flutter-con-sliverappbar-e-customscrollview":3,"comments-tutorial-reagire-alla-scroll-in-flutter-con-sliverappbar-e-customscrollview":73},{"id":4,"title":5,"slug":6,"excerpt":7,"intro":8,"cover_image":9,"video_url":10,"difficulty":11,"estimated_minutes":12,"flutter_version":13,"status":14,"published_at":15,"meta_title":16,"meta_description":17,"category":18,"author":22,"steps":24},50,"Reagire alla scroll in Flutter con SliverAppBar e CustomScrollView","reagire-alla-scroll-in-flutter-con-sliverappbar-e-customscrollview","Impara a costruire schermate con effetti di scroll avanzati in Flutter usando CustomScrollView e SliverAppBar: header collassabili, immagini parallasse e liste ottimizzate.","# Effetti di scroll con i Sliver\n\nSe hai bisogno di un header che si comprime durante lo scroll, un'immagine di copertina con effetto parallasse o vuoi combinare header, griglie e liste in un'unica area scrollabile, i widget **Sliver** sono la soluzione idiomatica di Flutter.\n\nIn questo tutorial costruiremo una schermata di dettaglio con un `SliverAppBar` collassabile, contenuti misti e una lista performante, il tutto dentro un `CustomScrollView`.\n\n> **Prerequisiti**: conoscenza base di widget e layout in Flutter.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Ftutorials\u002F5193eb16-c92b-4ea2-81d8-9af426b86a60.jpg",null,"intermediate",35,"3.x","published","2026-07-27T04:30:48+00:00","SliverAppBar e CustomScrollView in Flutter: guida","Crea header collassabili ed effetti parallasse in Flutter con CustomScrollView e SliverAppBar. Guida pratica passo-passo con esempi di codice.",{"id":19,"name":20,"slug":21},1,"Guide","guide",{"id":19,"name":23},"Flutter Bot",[25,31,38,45,52,59,66],{"id":26,"position":19,"title":27,"body":28,"code_snippet":10,"code_language":29,"expected_result":30,"demo_url":10,"video_url":10},336,"Capire i Sliver e CustomScrollView","Un **Sliver** è una porzione di area scrollabile. `CustomScrollView` è un widget che accetta una lista di sliver e li dispone lungo un unico asse di scroll condiviso.\n\nI principali sliver che useremo sono:\n\n- **`SliverAppBar`**: una AppBar che può espandersi, collassare e rimanere fissa (pinned) durante lo scroll.\n- **`SliverToBoxAdapter`**: incapsula un normale widget \"box\" (come `Container` o `Column`) dentro un contesto sliver.\n- **`SliverList`** e **`SliverGrid`**: versioni lazy di liste e griglie.\n\nLa differenza chiave rispetto a `ListView` è che qui più sezioni diverse condividono lo stesso scroll fluido.","dart","Hai chiara la differenza tra widget box e widget sliver e sai perché servono.",{"id":32,"position":33,"title":34,"body":35,"code_snippet":36,"code_language":29,"expected_result":37,"demo_url":10,"video_url":10},337,2,"Impostare lo scheletro con CustomScrollView","Creiamo una nuova schermata `StatelessWidget` che usa `CustomScrollView` come corpo dello `Scaffold`. Per ora inseriamo solo un `SliverAppBar` di base per verificare che la struttura funzioni.","import 'package:flutter\u002Fmaterial.dart';\n\nclass DetailScreen extends StatelessWidget {\n  const DetailScreen({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      body: CustomScrollView(\n        slivers: const [\n          SliverAppBar(\n            title: Text('Dettaglio'),\n            expandedHeight: 250,\n          ),\n        ],\n      ),\n    );\n  }\n}","Compilando l'app vedi una AppBar alta 250px che occupa la parte superiore dello schermo.",{"id":39,"position":40,"title":41,"body":42,"code_snippet":43,"code_language":29,"expected_result":44,"demo_url":10,"video_url":10},338,3,"Configurare un SliverAppBar collassabile","Ora rendiamo la AppBar interessante. Le proprietà chiave sono:\n\n- **`expandedHeight`**: altezza massima quando è espansa.\n- **`pinned: true`**: la barra resta visibile (collassata) in cima anche dopo lo scroll.\n- **`floating`**: se `true`, riappare appena si scrolla verso l'alto.\n- **`flexibleSpace`**: il contenuto che si espande\u002Fcomprime, tipicamente un `FlexibleSpaceBar`.\n\nUsiamo `FlexibleSpaceBar` con un titolo e un'immagine di sfondo.","SliverAppBar(\n  expandedHeight: 260,\n  pinned: true,\n  stretch: true,\n  flexibleSpace: FlexibleSpaceBar(\n    title: const Text('Monti del Trentino'),\n    centerTitle: true,\n    background: Image.network(\n      'https:\u002F\u002Fpicsum.photos\u002Fid\u002F1018\u002F800\u002F600',\n      fit: BoxFit.cover,\n    ),\n    stretchModes: const [\n      StretchMode.zoomBackground,\n      StretchMode.blurBackground,\n    ],\n  ),\n)","Scrollando, l'immagine si comprime e il titolo si sposta gradualmente verso la AppBar collassata; tirando verso il basso l'immagine fa uno zoom (stretch).",{"id":46,"position":47,"title":48,"body":49,"code_snippet":50,"code_language":29,"expected_result":51,"demo_url":10,"video_url":10},339,4,"Aggiungere contenuto con SliverToBoxAdapter","Dopo la AppBar vogliamo inserire un blocco di contenuto \"normale\" (una descrizione). Poiché `CustomScrollView` accetta solo sliver, incapsuliamo il nostro widget box dentro un `SliverToBoxAdapter`.\n\nAggiungi questo sliver subito dopo il `SliverAppBar` nella lista `slivers`.","SliverToBoxAdapter(\n  child: Padding(\n    padding: const EdgeInsets.all(16),\n    child: Column(\n      crossAxisAlignment: CrossAxisAlignment.start,\n      children: const [\n        Text(\n          'Descrizione',\n          style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),\n        ),\n        SizedBox(height: 8),\n        Text(\n          'Una raccolta dei sentieri piu belli del Trentino, '\n          'con dislivelli, tempi di percorrenza e punti panoramici.',\n        ),\n      ],\n    ),\n  ),\n)","Sotto l'header appare un blocco di testo che scorre insieme al resto della schermata.",{"id":53,"position":54,"title":55,"body":56,"code_snippet":57,"code_language":29,"expected_result":58,"demo_url":10,"video_url":10},340,5,"Inserire una lista performante con SliverList","Per elenchi lunghi usiamo `SliverList` con `SliverChildBuilderDelegate`, che costruisce gli elementi in modo **lazy** (solo quelli visibili), esattamente come `ListView.builder`.\n\nIl parametro `childCount` indica il numero di elementi; ometterlo crea una lista infinita.","SliverList(\n  delegate: SliverChildBuilderDelegate(\n    (context, index) {\n      return ListTile(\n        leading: CircleAvatar(child: Text('${index + 1}')),\n        title: Text('Sentiero n. ${index + 1}'),\n        subtitle: const Text('Difficolta media - 3h'),\n      );\n    },\n    childCount: 30,\n  ),\n)","Sotto la descrizione compare una lista di 30 elementi che scorre in modo fluido nello stesso movimento dell'header.",{"id":60,"position":61,"title":62,"body":63,"code_snippet":64,"code_language":29,"expected_result":65,"demo_url":10,"video_url":10},341,6,"Aggiungere una griglia con SliverGrid","Possiamo mixare anche una griglia nella stessa area di scroll. `SliverGrid.builder` usa un `gridDelegate` per definire il layout, ad esempio `SliverGridDelegateWithFixedCrossAxisCount` per un numero fisso di colonne.\n\nInseriamo la griglia dopo la lista (o al posto suo, a seconda del design).","SliverGrid.builder(\n  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(\n    crossAxisCount: 2,\n    mainAxisSpacing: 8,\n    crossAxisSpacing: 8,\n    childAspectRatio: 1.4,\n  ),\n  itemCount: 6,\n  itemBuilder: (context, index) {\n    return Card(\n      child: Center(child: Text('Foto ${index + 1}')),\n    );\n  },\n)","Nella stessa schermata scrollabile compare una griglia a 2 colonne integrata con lista e header.",{"id":67,"position":68,"title":69,"body":70,"code_snippet":71,"code_language":29,"expected_result":72,"demo_url":10,"video_url":10},342,7,"Best practice e rifiniture","Qualche accorgimento finale:\n\n- **`SliverPadding`**: usalo per aggiungere spaziatura attorno a un `SliverList` o `SliverGrid` (i normali `Padding` non funzionano tra sliver).\n- **`SliverFillRemaining`**: utile per riempire lo spazio residuo (es. stato vuoto centrato).\n- **`SliverSafeArea`**: gestisce le aree sicure in contesto sliver.\n- Preferisci sempre le versioni `builder`\u002Fdelegate per liste lunghe: mantengono le performance grazie al lazy loading.\n\nEsempio di padding attorno alla lista precedente:","SliverPadding(\n  padding: const EdgeInsets.symmetric(horizontal: 16),\n  sliver: SliverList(\n    delegate: SliverChildBuilderDelegate(\n      (context, index) => ListTile(title: Text('Voce $index')),\n      childCount: 10,\n    ),\n  ),\n)","Hai una schermata completa con header parallasse collassabile, contenuti misti, lista e griglia, tutto in un unico scroll fluido e performante.",[],1785219595301]