From c7d51af89002462f709fb30ba83656c91ad9af0c Mon Sep 17 00:00:00 2001 From: Amanda Fitch Date: Fri, 14 Mar 2025 14:41:20 -0700 Subject: [PATCH 1/5] Add cupertino examples to the Floating App Bar recipe. --- .../floating_app_bar/lib/main_cupertino.dart | 43 +++ .../lib/{main.dart => main_material.dart} | 8 +- .../lib/starter_cupertino.dart | 20 ++ .../{starter.dart => starter_material.dart} | 2 +- .../floating_app_bar/lib/step2_cupertino.dart | 31 ++ .../lib/{step2.dart => step2_material.dart} | 2 + .../cookbook/lists/floating-app-bar.md | 283 ++++++++++++++---- 7 files changed, 323 insertions(+), 66 deletions(-) create mode 100644 examples/cookbook/lists/floating_app_bar/lib/main_cupertino.dart rename examples/cookbook/lists/floating_app_bar/lib/{main.dart => main_material.dart} (86%) create mode 100644 examples/cookbook/lists/floating_app_bar/lib/starter_cupertino.dart rename examples/cookbook/lists/floating_app_bar/lib/{starter.dart => starter_material.dart} (88%) create mode 100644 examples/cookbook/lists/floating_app_bar/lib/step2_cupertino.dart rename examples/cookbook/lists/floating_app_bar/lib/{step2.dart => step2_material.dart} (91%) diff --git a/examples/cookbook/lists/floating_app_bar/lib/main_cupertino.dart b/examples/cookbook/lists/floating_app_bar/lib/main_cupertino.dart new file mode 100644 index 0000000000..afd5c9364e --- /dev/null +++ b/examples/cookbook/lists/floating_app_bar/lib/main_cupertino.dart @@ -0,0 +1,43 @@ +import 'package:flutter/cupertino.dart'; + +void main() => runApp(const MyApp()); + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + const title = 'Floating Navigation Bar'; + + return CupertinoApp( + title: title, + home: CupertinoPageScaffold( + // No navigation bar provided to CupertinoPageScaffold, + // only a body with a CustomScrollView. + child: CustomScrollView( + slivers: [ + // Add the navigation bar to the CustomScrollView. + const CupertinoSliverNavigationBar( + // Provide a standard title. + largeTitle: Text(title), + ), + // #docregion SliverList + // Next, create a SliverList + SliverList( + // Use a delegate to build items as they're scrolled on screen. + delegate: SliverChildBuilderDelegate( + // The builder function returns a ListTile with a title that + // displays the index of the current item. + (context, index) => + CupertinoListTile(title: Text('Item #$index')), + // Builds 50 ListTiles + childCount: 50, + ), + ), + // #enddocregion SliverList + ], + ), + ), + ); + } +} diff --git a/examples/cookbook/lists/floating_app_bar/lib/main.dart b/examples/cookbook/lists/floating_app_bar/lib/main_material.dart similarity index 86% rename from examples/cookbook/lists/floating_app_bar/lib/main.dart rename to examples/cookbook/lists/floating_app_bar/lib/main_material.dart index 49aa9401c4..81bac58329 100644 --- a/examples/cookbook/lists/floating_app_bar/lib/main.dart +++ b/examples/cookbook/lists/floating_app_bar/lib/main_material.dart @@ -12,7 +12,7 @@ class MyApp extends StatelessWidget { return MaterialApp( title: title, home: Scaffold( - // No appbar provided to the Scaffold, only a body with a + // No app bar provided to Scaffold, only a body with a // CustomScrollView. body: CustomScrollView( slivers: [ @@ -21,6 +21,8 @@ class MyApp extends StatelessWidget { // Provide a standard title. title: Text(title), // Allows the user to reveal the app bar if they begin scrolling + pinned: true, + // Allows the user to reveal the app bar if they begin scrolling // back up the list of items. floating: true, // Display a placeholder widget to visualize the shrinking size. @@ -36,8 +38,8 @@ class MyApp extends StatelessWidget { // The builder function returns a ListTile with a title that // displays the index of the current item. (context, index) => ListTile(title: Text('Item #$index')), - // Builds 1000 ListTiles - childCount: 1000, + // Builds 50 ListTiles + childCount: 50, ), ), // #enddocregion SliverList diff --git a/examples/cookbook/lists/floating_app_bar/lib/starter_cupertino.dart b/examples/cookbook/lists/floating_app_bar/lib/starter_cupertino.dart new file mode 100644 index 0000000000..367d74bc46 --- /dev/null +++ b/examples/cookbook/lists/floating_app_bar/lib/starter_cupertino.dart @@ -0,0 +1,20 @@ +import 'package:flutter/cupertino.dart'; + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + // #docregion CustomScrollView + return const CupertinoApp( + home: CupertinoPageScaffold( + // No navigation bar property provided yet. + child: CustomScrollView( + // Add the navigation bar and list of items as slivers in the next steps. + slivers: [], + ), + ), + ); + // #enddocregion CustomScrollView + } +} diff --git a/examples/cookbook/lists/floating_app_bar/lib/starter.dart b/examples/cookbook/lists/floating_app_bar/lib/starter_material.dart similarity index 88% rename from examples/cookbook/lists/floating_app_bar/lib/starter.dart rename to examples/cookbook/lists/floating_app_bar/lib/starter_material.dart index b4ca0e08e3..14d88dd2a7 100644 --- a/examples/cookbook/lists/floating_app_bar/lib/starter.dart +++ b/examples/cookbook/lists/floating_app_bar/lib/starter_material.dart @@ -7,7 +7,7 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { // #docregion CustomScrollView return const Scaffold( - // No appBar property provided, only the body. + // No app bar property provided yet. body: CustomScrollView( // Add the app bar and list of items as slivers in the next steps. slivers: [], diff --git a/examples/cookbook/lists/floating_app_bar/lib/step2_cupertino.dart b/examples/cookbook/lists/floating_app_bar/lib/step2_cupertino.dart new file mode 100644 index 0000000000..966466ac84 --- /dev/null +++ b/examples/cookbook/lists/floating_app_bar/lib/step2_cupertino.dart @@ -0,0 +1,31 @@ +import 'package:flutter/cupertino.dart'; + +void main() => runApp(const MyApp()); + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + const title = 'Floating Navigation Bar'; + + return CupertinoApp( + title: title, + home: CupertinoPageScaffold( + // No navigation bar provided to CupertinoPageScaffold, + // only a body with a CustomScrollView. + // #docregion SliverAppBar + child: CustomScrollView( + slivers: [ + // Add the navigation bar to the CustomScrollView. + const CupertinoSliverNavigationBar( + // Provide a standard title. + largeTitle: Text(title), + ), + ], + ), + // #enddocregion SliverAppBar + ), + ); + } +} diff --git a/examples/cookbook/lists/floating_app_bar/lib/step2.dart b/examples/cookbook/lists/floating_app_bar/lib/step2_material.dart similarity index 91% rename from examples/cookbook/lists/floating_app_bar/lib/step2.dart rename to examples/cookbook/lists/floating_app_bar/lib/step2_material.dart index a70e7dbc7d..f941a77d09 100644 --- a/examples/cookbook/lists/floating_app_bar/lib/step2.dart +++ b/examples/cookbook/lists/floating_app_bar/lib/step2_material.dart @@ -22,6 +22,8 @@ class MyApp extends StatelessWidget { // Provide a standard title. title: Text(title), // Allows the user to reveal the app bar if they begin scrolling + pinned: true, + // Allows the user to reveal the app bar if they begin scrolling // back up the list of items. floating: true, // Display a placeholder widget to visualize the shrinking size. diff --git a/src/content/cookbook/lists/floating-app-bar.md b/src/content/cookbook/lists/floating-app-bar.md index 81bddeef35..ce5eac78e2 100644 --- a/src/content/cookbook/lists/floating-app-bar.md +++ b/src/content/cookbook/lists/floating-app-bar.md @@ -1,6 +1,6 @@ --- title: Place a floating app bar above a list -description: How to place a floating app bar above a list. +description: How to place a floating app bar or navigation bar above a list. js: - defer: true url: /assets/js/inject_dartpad.js @@ -8,51 +8,57 @@ js: -To make it easier for users to view a list of items, -you might want to hide the app bar as the user scrolls down the list. -This is especially true if your app displays a "tall" -app bar that occupies a lot of vertical space. +This guide describes how to place a floating app bar or +navigation bar above a list in a Flutter app. + +## Overview -Typically, you create an app bar by providing an `appBar` property to the -`Scaffold` widget. This creates a fixed app bar that always remains above -the `body` of the `Scaffold`. +To make it easier for users to view a list of items, +you might want to minimize the app bar (navigation bar), as +the user scrolls down the list. -Moving the app bar from a `Scaffold` widget into a -[`CustomScrollView`][] allows you to create an app bar -that scrolls offscreen as you scroll through a -list of items contained inside the `CustomScrollView`. +Moving the app bar into a [`CustomScrollView`][] allows you +to create an app bar that can be minimized or scroll +offscreen as you scroll through a list of items contained +inside the `CustomScrollView`. -This recipe demonstrates how to use a `CustomScrollView` to display a list of -items with an app bar on top that scrolls offscreen as the user scrolls -down the list using the following steps: +This recipe demonstrates how to use a `CustomScrollView` to +display a list of items with an app bar on top that +minimizes as the user scrolls down the list using the +following steps: 1. Create a `CustomScrollView`. - 2. Use `SliverAppBar` to add a floating app bar. - 3. Add a list of items using a `SliverList`. + 2. Add a floating app bar to `CustomScrollView`. + 3. Add a list of items to `CustomScrollView`. ## 1. Create a `CustomScrollView` To create a floating app bar, place the app bar inside a `CustomScrollView` that also contains the list of items. -This synchronizes the scroll position of the app bar and the list of items. -You might think of the `CustomScrollView` widget as a `ListView` -that allows you to mix and match different types of scrollable lists -and widgets together. +This synchronizes the scroll position of the app bar and the +list of items. You might think of the `CustomScrollView` +widget as a `ListView` that allows you to mix and match +different types of scrollable lists and widgets together. The scrollable lists and widgets provided to the -`CustomScrollView` are known as _slivers_. There are several types -of slivers, such as `SliverList`, `SliverGrid`, and `SliverAppBar`. -In fact, the `ListView` and `GridView` widgets use the `SliverList` and -`SliverGrid` widgets to implement scrolling. +`CustomScrollView` are known as _slivers_. There are several +types of slivers, such as `SliverList`, `SliverGrid`, and +`SliverAppBar`. In fact, the `ListView` and `GridView` +widgets use the `SliverList` and `SliverGrid` widgets to +implement scrolling. -For this example, create a `CustomScrollView` that contains a -`SliverAppBar` and a `SliverList`. In addition, remove any app bars -that you provide to the `Scaffold` widget. +For this example, create a `CustomScrollView` that contains +a `SliverList`. Also, remove the app bar property from your +code if it exists. - +{% tabs "device-type-tabs" %} + +{% tab "Material widgets" %} + + ```dart Scaffold( - // No appBar property provided, only the body. + // No app bar property provided yet. body: CustomScrollView( // Add the app bar and list of items as slivers in the next steps. slivers: [], @@ -60,29 +66,55 @@ Scaffold( ); ``` -### 2. Use `SliverAppBar` to add a floating app bar +{% endtab %} + +{% tab "Cupertino widgets" %} + + +```dart +CupertinoApp( + home: CupertinoPageScaffold( + // No navigation bar property provided yet. + child: CustomScrollView( + // Add the navigation bar and list of items as slivers in the next steps. + slivers: [], + ), + ), +); +``` + +{% endtab %} + +{% endtabs %} + + +## 2. Add a floating app bar Next, add an app bar to the [`CustomScrollView`][]. + +{% tabs "device-type-tabs" %} + +{% tab "Material widgets" %} + Flutter provides the [`SliverAppBar`][] widget which, much like the normal `AppBar` widget, uses the `SliverAppBar` to display a title, tabs, images and more. -However, the `SliverAppBar` also gives you the ability to create a "floating" -app bar that scrolls offscreen as the user scrolls down the list. -Furthermore, you can configure the `SliverAppBar` to shrink and -expand as the user scrolls. +However, the `SliverAppBar` also gives you the ability to +create a "floating" app bar that scrolls offscreen as the +user scrolls down the list. Furthermore, you can configure +the `SliverAppBar` to shrink and expand as the user scrolls. To create this effect: 1. Start with an app bar that displays only a title. + 2. Set the `pinned` property to `true`. 2. Set the `floating` property to `true`. - This allows users to quickly reveal the app bar when - they scroll up the list. 3. Add a `flexibleSpace` widget that fills the available `expandedHeight`. - + ```dart CustomScrollView( slivers: [ @@ -91,6 +123,8 @@ CustomScrollView( // Provide a standard title. title: Text(title), // Allows the user to reveal the app bar if they begin scrolling + pinned: true, + // Allows the user to reveal the app bar if they begin scrolling // back up the list of items. floating: true, // Display a placeholder widget to visualize the shrinking size. @@ -105,28 +139,66 @@ CustomScrollView( :::tip Play around with the [various properties you can pass to the `SliverAppBar` widget][], -and use hot reload to see the results. For example, use an `Image` -widget for the `flexibleSpace` property to create a background image that -shrinks in size as it's scrolled offscreen. +and use hot reload to see the results. For example, use an +`Image` widget for the `flexibleSpace` property to create a +background image that shrinks in size as it's scrolled +offscreen. ::: +{% endtab %} -### 3. Add a list of items using a `SliverList` +{% tab "Cupertino widgets" %} -Now that you have the app bar in place, add a list of items to the -`CustomScrollView`. You have two options: a [`SliverList`][] -or a [`SliverGrid`][]. If you need to display a list of items one after the other, -use the `SliverList` widget. -If you need to display a grid list, use the `SliverGrid` widget. +Flutter provides the [`CupertinoSliverNavigationBar`][] +widget, which you can use to add a navigation bar for your +list. When used inside of a `CustomScrollView`, +the title shrinks when you scroll down and floats when +you're not at the top of the page. -The `SliverList` and `SliverGrid` widgets take one required parameter: a -[`SliverChildDelegate`][], which provides a list -of widgets to `SliverList` or `SliverGrid`. -For example, the [`SliverChildBuilderDelegate`][] -allows you to create a list of items that are built lazily as you scroll, -just like the `ListView.builder` widget. +For this example, add `CupertinoSliverNavigationBar` to +`CustomScrollView`. - + +```dart +child: CustomScrollView( + slivers: [ + // Add the navigation bar to the CustomScrollView. + const CupertinoSliverNavigationBar( + // Provide a standard title. + largeTitle: Text(title), + ), + ], +) +``` + +{% endtab %} + +{% endtabs %} + + +## 3. Add a list of items + +Now that you have the app bar in place, add a list of items +to the `CustomScrollView`. You have two options: a +[`SliverList`][] or a [`SliverGrid`][]. If you need to +display a list of items one after the other, use the +`SliverList` widget. If you need to display a grid list, use +the `SliverGrid` widget. + +The `SliverList` and `SliverGrid` widgets take one required +parameter: a sliver delegate, which provides a +list of widgets to `SliverList` or `SliverGrid`. + +There are many types of sliver delegates. In the following +example, the [`SliverChildBuilderDelegate`][] is used to +to create a list of items that are built lazily as you +scroll, just like the `ListView.builder` widget. + +{% tabs "device-type-tabs" %} + +{% tab "Material widgets" %} + + ```dart // Next, create a SliverList SliverList( @@ -135,16 +207,44 @@ SliverList( // The builder function returns a ListTile with a title that // displays the index of the current item. (context, index) => ListTile(title: Text('Item #$index')), - // Builds 1000 ListTiles - childCount: 1000, + // Builds 50 ListTiles + childCount: 50, + ), +) +``` + +{% endtab %} + +{% tab "Cupertino widgets" %} + + +```dart +// Next, create a SliverList +SliverList( + // Use a delegate to build items as they're scrolled on screen. + delegate: SliverChildBuilderDelegate( + // The builder function returns a ListTile with a title that + // displays the index of the current item. + (context, index) => + CupertinoListTile(title: Text('Item #$index')), + // Builds 50 ListTiles + childCount: 50, ), ) ``` +{% endtab %} + +{% endtabs %} + ## Interactive example - -```dartpad title="Flutter Floating AppBar hands-on example in DartPad" run="true" +{% tabs "device-type-tabs" %} + +{% tab "Material widgets" %} + + +```dartpad title="Flutter floating app bar hands-on example in DartPad" run="false" import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); @@ -159,7 +259,7 @@ class MyApp extends StatelessWidget { return MaterialApp( title: title, home: Scaffold( - // No appbar provided to the Scaffold, only a body with a + // No app bar provided to Scaffold, only a body with a // CustomScrollView. body: CustomScrollView( slivers: [ @@ -168,6 +268,8 @@ class MyApp extends StatelessWidget { // Provide a standard title. title: Text(title), // Allows the user to reveal the app bar if they begin scrolling + pinned: true, + // Allows the user to reveal the app bar if they begin scrolling // back up the list of items. floating: true, // Display a placeholder widget to visualize the shrinking size. @@ -182,8 +284,8 @@ class MyApp extends StatelessWidget { // The builder function returns a ListTile with a title that // displays the index of the current item. (context, index) => ListTile(title: Text('Item #$index')), - // Builds 1000 ListTiles - childCount: 1000, + // Builds 50 ListTiles + childCount: 50, ), ), ], @@ -195,10 +297,67 @@ class MyApp extends StatelessWidget { ``` +{% endtab %} + +{% tab "Cupertino widgets" %} + + +```dartpad title="Flutter floating navigation bar hands-on example in DartPad" run="false" +import 'package:flutter/cupertino.dart'; + +void main() => runApp(const MyApp()); + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + const title = 'Floating Navigation Bar'; + + return CupertinoApp( + title: title, + home: CupertinoPageScaffold( + // No navigation bar provided to CupertinoPageScaffold, + // only a body with a CustomScrollView. + child: CustomScrollView( + slivers: [ + // Add the navigation bar to the CustomScrollView. + const CupertinoSliverNavigationBar( + // Provide a standard title. + largeTitle: Text(title), + ), + // Next, create a SliverList + SliverList( + // Use a delegate to build items as they're scrolled on screen. + delegate: SliverChildBuilderDelegate( + // The builder function returns a ListTile with a title that + // displays the index of the current item. + (context, index) => + CupertinoListTile(title: Text('Item #$index')), + // Builds 50 ListTiles + childCount: 50, + ), + ), + ], + ), + ), + ); + } +} +``` + + + +{% endtab %} + +{% endtabs %} +[`CupertinoSliverNavigationBar`]: {{site.api}}/flutter/cupertino/CupertinoSliverNavigationBar-class.html [`CustomScrollView`]: {{site.api}}/flutter/widgets/CustomScrollView-class.html [`SliverAppBar`]: {{site.api}}/flutter/material/SliverAppBar-class.html [`SliverChildBuilderDelegate`]: {{site.api}}/flutter/widgets/SliverChildBuilderDelegate-class.html From 3e252264490c52d536b0b07aea7f87e017bec783 Mon Sep 17 00:00:00 2001 From: Amanda Fitch Date: Mon, 17 Mar 2025 13:53:52 -0700 Subject: [PATCH 2/5] First round of edits. --- .../floating_app_bar/lib/main_cupertino.dart | 18 +- .../floating_app_bar/lib/main_material.dart | 21 +-- .../lib/starter_cupertino.dart | 1 + .../lib/starter_material.dart | 13 +- .../floating_app_bar/lib/step2_cupertino.dart | 12 +- .../floating_app_bar/lib/step2_material.dart | 15 +- .../cookbook/lists/floating-app-bar.md | 161 ++++++++---------- 7 files changed, 104 insertions(+), 137 deletions(-) diff --git a/examples/cookbook/lists/floating_app_bar/lib/main_cupertino.dart b/examples/cookbook/lists/floating_app_bar/lib/main_cupertino.dart index afd5c9364e..ee16cf1904 100644 --- a/examples/cookbook/lists/floating_app_bar/lib/main_cupertino.dart +++ b/examples/cookbook/lists/floating_app_bar/lib/main_cupertino.dart @@ -23,16 +23,14 @@ class MyApp extends StatelessWidget { ), // #docregion SliverList // Next, create a SliverList - SliverList( - // Use a delegate to build items as they're scrolled on screen. - delegate: SliverChildBuilderDelegate( - // The builder function returns a ListTile with a title that - // displays the index of the current item. - (context, index) => - CupertinoListTile(title: Text('Item #$index')), - // Builds 50 ListTiles - childCount: 50, - ), + SliverList.builder( + // The builder function returns a ListTile with a title that + // displays the index of the current item. + itemBuilder: + (context, index) => + CupertinoListTile(title: Text('Item #$index')), + // Builds 50 ListTiles + itemCount: 50, ), // #enddocregion SliverList ], diff --git a/examples/cookbook/lists/floating_app_bar/lib/main_material.dart b/examples/cookbook/lists/floating_app_bar/lib/main_material.dart index 81bac58329..6ee2e8fabd 100644 --- a/examples/cookbook/lists/floating_app_bar/lib/main_material.dart +++ b/examples/cookbook/lists/floating_app_bar/lib/main_material.dart @@ -20,11 +20,8 @@ class MyApp extends StatelessWidget { const SliverAppBar( // Provide a standard title. title: Text(title), - // Allows the user to reveal the app bar if they begin scrolling + // Pin the app bar when scrolling pinned: true, - // Allows the user to reveal the app bar if they begin scrolling - // back up the list of items. - floating: true, // Display a placeholder widget to visualize the shrinking size. flexibleSpace: Placeholder(), // Make the initial height of the SliverAppBar larger than normal. @@ -32,15 +29,13 @@ class MyApp extends StatelessWidget { ), // #docregion SliverList // Next, create a SliverList - SliverList( - // Use a delegate to build items as they're scrolled on screen. - delegate: SliverChildBuilderDelegate( - // The builder function returns a ListTile with a title that - // displays the index of the current item. - (context, index) => ListTile(title: Text('Item #$index')), - // Builds 50 ListTiles - childCount: 50, - ), + SliverList.builder( + // The builder function returns a ListTile with a title that + // displays the index of the current item. + itemBuilder: + (context, index) => ListTile(title: Text('Item #$index')), + // Builds 50 ListTiles + itemCount: 50, ), // #enddocregion SliverList ], diff --git a/examples/cookbook/lists/floating_app_bar/lib/starter_cupertino.dart b/examples/cookbook/lists/floating_app_bar/lib/starter_cupertino.dart index 367d74bc46..17074a6171 100644 --- a/examples/cookbook/lists/floating_app_bar/lib/starter_cupertino.dart +++ b/examples/cookbook/lists/floating_app_bar/lib/starter_cupertino.dart @@ -7,6 +7,7 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { // #docregion CustomScrollView return const CupertinoApp( + title: 'Floating Navigation Bar', home: CupertinoPageScaffold( // No navigation bar property provided yet. child: CustomScrollView( diff --git a/examples/cookbook/lists/floating_app_bar/lib/starter_material.dart b/examples/cookbook/lists/floating_app_bar/lib/starter_material.dart index 14d88dd2a7..ab08bbbb6d 100644 --- a/examples/cookbook/lists/floating_app_bar/lib/starter_material.dart +++ b/examples/cookbook/lists/floating_app_bar/lib/starter_material.dart @@ -6,11 +6,14 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // #docregion CustomScrollView - return const Scaffold( - // No app bar property provided yet. - body: CustomScrollView( - // Add the app bar and list of items as slivers in the next steps. - slivers: [], + return const MaterialApp( + title: 'Floating App Bar', + home: Scaffold( + // No app bar property provided yet. + body: CustomScrollView( + // Add the app bar and list of items as slivers in the next steps. + slivers: [], + ), ), ); // #enddocregion CustomScrollView diff --git a/examples/cookbook/lists/floating_app_bar/lib/step2_cupertino.dart b/examples/cookbook/lists/floating_app_bar/lib/step2_cupertino.dart index 966466ac84..4a66f84e26 100644 --- a/examples/cookbook/lists/floating_app_bar/lib/step2_cupertino.dart +++ b/examples/cookbook/lists/floating_app_bar/lib/step2_cupertino.dart @@ -7,24 +7,22 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - const title = 'Floating Navigation Bar'; - - return CupertinoApp( - title: title, + return const CupertinoApp( + title: 'Floating App Bar', home: CupertinoPageScaffold( // No navigation bar provided to CupertinoPageScaffold, // only a body with a CustomScrollView. - // #docregion SliverAppBar child: CustomScrollView( + // #docregion SliverAppBar slivers: [ // Add the navigation bar to the CustomScrollView. const CupertinoSliverNavigationBar( // Provide a standard title. - largeTitle: Text(title), + largeTitle: Text('Floating App Bar'), ), ], + // #enddocregion SliverAppBar ), - // #enddocregion SliverAppBar ), ); } diff --git a/examples/cookbook/lists/floating_app_bar/lib/step2_material.dart b/examples/cookbook/lists/floating_app_bar/lib/step2_material.dart index f941a77d09..88b227aced 100644 --- a/examples/cookbook/lists/floating_app_bar/lib/step2_material.dart +++ b/examples/cookbook/lists/floating_app_bar/lib/step2_material.dart @@ -7,33 +7,28 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - const title = 'Floating App Bar'; - return const MaterialApp( - title: title, + title: 'Floating App Bar', home: Scaffold( // No appbar provided to the Scaffold, only a body with a // CustomScrollView. - // #docregion SliverAppBar body: CustomScrollView( + // #docregion SliverAppBar slivers: [ // Add the app bar to the CustomScrollView. SliverAppBar( // Provide a standard title. - title: Text(title), - // Allows the user to reveal the app bar if they begin scrolling + title: Text('Floating App Bar'), + // Pin the app bar when scrolling. pinned: true, - // Allows the user to reveal the app bar if they begin scrolling - // back up the list of items. - floating: true, // Display a placeholder widget to visualize the shrinking size. flexibleSpace: Placeholder(), // Make the initial height of the SliverAppBar larger than normal. expandedHeight: 200, ), ], + // #enddocregion SliverAppBar ), - // #enddocregion SliverAppBar ), ); } diff --git a/src/content/cookbook/lists/floating-app-bar.md b/src/content/cookbook/lists/floating-app-bar.md index ce5eac78e2..d8ff9106c5 100644 --- a/src/content/cookbook/lists/floating-app-bar.md +++ b/src/content/cookbook/lists/floating-app-bar.md @@ -57,11 +57,14 @@ code if it exists. ```dart -Scaffold( - // No app bar property provided yet. - body: CustomScrollView( - // Add the app bar and list of items as slivers in the next steps. - slivers: [], +MaterialApp( + title: 'Floating App Bar', + home: Scaffold( + // No app bar property provided yet. + body: CustomScrollView( + // Add the app bar and list of items as slivers in the next steps. + slivers: [], + ), ), ); ``` @@ -73,6 +76,7 @@ Scaffold( ```dart CupertinoApp( + title: 'Floating Navigation Bar', home: CupertinoPageScaffold( // No navigation bar property provided yet. child: CustomScrollView( @@ -102,38 +106,31 @@ uses the `SliverAppBar` to display a title, tabs, images and more. However, the `SliverAppBar` also gives you the ability to -create a "floating" app bar that scrolls offscreen as the -user scrolls down the list. Furthermore, you can configure -the `SliverAppBar` to shrink and expand as the user scrolls. +create a "floating" app bar that shrinks and floats when +you're not at the top of the page. To create this effect: 1. Start with an app bar that displays only a title. 2. Set the `pinned` property to `true`. - 2. Set the `floating` property to `true`. 3. Add a `flexibleSpace` widget that fills the available `expandedHeight`. ```dart -CustomScrollView( - slivers: [ - // Add the app bar to the CustomScrollView. - SliverAppBar( - // Provide a standard title. - title: Text(title), - // Allows the user to reveal the app bar if they begin scrolling - pinned: true, - // Allows the user to reveal the app bar if they begin scrolling - // back up the list of items. - floating: true, - // Display a placeholder widget to visualize the shrinking size. - flexibleSpace: Placeholder(), - // Make the initial height of the SliverAppBar larger than normal. - expandedHeight: 200, - ), - ], -) +slivers: [ + // Add the app bar to the CustomScrollView. + SliverAppBar( + // Provide a standard title. + title: Text('Floating App Bar'), + // Pin the app bar when scrolling. + pinned: true, + // Display a placeholder widget to visualize the shrinking size. + flexibleSpace: Placeholder(), + // Make the initial height of the SliverAppBar larger than normal. + expandedHeight: 200, + ), +], ``` :::tip @@ -150,25 +147,25 @@ offscreen. {% tab "Cupertino widgets" %} Flutter provides the [`CupertinoSliverNavigationBar`][] -widget, which you can use to add a navigation bar for your -list. When used inside of a `CustomScrollView`, -the title shrinks when you scroll down and floats when +widget, which lets you have a "floating" navigation +bar that shrinks when you scroll down and floats when you're not at the top of the page. -For this example, add `CupertinoSliverNavigationBar` to -`CustomScrollView`. +To create this effect: + + 1. Add `CupertinoSliverNavigationBar` to + `CustomScrollView`. + 2. Start with an app bar that displays only a title. ```dart -child: CustomScrollView( - slivers: [ - // Add the navigation bar to the CustomScrollView. - const CupertinoSliverNavigationBar( - // Provide a standard title. - largeTitle: Text(title), - ), - ], -) +slivers: [ + // Add the navigation bar to the CustomScrollView. + const CupertinoSliverNavigationBar( + // Provide a standard title. + largeTitle: Text('Floating App Bar'), + ), +], ``` {% endtab %} @@ -185,15 +182,6 @@ display a list of items one after the other, use the `SliverList` widget. If you need to display a grid list, use the `SliverGrid` widget. -The `SliverList` and `SliverGrid` widgets take one required -parameter: a sliver delegate, which provides a -list of widgets to `SliverList` or `SliverGrid`. - -There are many types of sliver delegates. In the following -example, the [`SliverChildBuilderDelegate`][] is used to -to create a list of items that are built lazily as you -scroll, just like the `ListView.builder` widget. - {% tabs "device-type-tabs" %} {% tab "Material widgets" %} @@ -201,15 +189,13 @@ scroll, just like the `ListView.builder` widget. ```dart // Next, create a SliverList -SliverList( - // Use a delegate to build items as they're scrolled on screen. - delegate: SliverChildBuilderDelegate( - // The builder function returns a ListTile with a title that - // displays the index of the current item. - (context, index) => ListTile(title: Text('Item #$index')), - // Builds 50 ListTiles - childCount: 50, - ), +SliverList.builder( + // The builder function returns a ListTile with a title that + // displays the index of the current item. + itemBuilder: + (context, index) => ListTile(title: Text('Item #$index')), + // Builds 50 ListTiles + itemCount: 50, ) ``` @@ -220,16 +206,14 @@ SliverList( ```dart // Next, create a SliverList -SliverList( - // Use a delegate to build items as they're scrolled on screen. - delegate: SliverChildBuilderDelegate( - // The builder function returns a ListTile with a title that - // displays the index of the current item. - (context, index) => - CupertinoListTile(title: Text('Item #$index')), - // Builds 50 ListTiles - childCount: 50, - ), +SliverList.builder( + // The builder function returns a ListTile with a title that + // displays the index of the current item. + itemBuilder: + (context, index) => + CupertinoListTile(title: Text('Item #$index')), + // Builds 50 ListTiles + itemCount: 50, ) ``` @@ -267,26 +251,21 @@ class MyApp extends StatelessWidget { const SliverAppBar( // Provide a standard title. title: Text(title), - // Allows the user to reveal the app bar if they begin scrolling + // Pin the app bar when scrolling pinned: true, - // Allows the user to reveal the app bar if they begin scrolling - // back up the list of items. - floating: true, // Display a placeholder widget to visualize the shrinking size. flexibleSpace: Placeholder(), // Make the initial height of the SliverAppBar larger than normal. expandedHeight: 200, ), // Next, create a SliverList - SliverList( - // Use a delegate to build items as they're scrolled on screen. - delegate: SliverChildBuilderDelegate( - // The builder function returns a ListTile with a title that - // displays the index of the current item. - (context, index) => ListTile(title: Text('Item #$index')), - // Builds 50 ListTiles - childCount: 50, - ), + SliverList.builder( + // The builder function returns a ListTile with a title that + // displays the index of the current item. + itemBuilder: + (context, index) => ListTile(title: Text('Item #$index')), + // Builds 50 ListTiles + itemCount: 50, ), ], ), @@ -330,16 +309,14 @@ class MyApp extends StatelessWidget { largeTitle: Text(title), ), // Next, create a SliverList - SliverList( - // Use a delegate to build items as they're scrolled on screen. - delegate: SliverChildBuilderDelegate( - // The builder function returns a ListTile with a title that - // displays the index of the current item. - (context, index) => - CupertinoListTile(title: Text('Item #$index')), - // Builds 50 ListTiles - childCount: 50, - ), + SliverList.builder( + // The builder function returns a ListTile with a title that + // displays the index of the current item. + itemBuilder: + (context, index) => + CupertinoListTile(title: Text('Item #$index')), + // Builds 50 ListTiles + itemCount: 50, ), ], ), From 4752958562d28da701bfa79a5c7383e2624fcc10 Mon Sep 17 00:00:00 2001 From: Amanda Fitch Date: Mon, 17 Mar 2025 16:15:18 -0700 Subject: [PATCH 3/5] Added small edits. --- .../cookbook/lists/floating_app_bar/lib/main_cupertino.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/cookbook/lists/floating_app_bar/lib/main_cupertino.dart b/examples/cookbook/lists/floating_app_bar/lib/main_cupertino.dart index ee16cf1904..5513df9580 100644 --- a/examples/cookbook/lists/floating_app_bar/lib/main_cupertino.dart +++ b/examples/cookbook/lists/floating_app_bar/lib/main_cupertino.dart @@ -24,12 +24,12 @@ class MyApp extends StatelessWidget { // #docregion SliverList // Next, create a SliverList SliverList.builder( - // The builder function returns a ListTile with a title that - // displays the index of the current item. + // The builder function returns a CupertinoListTile with a title + // that displays the index of the current item. itemBuilder: (context, index) => CupertinoListTile(title: Text('Item #$index')), - // Builds 50 ListTiles + // Builds 50 CupertinoListTile itemCount: 50, ), // #enddocregion SliverList From 241c7c81951f5734abf3a6b87d30632e808fcd4d Mon Sep 17 00:00:00 2001 From: Amanda Fitch Date: Mon, 17 Mar 2025 16:18:10 -0700 Subject: [PATCH 4/5] Updated excerpts. --- src/content/cookbook/lists/floating-app-bar.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/content/cookbook/lists/floating-app-bar.md b/src/content/cookbook/lists/floating-app-bar.md index d8ff9106c5..39f8f1f7b5 100644 --- a/src/content/cookbook/lists/floating-app-bar.md +++ b/src/content/cookbook/lists/floating-app-bar.md @@ -207,12 +207,12 @@ SliverList.builder( ```dart // Next, create a SliverList SliverList.builder( - // The builder function returns a ListTile with a title that - // displays the index of the current item. + // The builder function returns a CupertinoListTile with a title + // that displays the index of the current item. itemBuilder: (context, index) => CupertinoListTile(title: Text('Item #$index')), - // Builds 50 ListTiles + // Builds 50 CupertinoListTile itemCount: 50, ) ``` @@ -310,12 +310,12 @@ class MyApp extends StatelessWidget { ), // Next, create a SliverList SliverList.builder( - // The builder function returns a ListTile with a title that - // displays the index of the current item. + // The builder function returns a CupertinoListTile with a title + // that displays the index of the current item. itemBuilder: (context, index) => CupertinoListTile(title: Text('Item #$index')), - // Builds 50 ListTiles + // Builds 50 CupertinoListTile itemCount: 50, ), ], From 869aa0ec0a8d43a1bd3c56f0db07252a0e806e67 Mon Sep 17 00:00:00 2001 From: Amanda Fitch Date: Mon, 17 Mar 2025 16:24:42 -0700 Subject: [PATCH 5/5] Updated excerpts. --- .../cookbook/lists/floating_app_bar/lib/step2_cupertino.dart | 2 +- src/content/cookbook/lists/floating-app-bar.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/cookbook/lists/floating_app_bar/lib/step2_cupertino.dart b/examples/cookbook/lists/floating_app_bar/lib/step2_cupertino.dart index 4a66f84e26..aeb1c8c9ae 100644 --- a/examples/cookbook/lists/floating_app_bar/lib/step2_cupertino.dart +++ b/examples/cookbook/lists/floating_app_bar/lib/step2_cupertino.dart @@ -16,7 +16,7 @@ class MyApp extends StatelessWidget { // #docregion SliverAppBar slivers: [ // Add the navigation bar to the CustomScrollView. - const CupertinoSliverNavigationBar( + CupertinoSliverNavigationBar( // Provide a standard title. largeTitle: Text('Floating App Bar'), ), diff --git a/src/content/cookbook/lists/floating-app-bar.md b/src/content/cookbook/lists/floating-app-bar.md index 39f8f1f7b5..a66501ef6a 100644 --- a/src/content/cookbook/lists/floating-app-bar.md +++ b/src/content/cookbook/lists/floating-app-bar.md @@ -161,7 +161,7 @@ To create this effect: ```dart slivers: [ // Add the navigation bar to the CustomScrollView. - const CupertinoSliverNavigationBar( + CupertinoSliverNavigationBar( // Provide a standard title. largeTitle: Text('Floating App Bar'), ),