跳到主内容

在列表上方放置浮动应用栏

如何将浮动应用栏或导航栏放置在列表上方。

本指南介绍了如何在 Flutter 应用中将浮动应用栏或导航栏放置在列表上方的方法。

概述

#

为了方便用户查看项目列表,您可能希望在用户向下滚动列表时缩小应用栏(导航栏)。

将应用栏移动到 CustomScrollView 中,可以创建一个可以随着您滚动列表中的项目而缩小或移出屏幕的应用栏。

本教程演示如何使用 CustomScrollView 显示一个项目列表,并在顶部显示一个应用栏,该应用栏会在用户向下滚动列表时缩小,具体步骤如下:

  1. 创建一个 CustomScrollView
  2. 将浮动应用栏添加到 CustomScrollView
  3. 将项目列表添加到 CustomScrollView

1. 创建一个 CustomScrollView

#

要创建浮动应用栏,请将应用栏放置在包含项目列表的 CustomScrollView 内部。这将同步应用栏和项目列表的滚动位置。您可以将 CustomScrollView 组件视为一个 ListView,它允许您混合和匹配不同类型的可滚动列表和组件。

提供给 CustomScrollView 的可滚动列表和组件被称为 *sliver*。有几种类型的 sliver,例如 SliverListSliverGridSliverAppBar。实际上,ListViewGridView 组件使用 SliverListSliverGrid 组件来实现滚动。

对于本示例,创建一个包含 SliverListCustomScrollView。另外,如果您的代码中存在应用栏属性,请将其删除。

dart
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: <Widget>[],
    ),
  ),
);
dart
CupertinoApp(
  title: 'Floating Navigation Bar',
  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: <Widget>[],
    ),
  ),
);

2. 添加一个浮动应用栏

#

接下来,将应用栏添加到 CustomScrollView

Flutter 提供了 SliverAppBar 组件,它类似于普通的 AppBar 组件,使用 SliverAppBar 来显示标题、选项卡、图像等。

但是,SliverAppBar 还让您能够创建一个在不在页面顶部时缩小并浮动的“浮动”应用栏。

要创建此效果

  1. 从仅显示标题的应用栏开始。
  2. pinned 属性设置为 true
  3. 添加一个 flexibleSpace 组件,填充可用的 expandedHeight
dart
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,
  ),
],

Flutter 提供了 CupertinoSliverNavigationBar 组件,它允许您拥有一个在向下滚动时缩小并在不在页面顶部时浮动的“浮动”导航栏。

要创建此效果

  1. CupertinoSliverNavigationBar 添加到 CustomScrollView
  2. 从仅显示标题的应用栏开始。
dart
slivers: [
  // Add the navigation bar to the CustomScrollView.
  CupertinoSliverNavigationBar(
    // Provide a standard title.
    largeTitle: Text('Floating App Bar'),
  ),
],

3. 添加一个项目列表

#

现在您已经将应用栏放置到位,将一个项目列表添加到 CustomScrollView。您有两种选择:SliverListSliverGrid。如果您需要一个接一个地显示项目列表,请使用 SliverList 组件。如果您需要显示网格列表,请使用 SliverGrid 组件。

dart
// Next, create a SliverList
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,
)
dart
// Next, create a SliverList
SliverList.builder(
  // 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 CupertinoListTile
  itemCount: 50,
)

互动示例

#
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    const title = 'Floating App Bar';

    return MaterialApp(
      title: title,
      home: Scaffold(
        // No app bar provided to Scaffold, only a body with a
        // CustomScrollView.
        body: CustomScrollView(
          slivers: [
            // Add the app bar to the CustomScrollView.
            const SliverAppBar(
              // Provide a standard title.
              title: Text(title),
              // 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,
            ),
            // Next, create a SliverList
            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,
            ),
          ],
        ),
      ),
    );
  }
}
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.builder(
              // 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 CupertinoListTile
              itemCount: 50,
            ),
          ],
        ),
      ),
    );
  }
}